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/06 06:22:11 UTC

[echarts-examples] branch typescript updated (424edd8 -> 5743f81)

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

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


    from 424edd8  compile ts to js files
     new 16a6683  use prettier to format code
     new 5743f81  format example code

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


Summary of changes:
 .babelrc                                           |   11 +-
 .eslintrc.js                                       |   13 +
 .gitignore                                         |    1 +
 .gitignore => .prettierignore                      |   14 +-
 .prettierrc                                        |    7 +
 .vscode/settings.json                              |    6 +
 README.md                                          |   24 +-
 build/copyResource.js                              |  139 +-
 build/server.js                                    |   24 +-
 build/webpack.config.js                            |  155 +-
 common/buildCode.js                                |  611 ++---
 common/compareImage.js                             |   81 +-
 common/task.js                                     |   96 +-
 config/common.js                                   |    6 +-
 config/env.asf.js                                  |    2 +-
 config/env.dev.js                                  |    2 +-
 config/env.localsite.js                            |    2 +-
 e2e/cases/README.md                                |    2 +-
 e2e/cases/liquidfill.js                            |   14 +-
 e2e/cases/wordcloud.js                             |  230 +-
 e2e/config.js                                      |   58 +-
 e2e/main.js                                        | 1290 +++++-----
 e2e/package.json                                   |    3 +-
 e2e/preview.html                                   |   47 +-
 e2e/report.html                                    |  353 +--
 e2e/template.html                                  |   47 +-
 e2e/tsconfig.json                                  |   18 +-
 e2e/webpack.config.js                              |   29 +-
 public/en/editor.html                              |   53 +-
 public/en/index.html                               |   54 +-
 public/en/view.html                                |   53 +-
 public/examples/ts/area-basic.ts                   |   30 +-
 public/examples/ts/area-pieces.ts                  |  110 +-
 public/examples/ts/area-rainfall.ts                |  304 +--
 public/examples/ts/area-simple.ts                  |  126 +-
 public/examples/ts/area-stack-gradient.ts          |  339 +--
 public/examples/ts/area-stack.ts                   |  182 +-
 public/examples/ts/area-time-axis.ts               |  100 +-
 public/examples/ts/bar-animation-delay.ts          |  110 +-
 public/examples/ts/bar-background.ts               |   34 +-
 public/examples/ts/bar-brush.ts                    |  169 +-
 public/examples/ts/bar-data-color.ts               |   44 +-
 public/examples/ts/bar-drilldown.ts                |  167 +-
 public/examples/ts/bar-gradient.ts                 |  143 +-
 public/examples/ts/bar-histogram.ts                |  247 +-
 public/examples/ts/bar-label-rotation.ts           |  296 +--
 public/examples/ts/bar-large.ts                    |  150 +-
 public/examples/ts/bar-negative.ts                 |  135 +-
 public/examples/ts/bar-negative2.ts                |  118 +-
 public/examples/ts/bar-polar-label-radial.ts       |   58 +-
 public/examples/ts/bar-polar-label-tangential.ts   |   58 +-
 public/examples/ts/bar-polar-real-estate.ts        |  184 +-
 public/examples/ts/bar-polar-stack-radial.ts       |   78 +-
 public/examples/ts/bar-polar-stack.ts              |   80 +-
 public/examples/ts/bar-race-country.ts             |  255 +-
 public/examples/ts/bar-race.ts                     |   99 +-
 public/examples/ts/bar-rich-text.ts                |  265 +-
 public/examples/ts/bar-simple.ts                   |   26 +-
 public/examples/ts/bar-stack.ts                    |  222 +-
 public/examples/ts/bar-tick-align.ts               |   68 +-
 public/examples/ts/bar-waterfall.ts                |  108 +-
 public/examples/ts/bar-waterfall2.ts               |  153 +-
 public/examples/ts/bar-y-category-stack.ts         |  161 +-
 public/examples/ts/bar-y-category.ts               |   75 +-
 public/examples/ts/bar1.ts                         |  131 +-
 public/examples/ts/boxplot-light-velocity.ts       |  151 +-
 public/examples/ts/boxplot-light-velocity2.ts      |  155 +-
 public/examples/ts/boxplot-multi.ts                |  182 +-
 public/examples/ts/bubble-gradient.ts              |  238 +-
 public/examples/ts/calendar-charts.ts              |  314 ++-
 public/examples/ts/calendar-effectscatter.ts       |  293 +--
 public/examples/ts/calendar-graph.ts               |  189 +-
 public/examples/ts/calendar-heatmap.ts             |   84 +-
 public/examples/ts/calendar-horizontal.ts          |  107 +-
 public/examples/ts/calendar-lunar.ts               |  889 ++++---
 public/examples/ts/calendar-pie.ts                 |  178 +-
 public/examples/ts/calendar-simple.ts              |   52 +-
 public/examples/ts/calendar-vertical.ts            |  123 +-
 public/examples/ts/candlestick-brush.ts            |  490 ++--
 public/examples/ts/candlestick-large.ts            |  361 +--
 public/examples/ts/candlestick-sh-2015.ts          |  228 +-
 public/examples/ts/candlestick-sh.ts               |  576 +++--
 public/examples/ts/candlestick-simple.ts           |   30 +-
 public/examples/ts/candlestick-touch.ts            |  453 ++--
 public/examples/ts/circle-packing-with-d3.ts       |  380 +--
 public/examples/ts/confidence-band.ts              |  152 +-
 public/examples/ts/custom-bar-trend.ts             |  185 +-
 public/examples/ts/custom-calendar-icon.ts         |  213 +-
 public/examples/ts/custom-cartesian-polygon.js     |   96 +-
 public/examples/ts/custom-error-bar.js             |  197 +-
 public/examples/ts/custom-error-scatter.js         |  218 +-
 public/examples/ts/custom-gantt-flight.js          |  969 ++++----
 public/examples/ts/custom-gauge.js                 |  281 +--
 public/examples/ts/custom-hexbin.js                |  450 ++--
 public/examples/ts/custom-ohlc.js                  |  292 +--
 public/examples/ts/custom-polar-heatmap.js         |  128 +-
 public/examples/ts/custom-profile.js               |  193 +-
 public/examples/ts/custom-profit.js                |  113 +-
 public/examples/ts/custom-spiral-race.js           |  403 ++--
 public/examples/ts/custom-wind.js                  |  195 +-
 public/examples/ts/cycle-plot.js                   |  203 +-
 public/examples/ts/data-transform-aggregate.js     |  232 +-
 public/examples/ts/data-transform-filter.ts        |  147 +-
 public/examples/ts/data-transform-multiple-pie.ts  |  159 +-
 public/examples/ts/data-transform-sort-bar.ts      |   60 +-
 public/examples/ts/dataset-default.ts              |   87 +-
 public/examples/ts/dataset-encode0.ts              |   80 +-
 public/examples/ts/dataset-encode1.ts              |  189 +-
 public/examples/ts/dataset-link.ts                 |  140 +-
 public/examples/ts/dataset-series-layout-by.ts     |   60 +-
 public/examples/ts/dataset-simple0.ts              |   36 +-
 public/examples/ts/dataset-simple1.ts              |   36 +-
 public/examples/ts/dynamic-data.ts                 |  246 +-
 public/examples/ts/dynamic-data2.ts                |  120 +-
 public/examples/ts/effectScatter-bmap.ts           | 1135 ++++-----
 public/examples/ts/effectScatter-map.ts            |  974 ++++----
 public/examples/ts/funnel-align.ts                 |  188 +-
 public/examples/ts/funnel-customize.ts             |  154 +-
 public/examples/ts/funnel-mutiple.ts               |  184 +-
 public/examples/ts/funnel.ts                       |  118 +-
 public/examples/ts/gauge-barometer.ts              |  233 +-
 public/examples/ts/gauge-car.ts                    | 1005 ++++----
 public/examples/ts/gauge-clock.ts                  |  414 ++--
 public/examples/ts/gauge-grade.ts                  |  159 +-
 public/examples/ts/gauge-multi-title.ts            |  125 +-
 public/examples/ts/gauge-progress.ts               |  169 +-
 public/examples/ts/gauge-ring.ts                   |  161 +-
 public/examples/ts/gauge-simple.ts                 |   42 +-
 public/examples/ts/gauge-speed.ts                  |   98 +-
 public/examples/ts/gauge-stage.ts                  |  118 +-
 public/examples/ts/gauge-temperature.ts            |  242 +-
 public/examples/ts/gauge.ts                        |   34 +-
 public/examples/ts/geo-beef-cuts.ts                |  127 +-
 public/examples/ts/geo-lines.js                    |  531 ++--
 public/examples/ts/geo-map-scatter.js              |  653 +++--
 public/examples/ts/geo-organ.js                    |  133 +-
 public/examples/ts/geo-seatmap-flight.ts           |  147 +-
 public/examples/ts/geo-svg-lines.ts                |  149 +-
 public/examples/ts/geo-svg-map.ts                  |  359 +--
 public/examples/ts/geo-svg-scatter-simple.ts       |   90 +-
 public/examples/ts/geo-svg-traffic.ts              |  307 +--
 public/examples/ts/graph-circular-layout.ts        |  100 +-
 public/examples/ts/graph-force-dynamic.ts          |   76 +-
 public/examples/ts/graph-force.ts                  |   84 +-
 public/examples/ts/graph-force2.ts                 |   86 +-
 public/examples/ts/graph-grid.ts                   |   72 +-
 public/examples/ts/graph-label-overlap.ts          |   78 +-
 public/examples/ts/graph-life-expectancy.ts        |  181 +-
 public/examples/ts/graph-npm.ts                    |   84 +-
 public/examples/ts/graph-simple.ts                 |  166 +-
 public/examples/ts/graph-webkit-dep.ts             |   58 +-
 public/examples/ts/graph.ts                        |  108 +-
 public/examples/ts/grid-multiple.ts                |  216 +-
 public/examples/ts/heatmap-bmap.js                 |   76 +-
 public/examples/ts/heatmap-cartesian.ts            |  108 +-
 public/examples/ts/heatmap-large-piecewise.js      |  418 ++--
 public/examples/ts/heatmap-large.js                |  402 ++--
 public/examples/ts/heatmap-map.js                  |  862 +++----
 public/examples/ts/line-aqi.ts                     |  194 +-
 public/examples/ts/line-draggable.ts               |  227 +-
 public/examples/ts/line-easing.ts                  |  467 ++--
 public/examples/ts/line-function.ts                |  114 +-
 public/examples/ts/line-gradient.ts                |  129 +-
 public/examples/ts/line-graphic.ts                 |  210 +-
 .../ts/line-in-cartesian-coordinate-system.ts      |   20 +-
 public/examples/ts/line-log.ts                     |  103 +-
 public/examples/ts/line-marker.ts                  |  149 +-
 public/examples/ts/line-markline.ts                |  133 +-
 public/examples/ts/line-pen.ts                     |  114 +-
 public/examples/ts/line-polar.ts                   |   59 +-
 public/examples/ts/line-polar2.ts                  |   70 +-
 public/examples/ts/line-race.ts                    |  163 +-
 public/examples/ts/line-sections.ts                |  168 +-
 public/examples/ts/line-simple.ts                  |   26 +-
 public/examples/ts/line-smooth.ts                  |   28 +-
 public/examples/ts/line-stack.ts                   |  114 +-
 public/examples/ts/line-step.ts                    |   92 +-
 public/examples/ts/line-style.ts                   |   50 +-
 public/examples/ts/line-tooltip-touch.ts           |  256 +-
 public/examples/ts/line-y-category.ts              |   88 +-
 public/examples/ts/lines-airline.ts                |  107 +-
 public/examples/ts/lines-bmap-bus.ts               |  299 +--
 public/examples/ts/lines-bmap-effect.ts            |  371 +--
 public/examples/ts/lines-bmap.ts                   |  265 +-
 public/examples/ts/lines-ny.ts                     |  148 +-
 public/examples/ts/map-HK.ts                       |  176 +-
 public/examples/ts/map-bar-morph.ts                |  260 +-
 public/examples/ts/map-bin.js                      |  395 +--
 public/examples/ts/map-china-dataRange.js          |  250 +-
 public/examples/ts/map-china.js                    |   36 +-
 public/examples/ts/map-labels.js                   |  294 +--
 public/examples/ts/map-locate.js                   |   76 +-
 public/examples/ts/map-polygon.js                  | 1265 +++++-----
 public/examples/ts/map-province.js                 |  150 +-
 public/examples/ts/map-usa.ts                      |  265 +-
 public/examples/ts/map-world-dataRange.js          |  459 ++--
 public/examples/ts/map-world.js                    |  404 ++--
 public/examples/ts/mix-line-bar.ts                 |  139 +-
 public/examples/ts/mix-timeline-finance.js         |  598 ++---
 public/examples/ts/mix-zoom-on-value.ts            |  166 +-
 public/examples/ts/multiple-x-axis.ts              |  173 +-
 public/examples/ts/multiple-y-axis.ts              |  191 +-
 public/examples/ts/parallel-aqi.ts                 |  386 +--
 public/examples/ts/parallel-nutrients.ts           |  306 ++-
 public/examples/ts/parallel-simple.ts              |   45 +-
 public/examples/ts/pictorialBar-bar-transition.ts  |  253 +-
 public/examples/ts/pictorialBar-body-fill.ts       |  270 ++-
 public/examples/ts/pictorialBar-dotted.ts          |  178 +-
 public/examples/ts/pictorialBar-forest.ts          |  170 +-
 public/examples/ts/pictorialBar-hill.ts            |  214 +-
 public/examples/ts/pictorialBar-spirit.ts          |  193 +-
 public/examples/ts/pictorialBar-vehicle.ts         |  200 +-
 public/examples/ts/pictorialBar-velocity.ts        |  186 +-
 public/examples/ts/pie-alignTo.ts                  |  160 +-
 public/examples/ts/pie-borderRadius.ts             |   82 +-
 public/examples/ts/pie-custom.ts                   |  118 +-
 public/examples/ts/pie-doughnut.ts                 |   72 +-
 public/examples/ts/pie-labelLine-adjust.ts         |  162 +-
 public/examples/ts/pie-legend.ts                   |  124 +-
 public/examples/ts/pie-nest.ts                     |  163 +-
 public/examples/ts/pie-parliament-transition.ts    |  242 +-
 public/examples/ts/pie-pattern.ts                  |   92 +-
 public/examples/ts/pie-rich-text.ts                |  240 +-
 public/examples/ts/pie-roseType-simple.ts          |   70 +-
 public/examples/ts/pie-roseType.ts                 |  153 +-
 public/examples/ts/pie-simple.ts                   |   66 +-
 public/examples/ts/polar-roundCap.ts               |   80 +-
 public/examples/ts/radar-aqi.ts                    |  371 +--
 public/examples/ts/radar-custom.ts                 |  226 +-
 public/examples/ts/radar-multiple.ts               |  168 +-
 public/examples/ts/radar.ts                        |   66 +-
 public/examples/ts/radar2.ts                       |  128 +-
 public/examples/ts/sankey-energy.ts                |   52 +-
 public/examples/ts/sankey-itemstyle.ts             | 2544 ++++++++++----------
 public/examples/ts/sankey-levels.ts                |  125 +-
 public/examples/ts/sankey-nodeAlign-left.ts        |   54 +-
 public/examples/ts/sankey-nodeAlign-right.ts       |   55 +-
 public/examples/ts/sankey-simple.ts                |  106 +-
 public/examples/ts/sankey-vertical.ts              |   80 +-
 public/examples/ts/scatter-aggregate-bar.ts        |  134 +-
 public/examples/ts/scatter-anscombe-quartet.ts     |  255 +-
 public/examples/ts/scatter-aqi-color.ts            |  458 ++--
 public/examples/ts/scatter-clustering-process.js   |  405 ++--
 public/examples/ts/scatter-clustering.ts           |  221 +-
 public/examples/ts/scatter-effect.ts               |   40 +-
 .../examples/ts/scatter-exponential-regression.ts  |  146 +-
 public/examples/ts/scatter-label-align-right.ts    |   93 +-
 public/examples/ts/scatter-label-align-top.ts      |   80 +-
 public/examples/ts/scatter-large.ts                |  114 +-
 .../ts/scatter-life-expectancy-timeline.js         |  309 +--
 public/examples/ts/scatter-linear-regression.ts    |  507 ++--
 .../examples/ts/scatter-logarithmic-regression.ts  |  244 +-
 public/examples/ts/scatter-map-brush.ts            | 1389 ++++++-----
 public/examples/ts/scatter-map.js                  |  908 +++----
 public/examples/ts/scatter-matrix.ts               |  528 ++--
 public/examples/ts/scatter-nebula.ts               |  119 +-
 public/examples/ts/scatter-nutrients-matrix.ts     |  774 +++---
 public/examples/ts/scatter-nutrients.ts            |  267 +-
 public/examples/ts/scatter-painter-choice.ts       |   77 +-
 public/examples/ts/scatter-polar-punchCard.ts      |  117 +-
 .../examples/ts/scatter-polynomial-regression.ts   |  141 +-
 public/examples/ts/scatter-punchCard.ts            |  123 +-
 public/examples/ts/scatter-simple.ts               |   65 +-
 public/examples/ts/scatter-single-axis.ts          |   86 +-
 public/examples/ts/scatter-stream-visual.ts        |   88 +-
 public/examples/ts/scatter-symbol-morph.ts         |  189 +-
 public/examples/ts/scatter-weibo.ts                |  119 +-
 public/examples/ts/scatter-weight.ts               |  511 ++--
 public/examples/ts/scatter-world-population.js     |  985 ++++----
 public/examples/ts/sunburst-book.js                |  561 +++--
 public/examples/ts/sunburst-borderRadius.ts        |   84 +-
 public/examples/ts/sunburst-drink.ts               |  729 +++---
 public/examples/ts/sunburst-label-rotate.ts        |  194 +-
 public/examples/ts/sunburst-monochrome.ts          |  250 +-
 public/examples/ts/sunburst-simple.ts              |   82 +-
 public/examples/ts/sunburst-visualMap.ts           |  127 +-
 public/examples/ts/themeRiver-basic.ts             |  259 +-
 public/examples/ts/themeRiver-lastfm.ts            |  123 +-
 public/examples/ts/tree-basic.ts                   |  100 +-
 public/examples/ts/tree-legend.ts                  |  429 ++--
 public/examples/ts/tree-orient-bottom-top.ts       |   81 +-
 public/examples/ts/tree-orient-right-left.ts       |   86 +-
 public/examples/ts/tree-polyline.ts                |  310 ++-
 public/examples/ts/tree-radial.ts                  |   50 +-
 public/examples/ts/tree-vertical.ts                |   92 +-
 public/examples/ts/treemap-disk.ts                 |  127 +-
 public/examples/ts/treemap-drill-down.ts           |  157 +-
 public/examples/ts/treemap-obama.ts                |  355 +--
 public/examples/ts/treemap-show-parent.ts          |  157 +-
 public/examples/ts/treemap-simple.ts               |   64 +-
 public/examples/ts/treemap-sunburst-transition.ts  |   80 +-
 public/examples/ts/treemap-visual.ts               |  204 +-
 public/examples/ts/watermark.ts                    |  390 +--
 public/examples/ts/wind-barb.ts                    |  510 ++--
 public/zh/editor.html                              |   53 +-
 public/zh/index.html                               |   54 +-
 public/zh/view.html                                |   53 +-
 src/common/config.js                               |  224 +-
 src/common/helper.js                               |  105 +-
 src/common/i18n.js                                 |  236 +-
 src/common/store.js                                |   80 +-
 src/dep/showDebugDirtyRect.js                      |  152 +-
 src/editor/CodeAce.vue                             |  195 +-
 src/editor/CodeMonaco.vue                          |  268 ++-
 src/editor/Editor.vue                              |  772 +++---
 src/editor/FullCodePreview.vue                     |  139 +-
 src/editor/Preview.vue                             |  728 +++---
 src/editor/View.vue                                |   27 +-
 src/editor/downloadExample.js                      |   22 +-
 src/editor/object-visualizer.css                   |  122 +-
 src/editor/sandbox.js                              |  376 +--
 src/editor/transformTs.js                          |   10 +-
 src/explore/ExampleCard.vue                        |  236 +-
 src/explore/Explore.vue                            |  672 +++---
 src/main.js                                        |   61 +-
 src/style/color.scss                               |   42 +-
 src/style/config.xl.scss                           | 1219 +++++-----
 tool/build-example.js                              |  695 +++---
 tool/screenshot.html                               |  317 +--
 tool/seedrandom.js                                 |  459 ++--
 tool/updateFrontMatter.js                          |   43 +-
 321 files changed, 37081 insertions(+), 33880 deletions(-)
 create mode 100644 .eslintrc.js
 copy .gitignore => .prettierignore (71%)
 create mode 100644 .prettierrc
 create mode 100644 .vscode/settings.json

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


[echarts-examples] 01/02: use prettier to format code

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

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

commit 16a668348fea384ceb3c90558616e04eda103199
Author: pissang <bm...@gmail.com>
AuthorDate: Mon Sep 6 12:59:21 2021 +0800

    use prettier to format code
---
 .babelrc                         |   11 +-
 .eslintrc.js                     |   13 +
 .eslintrc.yaml                   |  194 ------
 .gitignore                       |    1 +
 .gitignore => .prettierignore    |   14 +-
 .prettierrc                      |    7 +
 .vscode/settings.json            |    4 +
 README.md                        |   24 +-
 build/copyResource.js            |  139 ++--
 build/server.js                  |   24 +-
 build/webpack.config.js          |  155 ++---
 common/buildCode.js              |  611 +++++++++---------
 common/compareImage.js           |   81 +--
 common/task.js                   |   96 ++-
 config/common.js                 |    6 +-
 config/env.asf.js                |    2 +-
 config/env.dev.js                |    2 +-
 config/env.localsite.js          |    2 +-
 e2e/cases/README.md              |    2 +-
 e2e/cases/liquidfill.js          |   14 +-
 e2e/cases/wordcloud.js           |  230 +++----
 e2e/config.js                    |   58 +-
 e2e/main.js                      | 1290 +++++++++++++++++++++-----------------
 e2e/package.json                 |    3 +-
 e2e/preview.html                 |   47 +-
 e2e/report.html                  |  353 ++++++-----
 e2e/template.html                |   47 +-
 e2e/tsconfig.json                |   18 +-
 e2e/webpack.config.js            |   29 +-
 public/en/editor.html            |   53 +-
 public/en/index.html             |   54 +-
 public/en/view.html              |   53 +-
 public/zh/editor.html            |   53 +-
 public/zh/index.html             |   54 +-
 public/zh/view.html              |   53 +-
 src/common/config.js             |  224 +++----
 src/common/helper.js             |  105 ++--
 src/common/i18n.js               |  236 +++----
 src/common/store.js              |   80 +--
 src/dep/showDebugDirtyRect.js    |  152 ++---
 src/editor/CodeAce.vue           |  195 +++---
 src/editor/CodeMonaco.vue        |  267 ++++----
 src/editor/Editor.vue            |  772 ++++++++++++-----------
 src/editor/FullCodePreview.vue   |  139 ++--
 src/editor/Preview.vue           |  728 ++++++++++-----------
 src/editor/View.vue              |   27 +-
 src/editor/downloadExample.js    |   22 +-
 src/editor/object-visualizer.css |  122 ++--
 src/editor/sandbox.js            |  376 +++++------
 src/editor/transformTs.js        |   10 +-
 src/explore/ExampleCard.vue      |  236 +++----
 src/explore/Explore.vue          |  672 ++++++++++----------
 src/main.js                      |   61 +-
 src/style/color.scss             |   42 +-
 src/style/config.xl.scss         | 1219 ++++++++++++++++++-----------------
 tool/build-example.js            |  695 ++++++++++----------
 tool/screenshot.html             |  317 ++++++----
 tool/seedrandom.js               |  459 ++++++++------
 tool/updateFrontMatter.js        |   43 +-
 59 files changed, 5707 insertions(+), 5289 deletions(-)

diff --git a/.babelrc b/.babelrc
index e87d71a..9da67db 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,5 +1,10 @@
 {
-    "presets": [["@babel/preset-env", {
+  "presets": [
+    [
+      "@babel/preset-env",
+      {
         "modules": false
-    }]]
-}
\ No newline at end of file
+      }
+    ]
+  ]
+}
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..d64a787
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,13 @@
+module.exports = {
+  root: true,
+  env: {
+    browser: true,
+    node: true
+  },
+  extends: ['prettier', 'prettier/vue'],
+  plugins: ['prettier'],
+  // add your custom rules here
+  rules: {
+    'space-before-function-paren': 0
+  }
+};
diff --git a/.eslintrc.yaml b/.eslintrc.yaml
deleted file mode 100644
index e4a2cee..0000000
--- a/.eslintrc.yaml
+++ /dev/null
@@ -1,194 +0,0 @@
-# Note:
-# If eslint does not work in VSCode, please check:
-# (1) Whether "@typescript-eslint/eslint-plugin" and "@typescript-eslint/parser"
-# are npm installed locally. Should better in the same version.
-# (2) Whether "VSCode ESlint extension" is installed.
-# (3) If the project folder is not the root folder of your working space, please
-# config the "VSCode ESlint extension" in "settings":
-# ```json
-# "eslint.workingDirectories": [{"mode": "auto"}]
-# ```
-# Note that it should be "workingDirectories" rather than "WorkingDirectories".
-
-rules:
-    # Check the rules in: node_modules/@typescript-eslint/eslint-plugin/README.md
-    no-console:
-        - 2
-        -
-            allow:
-                - "warn"
-                - "error"
-    prefer-const: 1
-    no-constant-condition: 0
-    comma-dangle: 2
-    no-debugger: 2
-    no-dupe-keys: 2
-    no-empty-character-class: 2
-    no-ex-assign: 2
-    no-extra-boolean-cast: 0
-    no-func-assign: 2
-    no-inner-declarations: 2
-    no-invalid-regexp: 2
-    no-negated-in-lhs: 2
-    no-obj-calls: 2
-    no-sparse-arrays: 2
-    no-unreachable: 2
-    use-isnan: 2
-    valid-typeof: 2
-    block-scoped-var: 2
-    curly:
-        - 2
-        - "all"
-    eqeqeq:
-        - 2
-        - "allow-null"
-    guard-for-in: 2
-    no-else-return: 0
-    no-labels:
-        - 2
-        -
-            allowLoop: true
-    no-eval: 2
-    no-extend-native: 2
-    no-extra-bind: 0
-    no-implied-eval: 2
-    no-iterator: 2
-    no-irregular-whitespace: 2
-    no-lone-blocks: 2
-    no-loop-func: 2
-    no-multi-str: 2
-    no-native-reassign: 2
-    no-new-wrappers: 2
-    no-octal: 2
-    no-octal-escape: 2
-    no-proto: 2
-    no-redeclare: 2
-    no-self-compare: 2
-    no-unneeded-ternary: 2
-    no-with: 2
-    radix: 2
-    wrap-iife:
-        - 2
-        - "any"
-    no-delete-var: 2
-    no-dupe-args: 2
-    no-duplicate-case: 2
-    no-label-var: 2
-    no-shadow-restricted-names: 2
-    no-undef: 2
-    no-undef-init: 2
-    "no-use-before-define": 0
-    brace-style:
-        - 2
-        - "stroustrup"
-        - {}
-    comma-spacing:
-        - 2
-        -
-            before: false
-            after: true
-    comma-style:
-        - 2
-        - "last"
-    new-parens: 2
-    no-array-constructor: 2
-    no-multi-spaces:
-        - 1
-        -
-            ignoreEOLComments: true
-            exceptions:
-                Property: true
-    no-new-object: 2
-    no-trailing-spaces: 2
-    no-extra-parens:
-        - 2
-        - "functions"
-    no-mixed-spaces-and-tabs: 2
-    one-var:
-        - 2
-        - "never"
-    operator-linebreak:
-        - 2
-        - "before"
-        -
-            overrides:
-                "=": "after"
-    "quotes":
-        - 2
-        - "single"
-    "semi":
-        - 2
-        - "always"
-    semi-spacing: 2
-    keyword-spacing: 2
-    key-spacing:
-        - 2
-        -
-            beforeColon: false
-            afterColon: true
-    "space-before-function-paren":
-        - 2
-        -
-            anonymous: "always"
-            named: "never"
-    space-before-blocks:
-        - 2
-        - "always"
-    computed-property-spacing:
-        - 2
-        - "never"
-    space-in-parens:
-        - 2
-        - "never"
-    space-unary-ops: 2
-    spaced-comment: 0
-
-    max-nested-callbacks:
-        - 1
-        - 5
-    max-depth:
-        - 1
-        - 6
-    max-len:
-        - 2
-        - 120
-        - 4
-        -
-            ignoreUrls: true
-            ignoreComments: true
-    max-params:
-        - 1
-        - 15
-
-    space-infix-ops: 2
-    dot-notation:
-        - 2
-        -
-            allowKeywords: true
-            allowPattern: "^catch$"
-
-    arrow-spacing: 2
-    constructor-super: 2
-    no-confusing-arrow:
-        - 2
-        -
-            allowParens: true
-    no-class-assign: 2
-    no-const-assign: 2
-    # no-dupe-class-members: 2
-    no-this-before-super: 0
-    no-duplicate-imports: 2
-    prefer-rest-params: 0
-    unicode-bom: 2
-    max-statements-per-line: 2
-
-    no-useless-constructor: 0
-    indent: ["warn", 4]
-
-    "func-call-spacing": "error"
-
-    "no-unused-vars":
-        - 1
-        -
-            vars: "local"
-            args: "none"
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index b862812..5e01c25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,7 @@ public/vendors/echarts/map/raw
 /public/asset
 /public/data/option
 /public/data-gl/option
+/public/examples/js
 /e2e/package-lock.json
 
 tmp
diff --git a/.gitignore b/.prettierignore
similarity index 71%
copy from .gitignore
copy to .prettierignore
index b862812..84fc23f 100644
--- a/.gitignore
+++ b/.prettierignore
@@ -1,8 +1,16 @@
+public/data
+public/data-gl
+src/data
+src/data
+src/data
+
+
+
+# From git ignore
 node_modules
 release
 public/vendors/echarts/map/tool
 public/vendors/echarts/map/raw
-.DS_Store
 /public.zip
 /build/config.gypi
 /public-gh
@@ -14,7 +22,7 @@ public/vendors/echarts/map/raw
 /public/asset
 /public/data/option
 /public/data-gl/option
+/public/examples/js
 /e2e/package-lock.json
 
-tmp
-.webm
\ No newline at end of file
+tmp
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..3410e80
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,7 @@
+{
+  "tabWidth": 2,
+  "semi": true,
+  "singleQuote": true,
+  "trailingComma": "none",
+  "printWidth": 80
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..1b6457c
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+  "editor.formatOnSave": true,
+  "editor.defaultFormatter": "esbenp.prettier-vscode"
+}
diff --git a/README.md b/README.md
index 5891e3f..d2c7314 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,6 @@ It will copy all the build resources to echarts-website/next/examples
 1. Update the URL of localEChartsMinJS in `common/config.js`
 2. Add `local=1` in URL. For example: `editor.html?c=area-basic&local=1`
 
-
 ## Edit example
 
 All test cases are in the `public/examples/ts` folder. The comment in the header
@@ -59,26 +58,27 @@ Most of examples are written in `TypeScript`. You need to comile it to `JavaScri
 npm run compile:example
 ```
 
-
 ## Some built-in features available in examples
 
 ### Import third-party library
 
 For example:
+
 ```js
 $.when(
-    $.getScript(ROOT_PATH + '/data/asset/js/xxxx.js'),
-    $.getScript('https://cdn.jsdelivr.net/npm/d3-contour@2.0.0/dist/d3-contour.jXs'),
+  $.getScript(ROOT_PATH + '/data/asset/js/xxxx.js'),
+  $.getScript(
+    'https://cdn.jsdelivr.net/npm/d3-contour@2.0.0/dist/d3-contour.jXs'
+  )
 ).done(function () {
-    // ...
+  // ...
 });
 ```
 
-
-
 ### Controller panel
 
 Use this code to enable controller panel for a example:
+
 ```js
 app.config = {
     aNameForTheSelectWidget: 'This is the initial value'
@@ -109,8 +109,8 @@ app.configParameters = {
 
 ```js
 app.onresize = function () {
-    // Do something.
-}
+  // Do something.
+};
 ```
 
 ### Get width and height of the chart area
@@ -120,7 +120,6 @@ var width = myChart.getWidth();
 var height = myChart.getHeight();
 ```
 
-
 ## Update example snapshots
 
 ```shell
@@ -133,7 +132,6 @@ Only for default theme
 node tool/build-example.js -t default
 ```
 
-
 ## Run e2e tests.
 
 Run all the examples to test package publishing and install, module importing, minimal bundling and DTS correctness.
@@ -145,6 +143,7 @@ npm run build:example
 ```
 
 Then run the tests.
+
 ```shell
 npm run test:e2e
 ```
@@ -152,6 +151,7 @@ npm run test:e2e
 You can change the testing branch or local dir, which is available when add `--local` in `e2e/config.js`
 
 If you want to test with esbuild bundler. Which is much faster.
+
 ```shell
 npm run test:e2e:esbuild
 ```
@@ -178,5 +178,3 @@ Specify matched tests.
 ```shell
 node e2e/main.js --skip npm --tests bar3D*
 ```
-
-
diff --git a/build/copyResource.js b/build/copyResource.js
index d36d55d..bfa378a 100644
--- a/build/copyResource.js
+++ b/build/copyResource.js
@@ -23,78 +23,91 @@ const projectDir = __dirname;
  */
 
 function initEnv() {
-    let envType = argv.env;
-    let isDev = argv.dev != null || argv.debug != null || envType === 'debug' || envType === 'dev';
-
-    if (isDev) {
-        console.warn('====================================================================');
-        console.warn('THIS IS IN DEV MODE');
-        console.warn('!!! Please input your local host in `config/env.dev.js` firstly !!!');
-        console.warn('====================================================================');
-        envType = 'dev';
-    }
-
-    if (!envType) {
-        throw new Error('--env MUST be specified');
-    }
-
-    let config = require('../config/env.' + envType);
-
-    if (isDev) {
-        console.warn('====================================================================');
-        console.warn('Please visit the website: ');
-        console.warn(config.host);
-        console.warn('====================================================================');
-    }
-
-    assert(path.isAbsolute(config.releaseDestDir));
-
-    config.envType = envType;
-
-    return config;
+  let envType = argv.env;
+  let isDev =
+    argv.dev != null ||
+    argv.debug != null ||
+    envType === 'debug' ||
+    envType === 'dev';
+
+  if (isDev) {
+    console.warn(
+      '===================================================================='
+    );
+    console.warn('THIS IS IN DEV MODE');
+    console.warn(
+      '!!! Please input your local host in `config/env.dev.js` firstly !!!'
+    );
+    console.warn(
+      '===================================================================='
+    );
+    envType = 'dev';
+  }
+
+  if (!envType) {
+    throw new Error('--env MUST be specified');
+  }
+
+  let config = require('../config/env.' + envType);
+
+  if (isDev) {
+    console.warn(
+      '===================================================================='
+    );
+    console.warn('Please visit the website: ');
+    console.warn(config.host);
+    console.warn(
+      '===================================================================='
+    );
+  }
+
+  assert(path.isAbsolute(config.releaseDestDir));
+
+  config.envType = envType;
+
+  return config;
 }
 
 async function copyResourcesToDest(config) {
-    let basePath = path.resolve(projectDir, '../public');
-    const filePaths = await globby([
-        '**/*',
-        // Use jade in echarts-www
-        '!zh/*',
-        '!en/*'
-    ], {
-        cwd: basePath
-    });
-
-    console.log();
-
-    for (let filePath of filePaths) {
-        fse.ensureDirSync(
-            path.resolve(config.releaseDestDir, path.dirname(filePath))
-        );
-        let destPath = path.resolve(config.releaseDestDir, filePath);
-        fs.copyFileSync(
-            path.resolve(basePath, filePath),
-            destPath
-        );
-
-        if (process.stdout.clearLine) {
-            process.stdout.clearLine();
-            process.stdout.cursorTo(0);
-            process.stdout.write(chalk.green(`resource copied to: ${destPath}`));
-        }
-        else {
-            console.log(chalk.green(`resource copied to: ${destPath}`));
-        }
+  let basePath = path.resolve(projectDir, '../public');
+  const filePaths = await globby(
+    [
+      '**/*',
+      // Use jade in echarts-www
+      '!zh/*',
+      '!en/*'
+    ],
+    {
+      cwd: basePath
+    }
+  );
+
+  console.log();
+
+  for (let filePath of filePaths) {
+    fse.ensureDirSync(
+      path.resolve(config.releaseDestDir, path.dirname(filePath))
+    );
+    let destPath = path.resolve(config.releaseDestDir, filePath);
+    fs.copyFileSync(path.resolve(basePath, filePath), destPath);
+
+    if (process.stdout.clearLine) {
+      process.stdout.clearLine();
+      process.stdout.cursorTo(0);
+      process.stdout.write(chalk.green(`resource copied to: ${destPath}`));
+    } else {
+      console.log(chalk.green(`resource copied to: ${destPath}`));
     }
+  }
 
-    console.log('\ncopyResourcesToDest done.');
+  console.log('\ncopyResourcesToDest done.');
 }
 
 async function run() {
-    let config = initEnv();
-    await copyResourcesToDest(config);
+  let config = initEnv();
+  await copyResourcesToDest(config);
 
-    console.log('All done.');
+  console.log('All done.');
 }
 
 run();
diff --git a/build/server.js b/build/server.js
index 77b0da6..03867d2 100644
--- a/build/server.js
+++ b/build/server.js
@@ -2,19 +2,23 @@ const nStatic = require('node-static');
 const open = require('open');
 
 const fileServer = new nStatic.Server(__dirname + '/../public');
-require('http').createServer(function (request, response) {
-    request.addListener('end', function () {
+require('http')
+  .createServer(function (request, response) {
+    request
+      .addListener('end', function () {
         fileServer.serve(request, response);
-    }).resume();
-}).listen(3002);
+      })
+      .resume();
+  })
+  .listen(3002);
 
 // Wait bundling to be finished
 setTimeout(() => {
-    open('http://127.0.0.1:3002/en/index.html');
+  open('http://127.0.0.1:3002/en/index.html');
 }, 3000);
 
-process.on('SIGINT', function() {
-    console.log('Closing');
-    // Close through ctrl + c;
-    process.exit();
-});
\ No newline at end of file
+process.on('SIGINT', function () {
+  console.log('Closing');
+  // Close through ctrl + c;
+  process.exit();
+});
diff --git a/build/webpack.config.js b/build/webpack.config.js
index 3107a0c..80dd631 100644
--- a/build/webpack.config.js
+++ b/build/webpack.config.js
@@ -6,81 +6,94 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 const distPath = path.resolve(__dirname, '../public');
 
 module.exports = [
-    {
-        entry: path.resolve(__dirname, '../src/main.js'),
-        output: {
-            publicPath: './',
-            filename: 'example-bundle.js',
-            path: path.join(distPath, 'js'),
-            library: 'echartsExample',
-            libraryTarget: 'var'
+  {
+    entry: path.resolve(__dirname, '../src/main.js'),
+    output: {
+      publicPath: './',
+      filename: 'example-bundle.js',
+      path: path.join(distPath, 'js'),
+      library: 'echartsExample',
+      libraryTarget: 'var'
+    },
+    stats: 'minimal',
+    module: {
+      rules: [
+        {
+          test: /\.vue$/,
+          use: ['vue-loader']
         },
-        stats: 'minimal',
-        module: {
-            rules: [{
-                test: /\.vue$/,
-                use: ['vue-loader']
-            }, {
-                test: /\.js$/,
-                use: ['babel-loader'],
-                exclude: /node_modules/
-            }, {
-                test: /\.css$/,
-                use: [MiniCssExtractPlugin.loader, 'css-loader']
-            }, {
-                test: /\.scss$/,
-                use: [MiniCssExtractPlugin.loader, 'css-loader', 'sassjs-loader']
-            }, {
-                test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2)(\?.+)?$/,
-                use: [{
-                    loader: 'file-loader',
-                    options: {
-                        limit: 10000,
-                        outputPath: '../asset',
-                        name: '[name].[ext]'
-                    }
-                }]
-            }, {
-                test: /\.svg$/,
-                use: [{
-                    loader: 'html-loader',
-                    options: {
-                        minimize: true
-                    }
-                }]
-              },]
+        {
+          test: /\.js$/,
+          use: ['babel-loader'],
+          exclude: /node_modules/
         },
-        externals: {
-            vue: 'Vue'
+        {
+          test: /\.css$/,
+          use: [MiniCssExtractPlugin.loader, 'css-loader']
         },
-        plugins: [
-            new webpack.IgnorePlugin(/^fs$/),
-            new VueLoaderPlugin(),
-            new MiniCssExtractPlugin({
-                filename: '../css/example-bundle.css'
-            })
-        ]
-    },
-    {
-        // Sepearte built ts transformer to be loaded async
-        entry: path.resolve(__dirname, '../src/editor/transformTs.js'),
-        stats: 'minimal',
-        module: {
-            rules: [{
-                test: /\.m?js$/,
-                include: /node_modules/,
-                type: 'javascript/auto',
-                resolve: {
-                    fullySpecified: false
-                }
-            }]
+        {
+          test: /\.scss$/,
+          use: [MiniCssExtractPlugin.loader, 'css-loader', 'sassjs-loader']
         },
-        output: {
-            filename: 'example-transform-ts-bundle.js',
-            path: path.join(distPath, 'js'),
-            library: 'echartsExampleTransformTs',
-            libraryExport: 'default',
-            libraryTarget: 'var'
+        {
+          test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2)(\?.+)?$/,
+          use: [
+            {
+              loader: 'file-loader',
+              options: {
+                limit: 10000,
+                outputPath: '../asset',
+                name: '[name].[ext]'
+              }
+            }
+          ]
+        },
+        {
+          test: /\.svg$/,
+          use: [
+            {
+              loader: 'html-loader',
+              options: {
+                minimize: true
+              }
+            }
+          ]
         }
+      ]
+    },
+    externals: {
+      vue: 'Vue'
+    },
+    plugins: [
+      new webpack.IgnorePlugin(/^fs$/),
+      new VueLoaderPlugin(),
+      new MiniCssExtractPlugin({
+        filename: '../css/example-bundle.css'
+      })
+    ]
+  },
+  {
+    // Sepearte built ts transformer to be loaded async
+    entry: path.resolve(__dirname, '../src/editor/transformTs.js'),
+    stats: 'minimal',
+    module: {
+      rules: [
+        {
+          test: /\.m?js$/,
+          include: /node_modules/,
+          type: 'javascript/auto',
+          resolve: {
+            fullySpecified: false
+          }
+        }
+      ]
+    },
+    output: {
+      filename: 'example-transform-ts-bundle.js',
+      path: path.join(distPath, 'js'),
+      library: 'echartsExampleTransformTs',
+      libraryExport: 'default',
+      libraryTarget: 'var'
     }
+  }
 ];
diff --git a/common/buildCode.js b/common/buildCode.js
index f0f5afa..64e4204 100644
--- a/common/buildCode.js
+++ b/common/buildCode.js
@@ -1,84 +1,83 @@
 const COMPONENTS_MAP = {
-    grid: 'GridComponent',
-    polar: 'PolarComponent',
-    geo: 'GeoComponent',
-    singleAxis: 'SingleAxisComponent',
-    parallel: 'ParallelComponent',
-    calendar: 'CalendarComponent',
-    graphic: 'GraphicComponent',
-    toolbox: 'ToolboxComponent',
-    tooltip: 'TooltipComponent',
-    axisPointer: 'AxisPointerComponent',
-    brush: 'BrushComponent',
-    title: 'TitleComponent',
-    timeline: 'TimelineComponent',
-    markPoint: 'MarkPointComponent',
-    markLine: 'MarkLineComponent',
-    markArea: 'MarkAreaComponent',
-    legend: 'LegendComponent',
-    dataZoom: 'DataZoomComponent',
-    visualMap: 'VisualMapComponent',
-    aria: 'AriaComponent',
-    dataset: 'DatasetComponent',
-
-    // Dependencies
-    xAxis: 'GridComponent',
-    yAxis: 'GridComponent',
-    angleAxis: 'PolarComponent',
-    radiusAxis: 'PolarComponent'
-}
+  grid: 'GridComponent',
+  polar: 'PolarComponent',
+  geo: 'GeoComponent',
+  singleAxis: 'SingleAxisComponent',
+  parallel: 'ParallelComponent',
+  calendar: 'CalendarComponent',
+  graphic: 'GraphicComponent',
+  toolbox: 'ToolboxComponent',
+  tooltip: 'TooltipComponent',
+  axisPointer: 'AxisPointerComponent',
+  brush: 'BrushComponent',
+  title: 'TitleComponent',
+  timeline: 'TimelineComponent',
+  markPoint: 'MarkPointComponent',
+  markLine: 'MarkLineComponent',
+  markArea: 'MarkAreaComponent',
+  legend: 'LegendComponent',
+  dataZoom: 'DataZoomComponent',
+  visualMap: 'VisualMapComponent',
+  aria: 'AriaComponent',
+  dataset: 'DatasetComponent',
+
+  // Dependencies
+  xAxis: 'GridComponent',
+  yAxis: 'GridComponent',
+  angleAxis: 'PolarComponent',
+  radiusAxis: 'PolarComponent'
+};
 
 const CHARTS_MAP = {
-    line: 'LineChart',
-    bar: 'BarChart',
-    pie: 'PieChart',
-    scatter: 'ScatterChart',
-    radar: 'RadarChart',
-    map: 'MapChart',
-    tree: 'TreeChart',
-    treemap: 'TreemapChart',
-    graph: 'GraphChart',
-    gauge: 'GaugeChart',
-    funnel: 'FunnelChart',
-    parallel: 'ParallelChart',
-    sankey: 'SankeyChart',
-    boxplot: 'BoxplotChart',
-    candlestick: 'CandlestickChart',
-    effectScatter: 'EffectScatterChart',
-    lines: 'LinesChart',
-    heatmap: 'HeatmapChart',
-    pictorialBar: 'PictorialBarChart',
-    themeRiver: 'ThemeRiverChart',
-    sunburst: 'SunburstChart',
-    custom: 'CustomChart'
-}
+  line: 'LineChart',
+  bar: 'BarChart',
+  pie: 'PieChart',
+  scatter: 'ScatterChart',
+  radar: 'RadarChart',
+  map: 'MapChart',
+  tree: 'TreeChart',
+  treemap: 'TreemapChart',
+  graph: 'GraphChart',
+  gauge: 'GaugeChart',
+  funnel: 'FunnelChart',
+  parallel: 'ParallelChart',
+  sankey: 'SankeyChart',
+  boxplot: 'BoxplotChart',
+  candlestick: 'CandlestickChart',
+  effectScatter: 'EffectScatterChart',
+  lines: 'LinesChart',
+  heatmap: 'HeatmapChart',
+  pictorialBar: 'PictorialBarChart',
+  themeRiver: 'ThemeRiverChart',
+  sunburst: 'SunburstChart',
+  custom: 'CustomChart'
+};
 const COMPONENTS_GL_MAP = {
-
-    grid3D: 'Grid3DComponent',
-    geo3D: 'Geo3DComponent',
-    globe: 'GlobeComponent',
-    mapbox3D: 'Mapbox3DComponent',
-    maptalks3D: 'Maptalks3DComponent',
-
-    // Dependencies
-    xAxis3D: 'Grid3DComponent',
-    yAxis3D: 'Grid3DComponent',
-    zAxis3D: 'Grid3DComponent',
-}
+  grid3D: 'Grid3DComponent',
+  geo3D: 'Geo3DComponent',
+  globe: 'GlobeComponent',
+  mapbox3D: 'Mapbox3DComponent',
+  maptalks3D: 'Maptalks3DComponent',
+
+  // Dependencies
+  xAxis3D: 'Grid3DComponent',
+  yAxis3D: 'Grid3DComponent',
+  zAxis3D: 'Grid3DComponent'
+};
 const CHARTS_GL_MAP = {
-    bar3D: 'Bar3DChart',
-    line3D: 'Line3DChart',
-    scatter3D: 'Scatter3DChart',
-    lines3D: 'Lines3DChart',
-    polygons3D: 'Polygons3DChart',
-    surface: 'SurfaceChart',
-    map3D: 'Map3DChart',
-
-    scatterGL: 'ScatterGLChart',
-    graphGL: 'GraphGLChart',
-    flowGL: 'FlowGLChart',
-    linesGL: 'LinesGLChart'
-}
+  bar3D: 'Bar3DChart',
+  line3D: 'Line3DChart',
+  scatter3D: 'Scatter3DChart',
+  lines3D: 'Lines3DChart',
+  polygons3D: 'Polygons3DChart',
+  surface: 'SurfaceChart',
+  map3D: 'Map3DChart',
+
+  scatterGL: 'ScatterGLChart',
+  graphGL: 'GraphGLChart',
+  flowGL: 'FlowGLChart',
+  linesGL: 'LinesGLChart'
+};
 
 const COMPONENTS_MAP_REVERSE = {};
 const CHARTS_MAP_REVERSE = {};
@@ -86,32 +85,39 @@ const CHARTS_GL_MAP_REVERSE = {};
 const COMPONENTS_GL_MAP_REVERSE = {};
 
 const RENDERERS_MAP_REVERSE = {
-    'SVGRenderer': 'svg',
-    'CanvasRenderer': 'canvas'
-}
+  SVGRenderer: 'svg',
+  CanvasRenderer: 'canvas'
+};
 
 // Component that will be injected automatically in preprocessor
 // These should be excluded util find they were used explicitly.
 const MARKERS = ['markLine', 'markArea', 'markPoint'];
 const INJECTED_COMPONENTS = [
-    ...MARKERS, 'grid', 'axisPointer',
-    'aria'  // TODO aria
+  ...MARKERS,
+  'grid',
+  'axisPointer',
+  'aria' // TODO aria
 ];
 
 // Component that was dependent.
 const DEPENDENT_COMPONENTS = [
-    'xAxis', 'yAxis', 'angleAxis', 'radiusAxis',
-    'xAxis3D', 'yAxis3D', 'zAxis3D'
+  'xAxis',
+  'yAxis',
+  'angleAxis',
+  'radiusAxis',
+  'xAxis3D',
+  'yAxis3D',
+  'zAxis3D'
 ];
 
 function createReverseMap(map, reverseMap) {
-    Object.keys(map).forEach(key => {
-        // Exclude dependencies.
-        if (DEPENDENT_COMPONENTS.includes(key)) {
-            return;
-        }
-        reverseMap[map[key]] = key;
-    });
+  Object.keys(map).forEach((key) => {
+    // Exclude dependencies.
+    if (DEPENDENT_COMPONENTS.includes(key)) {
+      return;
+    }
+    reverseMap[map[key]] = key;
+  });
 }
 
 createReverseMap(COMPONENTS_MAP, COMPONENTS_MAP_REVERSE);
@@ -120,248 +126,273 @@ createReverseMap(COMPONENTS_GL_MAP, COMPONENTS_GL_MAP_REVERSE);
 createReverseMap(CHARTS_GL_MAP, CHARTS_GL_MAP_REVERSE);
 
 module.exports.collectDeps = function collectDeps(option) {
-    let deps = [];
-    if (option.options) {
+  let deps = [];
+  if (option.options) {
+    // TODO getOption() doesn't have baseOption and options.
+    option.options.forEach((opt) => {
+      deps = deps.concat(collectDeps(opt));
+    });
 
-        // TODO getOption() doesn't have baseOption and options.
-        option.options.forEach((opt) => {
-            deps = deps.concat(collectDeps(opt));
-        });
+    if (option.baseOption) {
+      deps = deps.concat(collectDeps(option.baseOption));
+    }
 
-        if (option.baseOption) {
-            deps = deps.concat(collectDeps(option.baseOption))
-        }
+    // Remove duplicates
+    return Array.from(new Set(deps));
+  }
 
-        // Remove duplicates
-        return Array.from(new Set(deps));
+  Object.keys(option).forEach((key) => {
+    if (INJECTED_COMPONENTS.includes(key)) {
+      return;
     }
+    const val = option[key];
 
-    Object.keys(option).forEach((key) => {
-        if (INJECTED_COMPONENTS.includes(key)) {
-            return;
-        }
-        const val = option[key];
-
-        if (Array.isArray(val) && !val.length) {
-            return;
-        }
-
-        if (COMPONENTS_MAP[key]) {
-            deps.push(COMPONENTS_MAP[key]);
-        }
-        if (COMPONENTS_GL_MAP[key]) {
-            deps.push(COMPONENTS_GL_MAP[key]);
-        }
-    });
+    if (Array.isArray(val) && !val.length) {
+      return;
+    }
 
-    let series = option.series;
-    if (!Array.isArray(series)) {
-        series = [series];
+    if (COMPONENTS_MAP[key]) {
+      deps.push(COMPONENTS_MAP[key]);
     }
+    if (COMPONENTS_GL_MAP[key]) {
+      deps.push(COMPONENTS_GL_MAP[key]);
+    }
+  });
+
+  let series = option.series;
+  if (!Array.isArray(series)) {
+    series = [series];
+  }
 
-    series.forEach((seriesOpt) => {
-        if (CHARTS_MAP[seriesOpt.type]) {
-            deps.push(CHARTS_MAP[seriesOpt.type]);
-        }
-        if (CHARTS_GL_MAP[seriesOpt.type]) {
-            deps.push(CHARTS_GL_MAP[seriesOpt.type]);
-        }
-        if (seriesOpt.type === 'map') {
-            // Needs geo component when using map
-            deps.push(COMPONENTS_MAP.geo);
-        }
-        MARKERS.forEach(markerType => {
-            if (seriesOpt[markerType]) {
-                deps.push(COMPONENTS_MAP[markerType]);
-            }
-        });
+  series.forEach((seriesOpt) => {
+    if (CHARTS_MAP[seriesOpt.type]) {
+      deps.push(CHARTS_MAP[seriesOpt.type]);
+    }
+    if (CHARTS_GL_MAP[seriesOpt.type]) {
+      deps.push(CHARTS_GL_MAP[seriesOpt.type]);
+    }
+    if (seriesOpt.type === 'map') {
+      // Needs geo component when using map
+      deps.push(COMPONENTS_MAP.geo);
+    }
+    MARKERS.forEach((markerType) => {
+      if (seriesOpt[markerType]) {
+        deps.push(COMPONENTS_MAP[markerType]);
+      }
     });
+  });
 
-    // Remove duplicates
-    return Array.from(new Set(deps));
-}
+  // Remove duplicates
+  return Array.from(new Set(deps));
+};
 
 function buildMinimalBundleCode(deps, includeType) {
-    const chartsImports = [];
-    const componentsImports = [];
-    const chartsGLImports = [];
-    const componentsGLImports = [];
-    const renderersImports = [];
-    deps.forEach(function (dep) {
-        if (dep.endsWith('Renderer')) {
-            renderersImports.push(dep);
-        }
-        else if (CHARTS_MAP_REVERSE[dep]) {
-            chartsImports.push(dep);
-            if (includeType) {
-                chartsImports.push(dep.replace(/Chart$/, 'SeriesOption'));
-            }
-        }
-        else if (COMPONENTS_MAP_REVERSE[dep]) {
-            componentsImports.push(dep);
-            if (includeType) {
-                componentsImports.push(dep.replace(/Component$/, 'ComponentOption'));
-            }
-        }
-        else if (CHARTS_GL_MAP_REVERSE[dep]) {
-            chartsGLImports.push(dep)
-        }
-        else if (COMPONENTS_GL_MAP_REVERSE[dep]) {
-            componentsGLImports.push(dep);
-        }
-    });
-
-    function getImportsPartCode(imports) {
-        return `${imports.map(str => `
-    ${str}`).join(',')}`;
+  const chartsImports = [];
+  const componentsImports = [];
+  const chartsGLImports = [];
+  const componentsGLImports = [];
+  const renderersImports = [];
+  deps.forEach(function (dep) {
+    if (dep.endsWith('Renderer')) {
+      renderersImports.push(dep);
+    } else if (CHARTS_MAP_REVERSE[dep]) {
+      chartsImports.push(dep);
+      if (includeType) {
+        chartsImports.push(dep.replace(/Chart$/, 'SeriesOption'));
+      }
+    } else if (COMPONENTS_MAP_REVERSE[dep]) {
+      componentsImports.push(dep);
+      if (includeType) {
+        componentsImports.push(dep.replace(/Component$/, 'ComponentOption'));
+      }
+    } else if (CHARTS_GL_MAP_REVERSE[dep]) {
+      chartsGLImports.push(dep);
+    } else if (COMPONENTS_GL_MAP_REVERSE[dep]) {
+      componentsGLImports.push(dep);
     }
-
-    const allImports = [
-        ...componentsImports,
-        ...chartsImports,
-        ...componentsGLImports,
-        ...chartsGLImports,
-        ...renderersImports
-    ];
-
-    const ECOptionTypeCode = `
+  });
+
+  function getImportsPartCode(imports) {
+    return `${imports
+      .map(
+        (str) => `
+    ${str}`
+      )
+      .join(',')}`;
+  }
+
+  const allImports = [
+    ...componentsImports,
+    ...chartsImports,
+    ...componentsGLImports,
+    ...chartsGLImports,
+    ...renderersImports
+  ];
+
+  const ECOptionTypeCode = `
 type ECOption = echarts.ComposeOption<
-    ${allImports.filter(a => a.endsWith('Option')).join(' | ')}
+    ${allImports.filter((a) => a.endsWith('Option')).join(' | ')}
 >`;
-    const importsCodes = [
-        [componentsImports, 'echarts/components'],
-        [chartsImports, 'echarts/charts'],
-        [renderersImports, 'echarts/renderers'],
-        [chartsGLImports, 'echarts-gl/charts'],
-        [componentsGLImports, 'echarts-gl/components']
-    ].filter(a => a[0].length > 0).map(item => `
+  const importsCodes = [
+    [componentsImports, 'echarts/components'],
+    [chartsImports, 'echarts/charts'],
+    [renderersImports, 'echarts/renderers'],
+    [chartsGLImports, 'echarts-gl/charts'],
+    [componentsGLImports, 'echarts-gl/components']
+  ]
+    .filter((a) => a[0].length > 0)
+    .map((item) =>
+      `
 import {${getImportsPartCode(item[0])}
 } from '${item[1]}';
-    `.trim()).join('\n');
+    `.trim()
+    )
+    .join('\n');
 
-    return `import * as echarts from 'echarts/core';
+  return (
+    `import * as echarts from 'echarts/core';
 ${importsCodes}
 
 echarts.use(
-    [${allImports.filter(a => !a.endsWith('Option')).join(', ')}]
+    [${allImports.filter((a) => !a.endsWith('Option')).join(', ')}]
 );
 ` + (includeType ? ECOptionTypeCode : '')
+  );
 }
 
 module.exports.buildMinimalBundleCode = buildMinimalBundleCode;
 
 function buildLegacyMinimalBundleCode(deps, isESM) {
-    const modules = [];
-    deps.forEach(function (dep) {
-        if (dep.endsWith('Renderer') && dep !== 'CanvasRenderer') {
-            modules.push(`zrender/lib/${RENDERERS_MAP_REVERSE[dep]}/${RENDERERS_MAP_REVERSE[dep]}`);
-        }
-        else if (CHARTS_MAP_REVERSE[dep]) {
-            modules.push(`echarts/lib/chart/${CHARTS_MAP_REVERSE[dep]}`);
-        }
-        else if (COMPONENTS_MAP_REVERSE[dep]) {
-            modules.push(`echarts/lib/component/${COMPONENTS_MAP_REVERSE[dep]}`);
-        }
-        else if (CHARTS_GL_MAP_REVERSE[dep]) {
-            modules.push(`echarts-gl/lib/chart/${CHARTS_GL_MAP_REVERSE[dep]}`);
-        }
-        else if (COMPONENTS_GL_MAP_REVERSE[dep]) {
-            modules.push(`echarts-gl/lib/component/${COMPONENTS_GL_MAP_REVERSE[dep]}`);
-        }
-    });
+  const modules = [];
+  deps.forEach(function (dep) {
+    if (dep.endsWith('Renderer') && dep !== 'CanvasRenderer') {
+      modules.push(
+        `zrender/lib/${RENDERERS_MAP_REVERSE[dep]}/${RENDERERS_MAP_REVERSE[dep]}`
+      );
+    } else if (CHARTS_MAP_REVERSE[dep]) {
+      modules.push(`echarts/lib/chart/${CHARTS_MAP_REVERSE[dep]}`);
+    } else if (COMPONENTS_MAP_REVERSE[dep]) {
+      modules.push(`echarts/lib/component/${COMPONENTS_MAP_REVERSE[dep]}`);
+    } else if (CHARTS_GL_MAP_REVERSE[dep]) {
+      modules.push(`echarts-gl/lib/chart/${CHARTS_GL_MAP_REVERSE[dep]}`);
+    } else if (COMPONENTS_GL_MAP_REVERSE[dep]) {
+      modules.push(
+        `echarts-gl/lib/component/${COMPONENTS_GL_MAP_REVERSE[dep]}`
+      );
+    }
+  });
 
-    return isESM ? `import * as echarts from 'echarts/lib/echarts';
-${modules.map(mod => {
+  return isESM
+    ? `import * as echarts from 'echarts/lib/echarts';
+${modules
+  .map((mod) => {
     return `import '${mod}';`;
-}).join('\n')}
-` : `const echarts = require('echarts/lib/echarts');
-${modules.map(mod => {
-    return `require('${mod}');`;
-}).join('\n')}
+  })
+  .join('\n')}
 `
+    : `const echarts = require('echarts/lib/echarts');
+${modules
+  .map((mod) => {
+    return `require('${mod}');`;
+  })
+  .join('\n')}
+`;
 }
 
 function hasGLInDeps(deps) {
-    return !!deps.find(dep => !!(CHARTS_GL_MAP_REVERSE[dep] || COMPONENTS_GL_MAP_REVERSE[dep]));
+  return !!deps.find(
+    (dep) => !!(CHARTS_GL_MAP_REVERSE[dep] || COMPONENTS_GL_MAP_REVERSE[dep])
+  );
 }
 
 module.buildLegacyMinimalBundleCode = buildLegacyMinimalBundleCode;
 
 module.exports.buildExampleCode = function (
-    jsCode, deps, {
-        // If enable minimal import
-        minimal,
-        // If is ESM module or CommonJS module
-        // Force to be true in ts mode or minimal mode.
-        esm = true,
-        // If use legacy minimal import, like:
-        // import 'echarts/lib/chart/bar';
-        // Only available when minimal is true.
-        legacy,
-        // If is ts code
-        ts,
-        // Theme
-        theme,
-        ROOT_PATH,
-        // Other imports code code string
-        // For example
-        // `import 'echarts-liquidfill'`
-        extraImports
-    }
+  jsCode,
+  deps,
+  {
+    // If enable minimal import
+    minimal,
+    // If is ESM module or CommonJS module
+    // Force to be true in ts mode or minimal mode.
+    esm = true,
+    // If use legacy minimal import, like:
+    // import 'echarts/lib/chart/bar';
+    // Only available when minimal is true.
+    legacy,
+    // If is ts code
+    ts,
+    // Theme
+    theme,
+    ROOT_PATH,
+    // Other imports code code string
+    // For example
+    // `import 'echarts-liquidfill'`
+    extraImports
+  }
 ) {
-    // if (minimal && !legacy) {
-    //     // ESM must be used when use the new minimal import
-    //     esm = true;
-    // }
-
-    if (ts) {
-        esm = true;
-    }
-
-    if (minimal && !esm) {
-        // Only legacy mode can be used when use require in mimimal bundle.
-        legacy = true;
-    }
-
-
-    const hasECStat = jsCode.indexOf('ecStat') >= 0;
-    const usedRootPath = jsCode.indexOf('ROOT_PATH') >= 0;
-    const usedApp = jsCode.indexOf('app') >= 0;
-
-    const DEP_CODE = `
-${hasECStat ?
-    esm ? `import ecStat from 'echarts-stat';`
-        : `var ecStat = require('echarts-stat');`
+  // if (minimal && !legacy) {
+  //     // ESM must be used when use the new minimal import
+  //     esm = true;
+  // }
+
+  if (ts) {
+    esm = true;
+  }
+
+  if (minimal && !esm) {
+    // Only legacy mode can be used when use require in mimimal bundle.
+    legacy = true;
+  }
+
+  const hasECStat = jsCode.indexOf('ecStat') >= 0;
+  const usedRootPath = jsCode.indexOf('ROOT_PATH') >= 0;
+  const usedApp = jsCode.indexOf('app') >= 0;
+
+  const DEP_CODE = `
+${
+  hasECStat
+    ? esm
+      ? `import ecStat from 'echarts-stat';`
+      : `var ecStat = require('echarts-stat');`
     : ''
 }
 `;
-    const IMPORT_CODE = [
-        !minimal
-            ? esm
-                ? `import * as echarts from 'echarts';${hasGLInDeps(deps) ? `\nimport 'echarts-gl';` : ''}`
-                : `var echarts = require('echarts');${hasGLInDeps(deps) ? `\nrequire('echarts-gl');` : ''}`
-            : legacy
-                ? buildLegacyMinimalBundleCode(deps, esm)
-                : buildMinimalBundleCode(deps, ts),
-        (theme && theme !== 'dark')
-            ? esm
-                ? `import 'echarts/theme/${theme}'`
-                : `require('echarts/theme/${theme}')`
-            : '',
-        extraImports
-    ].filter(a => !!a).join('\n');
-
-    const ENV_CODE = [
-        usedRootPath ? `var ROOT_PATH = '${ROOT_PATH}';` : '',
-        usedApp ? `var app${ts ? ': any' : ''} = {};` : '',
-        ts && !minimal ? 'type ECOption = echarts.EChartsOption' : ''
-    ].filter(a => !!a).join('\n');
-
-    const PREPARE_CODE = [
-        IMPORT_CODE.trim(), DEP_CODE.trim(), ENV_CODE.trim()
-    ].filter(a => !!a).join('\n\n');
-
-    return `${PREPARE_CODE}
+  const IMPORT_CODE = [
+    !minimal
+      ? esm
+        ? `import * as echarts from 'echarts';${
+            hasGLInDeps(deps) ? `\nimport 'echarts-gl';` : ''
+          }`
+        : `var echarts = require('echarts');${
+            hasGLInDeps(deps) ? `\nrequire('echarts-gl');` : ''
+          }`
+      : legacy
+      ? buildLegacyMinimalBundleCode(deps, esm)
+      : buildMinimalBundleCode(deps, ts),
+    theme && theme !== 'dark'
+      ? esm
+        ? `import 'echarts/theme/${theme}'`
+        : `require('echarts/theme/${theme}')`
+      : '',
+    extraImports
+  ]
+    .filter((a) => !!a)
+    .join('\n');
+
+  const ENV_CODE = [
+    usedRootPath ? `var ROOT_PATH = '${ROOT_PATH}';` : '',
+    usedApp ? `var app${ts ? ': any' : ''} = {};` : '',
+    ts && !minimal ? 'type ECOption = echarts.EChartsOption' : ''
+  ]
+    .filter((a) => !!a)
+    .join('\n');
+
+  const PREPARE_CODE = [IMPORT_CODE.trim(), DEP_CODE.trim(), ENV_CODE.trim()]
+    .filter((a) => !!a)
+    .join('\n\n');
+
+  return `${PREPARE_CODE}
 
 var chartDom = document.getElementById('main')${ts ? '!' : ''};
 var myChart = echarts.init(chartDom${theme ? `, '${theme}'` : ''});
@@ -371,4 +402,4 @@ ${jsCode.trim()}
 
 option && myChart.setOption(option);
 `;
-}
\ No newline at end of file
+};
diff --git a/common/compareImage.js b/common/compareImage.js
index e0d3a93..1515933 100644
--- a/common/compareImage.js
+++ b/common/compareImage.js
@@ -3,45 +3,52 @@ const PNG = require('pngjs').PNG;
 const pixelmatch = require('pixelmatch');
 
 function readPNG(path) {
-    return new Promise(resolve => {
-        fs.createReadStream(path)
-            .pipe(new PNG())
-            .on('parsed', function () {
-                resolve({
-                    data: this.data,
-                    width: this.width,
-                    height: this.height
-                });
-            });
-    });
+  return new Promise((resolve) => {
+    fs.createReadStream(path)
+      .pipe(new PNG())
+      .on('parsed', function () {
+        resolve({
+          data: this.data,
+          width: this.width,
+          height: this.height
+        });
+      });
+  });
 }
 
-module.exports.compareImage = function (targetPath, sourcePath, threshold = 0.1) {
-    if (!fs.existsSync(targetPath)) {
-        return true;
-    }
+module.exports.compareImage = function (
+  targetPath,
+  sourcePath,
+  threshold = 0.1
+) {
+  if (!fs.existsSync(targetPath)) {
+    return true;
+  }
 
-    return Promise.all([
-        readPNG(targetPath),
-        readPNG(sourcePath)
-    ]).then(([expectedImg, actualImg]) => {
-        let width = expectedImg.width;
-        let height = expectedImg.height;
-        if (
-            (width !== actualImg.width)
-          || (height !== actualImg.height)
-        ) {
-            return {diffRatio: 1}
+  return Promise.all([readPNG(targetPath), readPNG(sourcePath)]).then(
+    ([expectedImg, actualImg]) => {
+      let width = expectedImg.width;
+      let height = expectedImg.height;
+      if (width !== actualImg.width || height !== actualImg.height) {
+        return { diffRatio: 1 };
+      }
+      const diffPNG = new PNG({ width, height });
+      let diffPixelsCount = pixelmatch(
+        expectedImg.data,
+        actualImg.data,
+        diffPNG.data,
+        width,
+        height,
+        {
+          threshold
         }
-        const diffPNG = new PNG({width, height});
-        let diffPixelsCount = pixelmatch(expectedImg.data, actualImg.data, diffPNG.data, width, height, {
-            threshold
-        });
-        let totalPixelsCount = width * height;
+      );
+      let totalPixelsCount = width * height;
 
-        return {
-            diffRatio: diffPixelsCount / totalPixelsCount,
-            diffPNG
-        };
-    });
-}
\ No newline at end of file
+      return {
+        diffRatio: diffPixelsCount / totalPixelsCount,
+        diffPNG
+      };
+    }
+  );
+};
diff --git a/common/task.js b/common/task.js
index f2e5f1c..4ad82ce 100644
--- a/common/task.js
+++ b/common/task.js
@@ -1,51 +1,49 @@
-function runTasks(
-    taskParamsLists, createTask, concurrency
-) {
-    concurrency = Math.min(taskParamsLists.length, concurrency);
-    return new Promise((resolve, reject) => {
-        let runningTaskCount = 0;
-        let cursor = 0;
-        let rets = [];
-
-        function finishTask(res, idx) {
-            rets[idx] = res;
-            processNext();
-        }
-
-        function failTask(e) {
-            console.error(e);
-            processNext();
-        }
-
-        function processNext() {
-            runningTaskCount--;
-            addTask();
-
-            if (runningTaskCount === 0) {
-                resolve(rets);
-            }
-        }
-
-        function addTask() {
-            const param = taskParamsLists[cursor];
-            if (param) {
-                const currentTaskIdx = cursor;
-                runningTaskCount++;
-                createTask(param)
-                    .then((res) => finishTask(res, currentTaskIdx))
-                    .catch(failTask);
-                cursor++;
-            }
-        }
-
-        for (let i = 0; i < concurrency; i++) {
-            addTask();
-        }
-
-        if (!runningTaskCount) {
-            resolve(rets);
-        }
-    });
+function runTasks(taskParamsLists, createTask, concurrency) {
+  concurrency = Math.min(taskParamsLists.length, concurrency);
+  return new Promise((resolve, reject) => {
+    let runningTaskCount = 0;
+    let cursor = 0;
+    let rets = [];
+
+    function finishTask(res, idx) {
+      rets[idx] = res;
+      processNext();
+    }
+
+    function failTask(e) {
+      console.error(e);
+      processNext();
+    }
+
+    function processNext() {
+      runningTaskCount--;
+      addTask();
+
+      if (runningTaskCount === 0) {
+        resolve(rets);
+      }
+    }
+
+    function addTask() {
+      const param = taskParamsLists[cursor];
+      if (param) {
+        const currentTaskIdx = cursor;
+        runningTaskCount++;
+        createTask(param)
+          .then((res) => finishTask(res, currentTaskIdx))
+          .catch(failTask);
+        cursor++;
+      }
+    }
+
+    for (let i = 0; i < concurrency; i++) {
+      addTask();
+    }
+
+    if (!runningTaskCount) {
+      resolve(rets);
+    }
+  });
 }
 
-module.exports.runTasks = runTasks;
\ No newline at end of file
+module.exports.runTasks = runTasks;
diff --git a/config/common.js b/config/common.js
index e4d473f..f053ebf 100644
--- a/config/common.js
+++ b/config/common.js
@@ -1,5 +1 @@
-
-module.exports = {
-};
-
-
+module.exports = {};
diff --git a/config/env.asf.js b/config/env.asf.js
index 8c08547..16d9a2e 100644
--- a/config/env.asf.js
+++ b/config/env.asf.js
@@ -2,7 +2,7 @@ const path = require('path');
 const config = require('./common');
 
 Object.assign(config, {
-    releaseDestDir: path.resolve(__dirname, '../../echarts-website/examples')
+  releaseDestDir: path.resolve(__dirname, '../../echarts-website/examples')
 });
 
 module.exports = config;
diff --git a/config/env.dev.js b/config/env.dev.js
index 8c08547..16d9a2e 100644
--- a/config/env.dev.js
+++ b/config/env.dev.js
@@ -2,7 +2,7 @@ const path = require('path');
 const config = require('./common');
 
 Object.assign(config, {
-    releaseDestDir: path.resolve(__dirname, '../../echarts-website/examples')
+  releaseDestDir: path.resolve(__dirname, '../../echarts-website/examples')
 });
 
 module.exports = config;
diff --git a/config/env.localsite.js b/config/env.localsite.js
index 84106f2..b8fdaaf 100644
--- a/config/env.localsite.js
+++ b/config/env.localsite.js
@@ -2,7 +2,7 @@ const path = require('path');
 const config = require('./common');
 
 Object.assign(config, {
-    releaseDestDir: path.resolve(__dirname, '../../echarts-website/next/examples')
+  releaseDestDir: path.resolve(__dirname, '../../echarts-website/next/examples')
 });
 
 module.exports = config;
diff --git a/e2e/cases/README.md b/e2e/cases/README.md
index 7d12477..57c6a61 100644
--- a/e2e/cases/README.md
+++ b/e2e/cases/README.md
@@ -1,3 +1,3 @@
 # Handwritten Cases
 
-Mostly for testing extensions.
\ No newline at end of file
+Mostly for testing extensions.
diff --git a/e2e/cases/liquidfill.js b/e2e/cases/liquidfill.js
index c219859..e257bb4 100644
--- a/e2e/cases/liquidfill.js
+++ b/e2e/cases/liquidfill.js
@@ -2,9 +2,11 @@
 extension: echarts-liquidfill
 */
 option = {
-    series: [{
-        type: 'liquidFill',
-        data: [0.6],
-        radius: '70%'
-    }]
-};
\ No newline at end of file
+  series: [
+    {
+      type: 'liquidFill',
+      data: [0.6],
+      radius: '70%'
+    }
+  ]
+};
diff --git a/e2e/cases/wordcloud.js b/e2e/cases/wordcloud.js
index ee14f29..5c01bb8 100644
--- a/e2e/cases/wordcloud.js
+++ b/e2e/cases/wordcloud.js
@@ -2,120 +2,126 @@
 extension: echarts-wordcloud
 */
 option = {
-    tooltip: {},
-    series: [ {
-        type: 'wordCloud',
-        gridSize: 2,
-        sizeRange: [12, 50],
-        rotationRange: [-90, 90],
-        shape: 'pentagon',
-        width: 600,
-        height: 400,
-        drawOutOfBound: true,
+  tooltip: {},
+  series: [
+    {
+      type: 'wordCloud',
+      gridSize: 2,
+      sizeRange: [12, 50],
+      rotationRange: [-90, 90],
+      shape: 'pentagon',
+      width: 600,
+      height: 400,
+      drawOutOfBound: true,
+      textStyle: {
+        color: function () {
+          return (
+            'rgb(' +
+            [
+              Math.round(Math.random() * 160),
+              Math.round(Math.random() * 160),
+              Math.round(Math.random() * 160)
+            ].join(',') +
+            ')'
+          );
+        }
+      },
+      emphasis: {
         textStyle: {
-            color: function () {
-                return 'rgb(' + [
-                    Math.round(Math.random() * 160),
-                    Math.round(Math.random() * 160),
-                    Math.round(Math.random() * 160)
-                ].join(',') + ')';
-            }
-        },
-        emphasis: {
+          shadowBlur: 10,
+          shadowColor: '#333'
+        }
+      },
+      data: [
+        {
+          name: 'Sam S Club',
+          value: 10000,
+          textStyle: {
+            color: 'black'
+          },
+          emphasis: {
             textStyle: {
-                shadowBlur: 10,
-                shadowColor: '#333'
+              color: 'red'
             }
+          }
         },
-        data: [
-            {
-                name: 'Sam S Club',
-                value: 10000,
-                textStyle: {
-                    color: 'black'
-                },
-                emphasis: {
-                    textStyle: {
-                        color: 'red'
-                    }
-                }
-            },
-            {
-                name: 'Macys',
-                value: 6181
-            },
-            {
-                name: 'Amy Schumer',
-                value: 4386
-            },
-            {
-                name: 'Jurassic World',
-                value: 4055
-            },
-            {
-                name: 'Charter Communications',
-                value: 2467
-            },
-            {
-                name: 'Chick Fil A',
-                value: 2244
-            },
-            {
-                name: 'Planet Fitness',
-                value: 1898
-            },
-            {
-                name: 'Pitch Perfect',
-                value: 1484
-            },
-            {
-                name: 'Express',
-                value: 1112
-            },
-            {
-                name: 'Home',
-                value: 965
-            },
-            {
-                name: 'Johnny Depp',
-                value: 847
-            },
-            {
-                name: 'Lena Dunham',
-                value: 582
-            },
-            {
-                name: 'Lewis Hamilton',
-                value: 555
-            },
-            {
-                name: 'KXAN',
-                value: 550
-            },
-            {
-                name: 'Mary Ellen Mark',
-                value: 462
-            },
-            {
-                name: 'Farrah Abraham',
-                value: 366
-            },
-            {
-                name: 'Rita Ora',
-                value: 360
-            },
-            {
-                name: 'Serena Williams',
-                value: 282
-            },
-            {
-                name: 'NCAA baseball tournament',
-                value: 273
-            },
-            {
-                name: 'Point Break',
-                value: 265
-            }
-        ]
-    } ]
+        {
+          name: 'Macys',
+          value: 6181
+        },
+        {
+          name: 'Amy Schumer',
+          value: 4386
+        },
+        {
+          name: 'Jurassic World',
+          value: 4055
+        },
+        {
+          name: 'Charter Communications',
+          value: 2467
+        },
+        {
+          name: 'Chick Fil A',
+          value: 2244
+        },
+        {
+          name: 'Planet Fitness',
+          value: 1898
+        },
+        {
+          name: 'Pitch Perfect',
+          value: 1484
+        },
+        {
+          name: 'Express',
+          value: 1112
+        },
+        {
+          name: 'Home',
+          value: 965
+        },
+        {
+          name: 'Johnny Depp',
+          value: 847
+        },
+        {
+          name: 'Lena Dunham',
+          value: 582
+        },
+        {
+          name: 'Lewis Hamilton',
+          value: 555
+        },
+        {
+          name: 'KXAN',
+          value: 550
+        },
+        {
+          name: 'Mary Ellen Mark',
+          value: 462
+        },
+        {
+          name: 'Farrah Abraham',
+          value: 366
+        },
+        {
+          name: 'Rita Ora',
+          value: 360
+        },
+        {
+          name: 'Serena Williams',
+          value: 282
+        },
+        {
+          name: 'NCAA baseball tournament',
+          value: 273
+        },
+        {
+          name: 'Point Break',
+          value: 265
+        }
+      ]
+    }
+  ]
 };
diff --git a/e2e/config.js b/e2e/config.js
index d377f17..61bbff2 100644
--- a/e2e/config.js
+++ b/e2e/config.js
@@ -1,32 +1,32 @@
 const nodePath = require('path');
 
 module.exports = {
-    packages: [
-        // Handwritten topological sort by the rule of dependency.
-        {
-            name: 'zrender',    // package name
-            dir: nodePath.resolve(__dirname, '../../zrender'),
-            git: 'ecomfe/zrender#release'
-        },
-        {
-            name: 'echarts',
-            dir: nodePath.resolve(__dirname, '../../echarts'),
-            git: 'apache/echarts#release'
-        },
-        {
-            name: 'echarts-gl',
-            dir: nodePath.resolve(__dirname, '../../echarts-gl'),
-            git: 'ecomfe/echarts-gl#master'
-        },
-        {
-            name: 'echarts-wordcloud',
-            dir: nodePath.resolve(__dirname, '../../echarts-wordcloud'),
-            git: 'ecomfe/echarts-wordcloud#master'
-        },
-        {
-            name: 'echarts-liquidfill',
-            dir: nodePath.resolve(__dirname, '../../echarts-liquidfill'),
-            git: 'ecomfe/echarts-liquidfill#master'
-        }
-    ]
-}
\ No newline at end of file
+  packages: [
+    // Handwritten topological sort by the rule of dependency.
+    {
+      name: 'zrender', // package name
+      dir: nodePath.resolve(__dirname, '../../zrender'),
+      git: 'ecomfe/zrender#release'
+    },
+    {
+      name: 'echarts',
+      dir: nodePath.resolve(__dirname, '../../echarts'),
+      git: 'apache/echarts#release'
+    },
+    {
+      name: 'echarts-gl',
+      dir: nodePath.resolve(__dirname, '../../echarts-gl'),
+      git: 'ecomfe/echarts-gl#master'
+    },
+    {
+      name: 'echarts-wordcloud',
+      dir: nodePath.resolve(__dirname, '../../echarts-wordcloud'),
+      git: 'ecomfe/echarts-wordcloud#master'
+    },
+    {
+      name: 'echarts-liquidfill',
+      dir: nodePath.resolve(__dirname, '../../echarts-liquidfill'),
+      git: 'ecomfe/echarts-liquidfill#master'
+    }
+  ]
+};
diff --git a/e2e/main.js b/e2e/main.js
index c086f26..acc8517 100644
--- a/e2e/main.js
+++ b/e2e/main.js
@@ -2,7 +2,7 @@
 
 const fs = require('fs');
 const globby = require('globby');
-const {buildExampleCode, collectDeps} = require('../common/buildCode');
+const { buildExampleCode, collectDeps } = require('../common/buildCode');
 const nodePath = require('path');
 const { runTasks } = require('../common/task');
 const fse = require('fs-extra');
@@ -11,37 +11,37 @@ const ts = require('typescript');
 const chalk = require('chalk');
 const nStatic = require('node-static');
 const webpack = require('webpack');
-const {RawSource} = require('webpack-sources');
+const { RawSource } = require('webpack-sources');
 const argparse = require('argparse');
 const esbuild = require('esbuild');
 const puppeteer = require('puppeteer');
 const config = require('./config');
-const {compareImage} = require('../common/compareImage');
+const { compareImage } = require('../common/compareImage');
 const shell = require('shelljs');
 const downloadGit = require('download-git-repo');
-const {promisify} = require('util');
+const { promisify } = require('util');
 const matter = require('gray-matter');
 const minimatch = require('minimatch');
 
 const parser = new argparse.ArgumentParser({
-    addHelp: true
+  addHelp: true
 });
 parser.addArgument(['--bundler'], {
-    help: 'Bundler, can be webpack or esbuild'
+  help: 'Bundler, can be webpack or esbuild'
 });
 parser.addArgument(['-m', '--minify'], {
-    action: 'storeTrue',
-    help: 'If minify'
+  action: 'storeTrue',
+  help: 'If minify'
 });
 parser.addArgument(['--local'], {
-    action: 'storeTrue',
-    help: `If use local repos. If so, don't forget to update the location of local repo in config.js.`
+  action: 'storeTrue',
+  help: `If use local repos. If so, don't forget to update the location of local repo in config.js.`
 });
 parser.addArgument(['--skip'], {
-    help: 'If skip some stages to speed up the test. Can be npm,bundle,render,compare'
+  help: 'If skip some stages to speed up the test. Can be npm,bundle,render,compare'
 });
 parser.addArgument(['-t', '--tests'], {
-    help: 'If use pattern to specify which tests to run'
+  help: 'If use pattern to specify which tests to run'
 });
 const args = parser.parseArgs();
 
@@ -63,7 +63,7 @@ const USE_WEBPACK = !(args.bundler === 'esbuild');
 
 let testsPattern = args.tests;
 if (testsPattern) {
-    testsPattern = testsPattern.split(',');
+  testsPattern = testsPattern.split(',');
 }
 
 // Create a server
@@ -89,21 +89,23 @@ echarts.registerPreprocessor(function (option) {
         });
     }
 });
-`
+`;
 
 function buildPrepareCode(isESM, lang) {
-    return `
+  return `
 // @ts-ignore
-${isESM
+${
+  isESM
     ? `import _seedrandom from 'seedrandom';`
     : `const _seedrandom = require('seedrandom');`
 }
 
 // Check if i18n will break the minimal imports.
-${lang
+${
+  lang
     ? isESM
-        ? `import 'echarts/i18n/${lang}';`
-        : `require('echarts/i18n/${lang}');`
+      ? `import 'echarts/i18n/${lang}';`
+      : `require('echarts/i18n/${lang}');`
     : ''
 }
 // @ts-ignore
@@ -118,657 +120,767 @@ ${TEMPLATE_CODE}
 }
 
 async function prepare() {
-    fse.removeSync(TMP_DIR);
-    fse.removeSync(RUN_CODE_DIR);
-    fse.removeSync(BUNDLE_DIR);
-    fse.removeSync(SCREENSHOTS_DIR);
+  fse.removeSync(TMP_DIR);
+  fse.removeSync(RUN_CODE_DIR);
+  fse.removeSync(BUNDLE_DIR);
+  fse.removeSync(SCREENSHOTS_DIR);
 
-    fse.removeSync(REPO_DIR);
-    fse.removeSync(PACKAGE_DIR);
+  fse.removeSync(REPO_DIR);
+  fse.removeSync(PACKAGE_DIR);
 
-    fse.ensureDirSync(TMP_DIR);
-    fse.ensureDirSync(RUN_CODE_DIR);
-    fse.ensureDirSync(BUNDLE_DIR);
-    fse.ensureDirSync(SCREENSHOTS_DIR);
+  fse.ensureDirSync(TMP_DIR);
+  fse.ensureDirSync(RUN_CODE_DIR);
+  fse.ensureDirSync(BUNDLE_DIR);
+  fse.ensureDirSync(SCREENSHOTS_DIR);
 
-    fse.ensureDirSync(REPO_DIR);
-    fse.ensureDirSync(PACKAGE_DIR);
+  fse.ensureDirSync(REPO_DIR);
+  fse.ensureDirSync(PACKAGE_DIR);
 }
 
 async function downloadPackages(config) {
-    for (let pkg of config.packages) {
-        const pkgDownloadPath = nodePath.join(REPO_DIR, pkg.name);
-        console.log(chalk.gray(`Downloading ${pkg.git}`))
-        await promisify(downloadGit)(pkg.git, pkgDownloadPath);
-        // Override the path
-        pkg.dir = pkgDownloadPath;
-    }
+  for (let pkg of config.packages) {
+    const pkgDownloadPath = nodePath.join(REPO_DIR, pkg.name);
+    console.log(chalk.gray(`Downloading ${pkg.git}`));
+    await promisify(downloadGit)(pkg.git, pkgDownloadPath);
+    // Override the path
+    pkg.dir = pkgDownloadPath;
+  }
 }
 
 async function installPackages(config) {
-
-    const publishedPackages = {};
-
-    function checkFolder(pkg) {
-        const dir = pkg.dir;
-        if (!fs.existsSync(dir)) {
-            console.warn(chalk.yellow(`${dir} not exists. Please update it in e2e/config.js.`));
-            return false;
-        }
-        if (!nodePath.isAbsolute(dir)) {
-            console.warn(chalk.yellow(`${dir} is not an absolute path. Please update it in e2e/config.js.`));
-            return false;
-        }
-        return true;
+  const publishedPackages = {};
+
+  function checkFolder(pkg) {
+    const dir = pkg.dir;
+    if (!fs.existsSync(dir)) {
+      console.warn(
+        chalk.yellow(`${dir} not exists. Please update it in e2e/config.js.`)
+      );
+      return false;
     }
+    if (!nodePath.isAbsolute(dir)) {
+      console.warn(
+        chalk.yellow(
+          `${dir} is not an absolute path. Please update it in e2e/config.js.`
+        )
+      );
+      return false;
+    }
+    return true;
+  }
 
-    function publishPackage(pkg) {
-        console.log(chalk.gray(`Publishing ${pkg.dir}`))
-
-        shell.cd(pkg.dir);
-
-        const packageJson = JSON.parse(fs.readFileSync(nodePath.join(pkg.dir, 'package.json')));
-        const tgzFileName = `${packageJson.name}-${packageJson.version}.tgz`;
-        const targetTgzFilePath = nodePath.join(PACKAGE_DIR, tgzFileName);
-
-        if (packageJson.dependencies) {
-            for (let depPkgName in packageJson.dependencies) {
-                const depPkg = config.packages.find(a => a.name === depPkgName);
-                if (depPkg && !publishedPackages[depPkgName]) {
-                    publishPackage(depPkg);
-                    // Come back.
-                    shell.cd(pkg.dir);
-                }
+  function publishPackage(pkg) {
+    console.log(chalk.gray(`Publishing ${pkg.dir}`));
 
-                shell.exec(`npm install`);
+    shell.cd(pkg.dir);
 
-                if (depPkg) {
-                    console.log(chalk.gray(`Installing dependency ${depPkgName} from "${publishedPackages[depPkgName]}" ...`));
-                    shell.exec(`npm install ${publishedPackages[depPkgName]} --no-save`);
-                    console.log(chalk.gray(`Install dependency ${depPkgName} done.`));
-                }
-            }
+    const packageJson = JSON.parse(
+      fs.readFileSync(nodePath.join(pkg.dir, 'package.json'))
+    );
+    const tgzFileName = `${packageJson.name}-${packageJson.version}.tgz`;
+    const targetTgzFilePath = nodePath.join(PACKAGE_DIR, tgzFileName);
+
+    if (packageJson.dependencies) {
+      for (let depPkgName in packageJson.dependencies) {
+        const depPkg = config.packages.find((a) => a.name === depPkgName);
+        if (depPkg && !publishedPackages[depPkgName]) {
+          publishPackage(depPkg);
+          // Come back.
+          shell.cd(pkg.dir);
         }
 
-        shell.exec(`npm pack`);
-        fs.renameSync(nodePath.join(pkg.dir, tgzFileName), targetTgzFilePath);
-        publishedPackages[packageJson.name] = targetTgzFilePath;
-    }
+        shell.exec(`npm install`);
 
-    for (let pkg of config.packages) {
-        if (!checkFolder(pkg)) {
-            return;
+        if (depPkg) {
+          console.log(
+            chalk.gray(
+              `Installing dependency ${depPkgName} from "${publishedPackages[depPkgName]}" ...`
+            )
+          );
+          shell.exec(`npm install ${publishedPackages[depPkgName]} --no-save`);
+          console.log(chalk.gray(`Install dependency ${depPkgName} done.`));
         }
-
-        publishPackage(pkg);
-    };
-
-    shell.cd(__dirname);
-    for (let pkg of config.packages) {
-        console.log(chalk.gray(`Installing ${pkg.name} from "${publishedPackages[pkg.name]}" ...`));
-        shell.exec(`npm install ${publishedPackages[pkg.name]} --no-save`);
-        console.log(chalk.gray(`Install ${pkg.name} done.`));
-    }
-
-    // Come back.
-    shell.cd(process.cwd());
-}
-
-async function buildRunCode() {
-    const files = await globby([
-        `${EXAMPLE_DIR}/data/option/*.json`,
-        `${EXAMPLE_DIR}/data-gl/option/*.json`
-    ]);
-
-    if (!files.length) {
-        throw new Error('You need to run `node tool/build-example.js` before run this test.');
+      }
     }
 
-    async function addTestCase(testName, testCode, deps, checkTs, extraImports, extraRequire) {
-        const ROOT_PATH = `${baseUrl}/public`;
+    shell.exec(`npm pack`);
+    fs.renameSync(nodePath.join(pkg.dir, tgzFileName), targetTgzFilePath);
+    publishedPackages[packageJson.name] = targetTgzFilePath;
+  }
 
-        const fullCode = buildExampleCode(buildPrepareCode(true) + testCode, deps, {
-            minimal: false,
-            ts: checkTs,
-            // Check if theme will break the minimal imports.
-            theme: TEST_THEME,
-            ROOT_PATH,
-            extraImports
-        });
-        const minimalCode = buildExampleCode(buildPrepareCode(true) + testCode, deps, {
-            minimal: true,
-            ts: checkTs,
-            theme: TEST_THEME,
-            ROOT_PATH,
-            extraImports
-        });
-        const legacyCode = buildExampleCode(buildPrepareCode(false) + testCode, deps, {
-            minimal: true,
-            esm: false,
-            ts: false,
-            theme: TEST_THEME,
-            ROOT_PATH,
-            extraImports: extraRequire
-        });
-
-        await fse.writeFile(
-            nodePath.join(RUN_CODE_DIR, testName + (checkTs ? '.ts' : '.js')),
-            prettier.format(fullCode, {
-                singleQuote: true,
-                parser: checkTs ? 'typescript' : 'babel'
-            }), 'utf-8'
-        );
-        await fse.writeFile(
-            nodePath.join(RUN_CODE_DIR, testName + `.${MINIMAL_POSTFIX}.${checkTs ? 'ts' : 'js'}`),
-            prettier.format(minimalCode, {
-                singleQuote: true,
-                parser: checkTs ? 'typescript' : 'babel'
-            }), 'utf-8'
-        );
-        await fse.writeFile(
-            nodePath.join(RUN_CODE_DIR, testName + `.${MINIMAL_LEGACY_POSTFIX}.js`),
-            prettier.format(legacyCode, {
-                singleQuote: true,
-                parser: 'babel'
-            }), 'utf-8'
-        );
-        console.log(
-            chalk.green('Generated: ', testName)
-        );
+  for (let pkg of config.packages) {
+    if (!checkFolder(pkg)) {
+      return;
     }
 
-    const builtinTestCases = await runTasks(files, async (fileName) => {
-        const isGL = fileName.startsWith(`${EXAMPLE_DIR}/data-gl`);
-        const testName = nodePath.basename(fileName, '.json');
-
-        if (testsPattern && !testsPattern.some(pattern => minimatch(testName, pattern))) {
-            return;
-        }
+    publishPackage(pkg);
+  }
 
-        const optionCode = await fse.readFile(fileName, 'utf-8');
-        let option;
-        try {
-            option = JSON.parse(optionCode);
-        }
-        catch (err) {
-            console.error(`Parse JSON error: fileName: ${fileName} | fileContent: ${optionCode}`);
-            throw err;
-        }
-        const testCode = await fse.readFile(nodePath.join(
-            EXAMPLE_DIR, isGL ? 'data-gl' : 'data', testName + '.js'
-        ), 'utf-8');
-
-        // TODO Ignore case with extension.
-
-        const deps = collectDeps(option).concat([
-            // TODO SVG
-            'CanvasRenderer'
-        ]);
-
-        if (
-            !(testName === 'map-HK' || testName === 'map-usa')  // Only test these two map examples
-            && (deps.includes('MapChart')
-                || deps.includes('GeoComponent')
-                || option.bmap)
-        ) {
-            console.warn(chalk.yellow(`Ignored map tests ${testName}`));
-            return;
-        }
+  shell.cd(__dirname);
+  for (let pkg of config.packages) {
+    console.log(
+      chalk.gray(
+        `Installing ${pkg.name} from "${publishedPackages[pkg.name]}" ...`
+      )
+    );
+    shell.exec(`npm install ${publishedPackages[pkg.name]} --no-save`);
+    console.log(chalk.gray(`Install ${pkg.name} done.`));
+  }
 
-        // TODO: Don't support TypeScript in GL
-        await addTestCase(testName, testCode, deps, !isGL);
+  // Come back.
+  shell.cd(process.cwd());
+}
 
-        return testName;
-    }, 20);
-    const extensionTestCases = await runTasks(await globby(__dirname + '/cases/*.js'), async (fileName) => {
-        const testName = nodePath.basename(fileName, '.js');
-        if (testsPattern && !testsPattern.some(pattern => minimatch(testName, pattern))) {
-            return;
-        }
+async function buildRunCode() {
+  const files = await globby([
+    `${EXAMPLE_DIR}/data/option/*.json`,
+    `${EXAMPLE_DIR}/data-gl/option/*.json`
+  ]);
+
+  if (!files.length) {
+    throw new Error(
+      'You need to run `node tool/build-example.js` before run this test.'
+    );
+  }
+
+  async function addTestCase(
+    testName,
+    testCode,
+    deps,
+    checkTs,
+    extraImports,
+    extraRequire
+  ) {
+    const ROOT_PATH = `${baseUrl}/public`;
+
+    const fullCode = buildExampleCode(buildPrepareCode(true) + testCode, deps, {
+      minimal: false,
+      ts: checkTs,
+      // Check if theme will break the minimal imports.
+      theme: TEST_THEME,
+      ROOT_PATH,
+      extraImports
+    });
+    const minimalCode = buildExampleCode(
+      buildPrepareCode(true) + testCode,
+      deps,
+      {
+        minimal: true,
+        ts: checkTs,
+        theme: TEST_THEME,
+        ROOT_PATH,
+        extraImports
+      }
+    );
+    const legacyCode = buildExampleCode(
+      buildPrepareCode(false) + testCode,
+      deps,
+      {
+        minimal: true,
+        esm: false,
+        ts: false,
+        theme: TEST_THEME,
+        ROOT_PATH,
+        extraImports: extraRequire
+      }
+    );
 
-        const testCode = await fse.readFile(fileName, 'utf-8');
-        let importsCode = '';
-        let requireCode = '';
-        try {
-            const fmResult = matter(testCode, {
-                delimiters: ['/*', '*/']
-            });
-            const extension = fmResult.data.extension;
-            if (extension) {
-                importsCode = `import '${extension}';`;
-                requireCode = `require('${extension}');`;
-            }
-        }
-        catch (e)  {
+    await fse.writeFile(
+      nodePath.join(RUN_CODE_DIR, testName + (checkTs ? '.ts' : '.js')),
+      prettier.format(fullCode, {
+        singleQuote: true,
+        parser: checkTs ? 'typescript' : 'babel'
+      }),
+      'utf-8'
+    );
+    await fse.writeFile(
+      nodePath.join(
+        RUN_CODE_DIR,
+        testName + `.${MINIMAL_POSTFIX}.${checkTs ? 'ts' : 'js'}`
+      ),
+      prettier.format(minimalCode, {
+        singleQuote: true,
+        parser: checkTs ? 'typescript' : 'babel'
+      }),
+      'utf-8'
+    );
+    await fse.writeFile(
+      nodePath.join(RUN_CODE_DIR, testName + `.${MINIMAL_LEGACY_POSTFIX}.js`),
+      prettier.format(legacyCode, {
+        singleQuote: true,
+        parser: 'babel'
+      }),
+      'utf-8'
+    );
+    console.log(chalk.green('Generated: ', testName));
+  }
+
+  const builtinTestCases = await runTasks(
+    files,
+    async (fileName) => {
+      const isGL = fileName.startsWith(`${EXAMPLE_DIR}/data-gl`);
+      const testName = nodePath.basename(fileName, '.json');
+
+      if (
+        testsPattern &&
+        !testsPattern.some((pattern) => minimatch(testName, pattern))
+      ) {
+        return;
+      }
+
+      const optionCode = await fse.readFile(fileName, 'utf-8');
+      let option;
+      try {
+        option = JSON.parse(optionCode);
+      } catch (err) {
+        console.error(
+          `Parse JSON error: fileName: ${fileName} | fileContent: ${optionCode}`
+        );
+        throw err;
+      }
+      const testCode = await fse.readFile(
+        nodePath.join(EXAMPLE_DIR, isGL ? 'data-gl' : 'data', testName + '.js'),
+        'utf-8'
+      );
+
+      // TODO Ignore case with extension.
+
+      const deps = collectDeps(option).concat([
+        // TODO SVG
+        'CanvasRenderer'
+      ]);
+
+      if (
+        !(testName === 'map-HK' || testName === 'map-usa') && // Only test these two map examples
+        (deps.includes('MapChart') ||
+          deps.includes('GeoComponent') ||
+          option.bmap)
+      ) {
+        console.warn(chalk.yellow(`Ignored map tests ${testName}`));
+        return;
+      }
+
+      // TODO: Don't support TypeScript in GL
+      await addTestCase(testName, testCode, deps, !isGL);
+
+      return testName;
+    },
+    20
+  );
+  const extensionTestCases = await runTasks(
+    await globby(__dirname + '/cases/*.js'),
+    async (fileName) => {
+      const testName = nodePath.basename(fileName, '.js');
+      if (
+        testsPattern &&
+        !testsPattern.some((pattern) => minimatch(testName, pattern))
+      ) {
+        return;
+      }
+
+      const testCode = await fse.readFile(fileName, 'utf-8');
+      let importsCode = '';
+      let requireCode = '';
+      try {
+        const fmResult = matter(testCode, {
+          delimiters: ['/*', '*/']
+        });
+        const extension = fmResult.data.extension;
+        if (extension) {
+          importsCode = `import '${extension}';`;
+          requireCode = `require('${extension}');`;
         }
-        await addTestCase(testName, testCode, [], false, importsCode, requireCode);
-
-        return testName;
-    }, 20);
-
-    return builtinTestCases.concat(extensionTestCases).filter(a => !!a);
+      } catch (e) {}
+      await addTestCase(
+        testName,
+        testCode,
+        [],
+        false,
+        importsCode,
+        requireCode
+      );
+
+      return testName;
+    },
+    20
+  );
+
+  return builtinTestCases.concat(extensionTestCases).filter((a) => !!a);
 }
 
 async function compileTs(tsTestFiles, result) {
-    const config = JSON.parse(fs.readFileSync(nodePath.join(__dirname, 'tsconfig.json'), 'utf-8'));
-
-    const compilerOptions = {
-        ...config.compilerOptions
-    };
-
-    const {options, errors} = ts.convertCompilerOptionsFromJson(compilerOptions, nodePath.resolve(__dirname));
-
-    if (errors.length) {
-        let errMsg = 'tsconfig parse failed: '
-            + errors.map(error => error.messageText).join('. ')
-            + '\n compilerOptions: \n' + JSON.stringify(config.compilerOptions, null, 4);
-        assert(false, errMsg);
-    }
-
-    // Generate this config file for checking the source code in vscode.
-    fs.writeFileSync(nodePath.join(RUN_CODE_DIR, 'tsconfig.json'), JSON.stringify({
+  const config = JSON.parse(
+    fs.readFileSync(nodePath.join(__dirname, 'tsconfig.json'), 'utf-8')
+  );
+
+  const compilerOptions = {
+    ...config.compilerOptions
+  };
+
+  const { options, errors } = ts.convertCompilerOptionsFromJson(
+    compilerOptions,
+    nodePath.resolve(__dirname)
+  );
+
+  if (errors.length) {
+    let errMsg =
+      'tsconfig parse failed: ' +
+      errors.map((error) => error.messageText).join('. ') +
+      '\n compilerOptions: \n' +
+      JSON.stringify(config.compilerOptions, null, 4);
+    assert(false, errMsg);
+  }
+
+  // Generate this config file for checking the source code in vscode.
+  fs.writeFileSync(
+    nodePath.join(RUN_CODE_DIR, 'tsconfig.json'),
+    JSON.stringify(
+      {
         compilerOptions
-    }, null, 2), 'utf-8');
-
-    // See: https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API
-    let program = ts.createProgram(tsTestFiles, options);
-    let emitResult = program.emit();
-
-    let allDiagnostics = ts
-        .getPreEmitDiagnostics(program)
-        .concat(emitResult.diagnostics);
-
-    allDiagnostics.forEach(diagnostic => {
-        if (diagnostic.file) {
-            let {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
-            let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
-
-            const compilerError = {
-                location: [line + 1, character + 1],
-                message
-            };
-            if (diagnostic.file.fileName.endsWith(`${MINIMAL_POSTFIX}.ts`)) {
-                const basename = nodePath.basename(diagnostic.file.fileName, `.${MINIMAL_POSTFIX}.ts`);
-                if (!result[basename]) {
-                    throw new Error(`${basename} does not exists in result.`);
-                }
-                result[basename].compileErrors.minimal.push(compilerError);
-            }
-            else {
-                const basename = nodePath.basename(diagnostic.file.fileName, `.ts`);
-                if (!result[basename]) {
-                    throw new Error(`${basename} does not exists in result.`);
-                }
-                result[basename].compileErrors.full.push(compilerError);
-            }
-            // console.log(chalk.red(`${diagnostic.file.fileName} (${line + 1},${character + 1})`));
-            // console.log(chalk.gray(message));
+      },
+      null,
+      2
+    ),
+    'utf-8'
+  );
+
+  // See: https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API
+  let program = ts.createProgram(tsTestFiles, options);
+  let emitResult = program.emit();
+
+  let allDiagnostics = ts
+    .getPreEmitDiagnostics(program)
+    .concat(emitResult.diagnostics);
+
+  allDiagnostics.forEach((diagnostic) => {
+    if (diagnostic.file) {
+      let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(
+        diagnostic.start
+      );
+      let message = ts.flattenDiagnosticMessageText(
+        diagnostic.messageText,
+        '\n'
+      );
+
+      const compilerError = {
+        location: [line + 1, character + 1],
+        message
+      };
+      if (diagnostic.file.fileName.endsWith(`${MINIMAL_POSTFIX}.ts`)) {
+        const basename = nodePath.basename(
+          diagnostic.file.fileName,
+          `.${MINIMAL_POSTFIX}.ts`
+        );
+        if (!result[basename]) {
+          throw new Error(`${basename} does not exists in result.`);
         }
-        else {
-            console.log(chalk.red(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')));
+        result[basename].compileErrors.minimal.push(compilerError);
+      } else {
+        const basename = nodePath.basename(diagnostic.file.fileName, `.ts`);
+        if (!result[basename]) {
+          throw new Error(`${basename} does not exists in result.`);
         }
-    });
-    // assert(!emitResult.emitSkipped, 'ts compile failed.');
+        result[basename].compileErrors.full.push(compilerError);
+      }
+      // console.log(chalk.red(`${diagnostic.file.fileName} (${line + 1},${character + 1})`));
+      // console.log(chalk.gray(message));
+    } else {
+      console.log(
+        chalk.red(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'))
+      );
+    }
+  });
+  // assert(!emitResult.emitSkipped, 'ts compile failed.');
 }
 
 async function webpackBundle(esbuildService, entry, result) {
-    return new Promise((resolve) => {
-        webpack({
-            entry,
-            output: {
-                path: BUNDLE_DIR,
-                filename: '[name].js'
-            },
-            // Use esbuild as minify, terser is tooooooo slow for so much tests.
-            optimization: {
-                minimizer: MINIFY_BUNDLE ? [{
-                    apply(compiler) {
-                        compiler.hooks.compilation.tap(
-                            'ESBuild Minify',
-                            (compilation) => {
-                                compilation.hooks.optimizeChunkAssets.tapPromise(
-                                    'ESBuild Minify',
-                                    async (chunks) => {
-                                        for (const chunk of chunks) {
-                                            for (const file of chunk.files) {
-                                                const asset = compilation.assets[file];
-                                                const { source } = asset.sourceAndMap();
-                                                const result = await esbuildService.transform(source, {
-                                                    minify: true,
-                                                    sourcemap: false
-                                                });
-                                                compilation.updateAsset(file, () => {
-                                                    return new RawSource(result.code || '');
-                                                });
-                                            }
-                                        }
-                                    }
+  return new Promise((resolve) => {
+    webpack(
+      {
+        entry,
+        output: {
+          path: BUNDLE_DIR,
+          filename: '[name].js'
+        },
+        // Use esbuild as minify, terser is tooooooo slow for so much tests.
+        optimization: {
+          minimizer: MINIFY_BUNDLE
+            ? [
+                {
+                  apply(compiler) {
+                    compiler.hooks.compilation.tap(
+                      'ESBuild Minify',
+                      (compilation) => {
+                        compilation.hooks.optimizeChunkAssets.tapPromise(
+                          'ESBuild Minify',
+                          async (chunks) => {
+                            for (const chunk of chunks) {
+                              for (const file of chunk.files) {
+                                const asset = compilation.assets[file];
+                                const { source } = asset.sourceAndMap();
+                                const result = await esbuildService.transform(
+                                  source,
+                                  {
+                                    minify: true,
+                                    sourcemap: false
+                                  }
                                 );
-                            },
-                          );
-
-                    }
-                }] : []
-            }
-        }, (err, stats) => {
-            if (err || stats.hasErrors()) {
-                if (err) {
-                    console.error(err.stack || err);
-                    if (err.details) {
-                        console.error(err.details);
-                    }
-                    resolve();
-                    return;
-                }
-
-                const info = stats.toJson();
-
-                if (stats.hasErrors()) {
-                    console.error(info.errors);
-                }
-
-                if (stats.hasWarnings()) {
-                    console.warn(info.warnings);
+                                compilation.updateAsset(file, () => {
+                                  return new RawSource(result.code || '');
+                                });
+                              }
+                            }
+                          }
+                        );
+                      }
+                    );
+                  }
                 }
+              ]
+            : []
+        }
+      },
+      (err, stats) => {
+        if (err || stats.hasErrors()) {
+          if (err) {
+            console.error(err.stack || err);
+            if (err.details) {
+              console.error(err.details);
             }
-            else {
-                console.log(chalk.green(`${Object.values(entry).map(a => `Bundled ${a}`).join('\n')}`));
-            }
-
             resolve();
-        });
-    })
+            return;
+          }
+
+          const info = stats.toJson();
+
+          if (stats.hasErrors()) {
+            console.error(info.errors);
+          }
+
+          if (stats.hasWarnings()) {
+            console.warn(info.warnings);
+          }
+        } else {
+          console.log(
+            chalk.green(
+              `${Object.values(entry)
+                .map((a) => `Bundled ${a}`)
+                .join('\n')}`
+            )
+          );
+        }
+
+        resolve();
+      }
+    );
+  });
 }
 
 function esbuildBundle(entry, result, minify) {
-    return esbuild.build({
-        entryPoints: entry,
-        bundle: true,
-        minify: minify,
-        define: {
-            'process.env.NODE_ENV': JSON.stringify(minify ? 'production' : 'development')
-        },
-        outdir: BUNDLE_DIR
-    });
+  return esbuild.build({
+    entryPoints: entry,
+    bundle: true,
+    minify: minify,
+    define: {
+      'process.env.NODE_ENV': JSON.stringify(
+        minify ? 'production' : 'development'
+      )
+    },
+    outdir: BUNDLE_DIR
+  });
 }
 
 async function bundle(entryFiles, result) {
-    if (USE_WEBPACK) {
-        // Split to multiple buckets to seepup bundle
-        // TODO Multiple entry may have effects on the final bundle.
-        const BUCKET_SIZE = 1;
-        const buckets = [];
-        const esbuildService = await esbuild.startService();
-        let count = 0;
-        outer: while (true) {
-            const bucket = {};
-            for (let i = 0; i < BUCKET_SIZE; i++) {
-                const filePath = entryFiles[count++];
-                if (!filePath) {
-                    break outer;
-                }
-                const basename = nodePath.basename(filePath, '.js');
-                bucket[basename] = filePath;
-            }
-            buckets.push(bucket);
-        }
-
-        // TODO Multiple thread.
-        for (let bucket of buckets) {
-            await webpackBundle(esbuildService, bucket, result);
+  if (USE_WEBPACK) {
+    // Split to multiple buckets to seepup bundle
+    // TODO Multiple entry may have effects on the final bundle.
+    const BUCKET_SIZE = 1;
+    const buckets = [];
+    const esbuildService = await esbuild.startService();
+    let count = 0;
+    outer: while (true) {
+      const bucket = {};
+      for (let i = 0; i < BUCKET_SIZE; i++) {
+        const filePath = entryFiles[count++];
+        if (!filePath) {
+          break outer;
         }
+        const basename = nodePath.basename(filePath, '.js');
+        bucket[basename] = filePath;
+      }
+      buckets.push(bucket);
+    }
 
-        esbuildService.stop();
+    // TODO Multiple thread.
+    for (let bucket of buckets) {
+      await webpackBundle(esbuildService, bucket, result);
     }
-    else {
-        for (let file of entryFiles) {
-            await esbuildBundle([file], result, MINIFY_BUNDLE);
-            console.log(chalk.green(`Bundled ${file}`));
-        }
+
+    esbuildService.stop();
+  } else {
+    for (let file of entryFiles) {
+      await esbuildBundle([file], result, MINIFY_BUNDLE);
+      console.log(chalk.green(`Bundled ${file}`));
     }
+  }
 }
 
 function waitTime(time) {
-    return new Promise((resolve) => setTimeout(resolve, time));
+  return new Promise((resolve) => setTimeout(resolve, time));
 }
 async function runExamples(jsFiles, result) {
-    const fileServer = new nStatic.Server(__dirname + '/../');
-    const server = require('http').createServer(function (request, response) {
-        request.addListener('end', function () {
-            fileServer.serve(request, response);
-        }).resume();
-    })
-    server.listen(port);
+  const fileServer = new nStatic.Server(__dirname + '/../');
+  const server = require('http').createServer(function (request, response) {
+    request
+      .addListener('end', function () {
+        fileServer.serve(request, response);
+      })
+      .resume();
+  });
+  server.listen(port);
+
+  try {
+    const IGNORE_LOG = [
+      'A cookie associated with a cross-site resource at',
+      'A parser-blocking, cross site',
+      // For ECharts GL
+      'RENDER WARNING',
+      'GL ERROR',
+      'GL_INVALID_OPERATION'
+    ];
+
+    const browser = await puppeteer.launch({
+      headless: false,
+      args: [
+        '--headless',
+        '--hide-scrollbars',
+        // https://github.com/puppeteer/puppeteer/issues/4913
+        '--use-gl=egl',
+        '--mute-audio'
+      ]
+    });
 
-    try {
-        const IGNORE_LOG = [
-            'A cookie associated with a cross-site resource at',
-            'A parser-blocking, cross site',
-            // For ECharts GL
-            'RENDER WARNING',
-            'GL ERROR',
-            'GL_INVALID_OPERATION'
-        ];
-
-        const browser = await puppeteer.launch({
-            headless: false,
-            args: [
-                '--headless',
-                '--hide-scrollbars',
-                // https://github.com/puppeteer/puppeteer/issues/4913
-                '--use-gl=egl',
-                '--mute-audio'
-            ]
+    await runTasks(
+      jsFiles,
+      async (file) => {
+        const page = await browser.newPage();
+        const basename = nodePath.basename(file, '.js');
+        await page.setViewport({ width: 800, height: 600 });
+
+        page.on('pageerror', function (err) {
+          // TODO Record pageerror
+          console.error(chalk.red(`[PAGE ERROR] [${basename}]`));
+          console.error(chalk.red(err.toString()));
+        });
+        page.on('console', (msg) => {
+          const text = msg.text();
+          if (!IGNORE_LOG.find((a) => text.indexOf(a) >= 0)) {
+            console.log(chalk.gray(`[PAGE LOG] [${basename}]: ${text}`));
+          }
         });
 
-        await runTasks(jsFiles, async (file) => {
-            const page = await browser.newPage();
-            const basename = nodePath.basename(file, '.js');
-            await page.setViewport({ width: 800, height: 600 });
-
-            page.on('pageerror', function (err) {
-                // TODO Record pageerror
-                console.error(chalk.red(`[PAGE ERROR] [${basename}]`));
-                console.error(chalk.red(err.toString()));
-            });
-            page.on('console', msg => {
-                const text = msg.text();
-                if (!IGNORE_LOG.find(a => text.indexOf(a) >= 0)) {
-                    console.log(chalk.gray(`[PAGE LOG] [${basename}]: ${text}`));
-                }
-            });
-
-            await page.goto(`${baseUrl}/e2e/template.html`, {
-                waitUntil: 'networkidle0',
-                timeout: 10000
-            });
-            await page.addScriptTag({
-                url: `${baseUrl}/e2e/tmp/bundles/${basename}.js`
-            });
-            await waitTime(200);
-
-            await page.screenshot({
-                type: 'png',
-                path: nodePath.resolve(SCREENSHOTS_DIR, basename + '.png')
-            });
-
-            await page.close();
-
-            console.log(chalk.green(`Rendered ${file}`));
-        }, 8);
-    }
-    catch (e) {
-        server.close();
-        throw e;
-    }
-}
+        await page.goto(`${baseUrl}/e2e/template.html`, {
+          waitUntil: 'networkidle0',
+          timeout: 10000
+        });
+        await page.addScriptTag({
+          url: `${baseUrl}/e2e/tmp/bundles/${basename}.js`
+        });
+        await waitTime(200);
 
+        await page.screenshot({
+          type: 'png',
+          path: nodePath.resolve(SCREENSHOTS_DIR, basename + '.png')
+        });
 
-async function compareExamples(testNames, result) {
+        await page.close();
 
-    function writePNG(png, diffPath) {
-        return new Promise(resolve => {
-            const writer = fs.createWriteStream(diffPath);
-            png.pack().pipe(writer);
-            writer.on('finish', () => { resolve(); });
-        });
-    }
+        console.log(chalk.green(`Rendered ${file}`));
+      },
+      8
+    );
+  } catch (e) {
+    server.close();
+    throw e;
+  }
+}
 
-    for (let testName of testNames) {
-        const diffMinimal = await compareImage(
-            nodePath.resolve(SCREENSHOTS_DIR, testName + '.png'),
-            nodePath.resolve(SCREENSHOTS_DIR, `${testName}.${MINIMAL_POSTFIX}.png`)
-        );
-        const diffMinimalLegacy = await compareImage(
-            nodePath.resolve(SCREENSHOTS_DIR, testName + '.png'),
-            nodePath.resolve(SCREENSHOTS_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.png`)
-        );
+async function compareExamples(testNames, result) {
+  function writePNG(png, diffPath) {
+    return new Promise((resolve) => {
+      const writer = fs.createWriteStream(diffPath);
+      png.pack().pipe(writer);
+      writer.on('finish', () => {
+        resolve();
+      });
+    });
+  }
 
-        const diffMinimalPNGPath = nodePath.resolve(SCREENSHOTS_DIR, `${testName}.${MINIMAL_POSTFIX}.diff.png`);
-        const diffMinimalLegacyPNGPath = nodePath.resolve(SCREENSHOTS_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.diff.png`);
+  for (let testName of testNames) {
+    const diffMinimal = await compareImage(
+      nodePath.resolve(SCREENSHOTS_DIR, testName + '.png'),
+      nodePath.resolve(SCREENSHOTS_DIR, `${testName}.${MINIMAL_POSTFIX}.png`)
+    );
+    const diffMinimalLegacy = await compareImage(
+      nodePath.resolve(SCREENSHOTS_DIR, testName + '.png'),
+      nodePath.resolve(
+        SCREENSHOTS_DIR,
+        `${testName}.${MINIMAL_LEGACY_POSTFIX}.png`
+      )
+    );
 
-        writePNG(diffMinimal.diffPNG, diffMinimalPNGPath);
-        writePNG(diffMinimalLegacy.diffPNG, diffMinimalLegacyPNGPath);
+    const diffMinimalPNGPath = nodePath.resolve(
+      SCREENSHOTS_DIR,
+      `${testName}.${MINIMAL_POSTFIX}.diff.png`
+    );
+    const diffMinimalLegacyPNGPath = nodePath.resolve(
+      SCREENSHOTS_DIR,
+      `${testName}.${MINIMAL_LEGACY_POSTFIX}.diff.png`
+    );
 
-        result[testName].screenshotDiff = {
-            minimal: {
-                ratio: diffMinimal.diffRatio,
-                png: nodePath.basename(diffMinimalPNGPath)
-            },
-            minimalLegacy: {
-                ratio: diffMinimalLegacy.diffRatio,
-                png: nodePath.basename(diffMinimalLegacyPNGPath)
-            }
-        }
+    writePNG(diffMinimal.diffPNG, diffMinimalPNGPath);
+    writePNG(diffMinimalLegacy.diffPNG, diffMinimalLegacyPNGPath);
+
+    result[testName].screenshotDiff = {
+      minimal: {
+        ratio: diffMinimal.diffRatio,
+        png: nodePath.basename(diffMinimalPNGPath)
+      },
+      minimalLegacy: {
+        ratio: diffMinimalLegacy.diffRatio,
+        png: nodePath.basename(diffMinimalLegacyPNGPath)
+      }
+    };
 
-        if (diffMinimal.diffRatio > 0 || diffMinimalLegacy.diffRatio > 0) {
-            console.log(chalk.red(`Failed ${testName}`));
-        }
-        else {
-            console.log(chalk.green(`Passed ${testName}`));
-        }
+    if (diffMinimal.diffRatio > 0 || diffMinimalLegacy.diffRatio > 0) {
+      console.log(chalk.red(`Failed ${testName}`));
+    } else {
+      console.log(chalk.green(`Passed ${testName}`));
     }
+  }
 }
 
-
 async function main() {
-    let result;
-
-    if (!args.skip && !args.tests) {
-        // Don't clean up if skipping some of the stages.
-        await prepare();
-        result = {};
-    }
-    else {
-        // Read result.
-        try {
-            result = JSON.parse(fs.readFileSync(__dirname + '/tmp/result.json', 'utf-8'));
-        }
-        catch (e) {
-            console.error(e);
-            throw 'Must run full e2e test without --skip and --tests at least once.';
-        }
-    }
-
-    function isNotSkipped(stage) {
-        return !((args.skip || '').indexOf(stage) >= 0);
+  let result;
+
+  if (!args.skip && !args.tests) {
+    // Don't clean up if skipping some of the stages.
+    await prepare();
+    result = {};
+  } else {
+    // Read result.
+    try {
+      result = JSON.parse(
+        fs.readFileSync(__dirname + '/tmp/result.json', 'utf-8')
+      );
+    } catch (e) {
+      console.error(e);
+      throw 'Must run full e2e test without --skip and --tests at least once.';
     }
+  }
 
-    // We don't have to test the npm if bundle is also skipped.
-    if (isNotSkipped('npm') && isNotSkipped('bundle')) {
-        if (!args.local) {
-            console.log(chalk.gray('Downloading packages'));
-            await downloadPackages(config);
-        }
+  function isNotSkipped(stage) {
+    return !((args.skip || '').indexOf(stage) >= 0);
+  }
 
-        console.log(chalk.gray('Installing packages'));
-        await installPackages(config);
-    }
-    else {
-        console.log(chalk.yellow('Skipped NPM.'));
+  // We don't have to test the npm if bundle is also skipped.
+  if (isNotSkipped('npm') && isNotSkipped('bundle')) {
+    if (!args.local) {
+      console.log(chalk.gray('Downloading packages'));
+      await downloadPackages(config);
     }
 
-
-    console.log(chalk.gray('Generating codes'));
-    // Always build code.
-    const testNames = await buildRunCode();
-
-    for (let key of testNames) {
-        result[key] = result[key] || {};
-    }
-
-    Object.keys(result).forEach(key => {
-        // Always do TS check on all tests. So reset all compile errors.
-        result[key].compileErrors = {
-            full: [],
-            minimal: [],
-            minimalLegacy: []
-        };
-    });
-
-    console.log('Compiling TypeScript');
-    // Always run typescript check to generate the js code.
-    await compileTs(
-        (await globby(nodePath.join(RUN_CODE_DIR, '*.ts')))
-            // No need to check types of the minimal legacy imports
-            .filter(a => !a.endsWith(`${MINIMAL_LEGACY_POSTFIX}.ts`)),
-        result
+    console.log(chalk.gray('Installing packages'));
+    await installPackages(config);
+  } else {
+    console.log(chalk.yellow('Skipped NPM.'));
+  }
+
+  console.log(chalk.gray('Generating codes'));
+  // Always build code.
+  const testNames = await buildRunCode();
+
+  for (let key of testNames) {
+    result[key] = result[key] || {};
+  }
+
+  Object.keys(result).forEach((key) => {
+    // Always do TS check on all tests. So reset all compile errors.
+    result[key].compileErrors = {
+      full: [],
+      minimal: [],
+      minimalLegacy: []
+    };
+  });
+
+  console.log('Compiling TypeScript');
+  // Always run typescript check to generate the js code.
+  await compileTs(
+    (
+      await globby(nodePath.join(RUN_CODE_DIR, '*.ts'))
+    )
+      // No need to check types of the minimal legacy imports
+      .filter((a) => !a.endsWith(`${MINIMAL_LEGACY_POSTFIX}.ts`)),
+    result
+  );
+
+  if (isNotSkipped('bundle')) {
+    console.log(
+      chalk.green(`Bundling with ${USE_WEBPACK ? 'webpack' : 'esbuild'}`)
     );
-
-    if (isNotSkipped('bundle')) {
-        console.log(chalk.green(`Bundling with ${USE_WEBPACK ? 'webpack' : 'esbuild'}`));
-        const jsFiles = [];
-        for (let testName of testNames) {
-            jsFiles.push(
-                nodePath.join(RUN_CODE_DIR, `${testName}.js`),
-                nodePath.join(RUN_CODE_DIR, `${testName}.${MINIMAL_POSTFIX}.js`),
-                nodePath.join(RUN_CODE_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.js`)
-            );
-        }
-        await bundle(jsFiles, result);
-    }
-    else {
-        console.log(chalk.yellow('Skipped Bundle.'));
-    }
-
-    if (isNotSkipped('render')) {
-        console.log(chalk.green('Running examples'));
-        const bundleFiles = [];
-        for (let testName of testNames) {
-            bundleFiles.push(
-                nodePath.join(BUNDLE_DIR, `${testName}.js`),
-                nodePath.join(BUNDLE_DIR, `${testName}.${MINIMAL_POSTFIX}.js`),
-                nodePath.join(BUNDLE_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.js`)
-            );
-        }
-        await runExamples(bundleFiles, result);
-    }
-    else {
-        console.log(chalk.yellow('Skipped Render.'));
-    }
-
-    if (isNotSkipped('compare')) {
-        console.log(chalk.green('Comparing Results'));
-        await compareExamples(testNames, result);
+    const jsFiles = [];
+    for (let testName of testNames) {
+      jsFiles.push(
+        nodePath.join(RUN_CODE_DIR, `${testName}.js`),
+        nodePath.join(RUN_CODE_DIR, `${testName}.${MINIMAL_POSTFIX}.js`),
+        nodePath.join(RUN_CODE_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.js`)
+      );
     }
-    else {
-        console.log(chalk.yellow('Skipped Compare.'));
+    await bundle(jsFiles, result);
+  } else {
+    console.log(chalk.yellow('Skipped Bundle.'));
+  }
+
+  if (isNotSkipped('render')) {
+    console.log(chalk.green('Running examples'));
+    const bundleFiles = [];
+    for (let testName of testNames) {
+      bundleFiles.push(
+        nodePath.join(BUNDLE_DIR, `${testName}.js`),
+        nodePath.join(BUNDLE_DIR, `${testName}.${MINIMAL_POSTFIX}.js`),
+        nodePath.join(BUNDLE_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.js`)
+      );
     }
-
-    fs.writeFileSync(__dirname + '/tmp/result.json', JSON.stringify(
-        result, null, 2
-    ), 'utf-8');
+    await runExamples(bundleFiles, result);
+  } else {
+    console.log(chalk.yellow('Skipped Render.'));
+  }
+
+  if (isNotSkipped('compare')) {
+    console.log(chalk.green('Comparing Results'));
+    await compareExamples(testNames, result);
+  } else {
+    console.log(chalk.yellow('Skipped Compare.'));
+  }
+
+  fs.writeFileSync(
+    __dirname + '/tmp/result.json',
+    JSON.stringify(result, null, 2),
+    'utf-8'
+  );
 }
 
-main().catch(e => {
+main()
+  .catch((e) => {
     console.error(e);
     process.exit();
-}).then(() => {
+  })
+  .then(() => {
     process.exit();
-});
+  });
 
-process.on('SIGINT', function() {
-    console.log('Closing');
-    // Close through ctrl + c;
-    process.exit();
-});
\ No newline at end of file
+process.on('SIGINT', function () {
+  console.log('Closing');
+  // Close through ctrl + c;
+  process.exit();
+});
diff --git a/e2e/package.json b/e2e/package.json
index bb44880..5dbec9c 100644
--- a/e2e/package.json
+++ b/e2e/package.json
@@ -9,6 +9,5 @@
   },
   "author": "",
   "license": "ISC",
-  "dependencies": {
-  }
+  "dependencies": {}
 }
diff --git a/e2e/preview.html b/e2e/preview.html
index fb94486..46f4ad5 100644
--- a/e2e/preview.html
+++ b/e2e/preview.html
@@ -1,27 +1,34 @@
 <!DOCTYPE html>
 <html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@2.2.4/dist/jquery.min.js"></script>
-    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/dat.gui@0.6.5/build/dat.gui.min.js"></script>
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <script
+      type="text/javascript"
+      src="https://cdn.jsdelivr.net/npm/jquery@2.2.4/dist/jquery.min.js"
+    ></script>
+    <script
+      type="text/javascript"
+      src="https://cdn.jsdelivr.net/npm/dat.gui@0.6.5/build/dat.gui.min.js"
+    ></script>
     <title>Test Container</title>
-</head>
-<body>
+  </head>
+  <body>
     <style>
-        html, body {
-            margin: 0;
-            overflow: hidden;
-        }
-        #main {
-            position: absolute;
-            left: 0px;
-            top: 0px;
-            right: 0px;
-            bottom: 0px;
-        }
+      html,
+      body {
+        margin: 0;
+        overflow: hidden;
+      }
+      #main {
+        position: absolute;
+        left: 0px;
+        top: 0px;
+        right: 0px;
+        bottom: 0px;
+      }
     </style>
     <div id="main"></div>
     <script src="tmp/bundles/graph-grid.js"></script>
-</body>
-</html>
\ No newline at end of file
+  </body>
+</html>
diff --git a/e2e/report.html b/e2e/report.html
index d4c44f2..edc4589 100644
--- a/e2e/report.html
+++ b/e2e/report.html
@@ -1,186 +1,209 @@
 <!DOCTYPE html>
 <html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Test Report</title>
-    <link href="https://cdn.jsdelivr.net/npm/element-ui@2.14.1/lib/theme-chalk/index.css" rel="stylesheet" type="text/css">
+    <link
+      href="https://cdn.jsdelivr.net/npm/element-ui@2.14.1/lib/theme-chalk/index.css"
+      rel="stylesheet"
+      type="text/css"
+    />
 
     <style>
-        #app {
-            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
-        }
+      #app {
+        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+      }
 
-        .import-type-title {
-            padding: 10px;
-        }
+      .import-type-title {
+        padding: 10px;
+      }
 
-        .import-type-title div {
-            font-size: 14px;
-            font-family:'Courier New', Courier, monospace;
-        }
+      .import-type-title div {
+        font-size: 14px;
+        font-family: 'Courier New', Courier, monospace;
+      }
 
-        .type-error-log {
-            padding: 10px;
-            color: red;
-            font-family:'Courier New', Courier, monospace;
-        }
-        .type-error-log pre {
-            margin: 5px 0;
-            padding: 0;
-            /* https://css-tricks.com/snippets/css/make-pre-text-wrap/ */
-            white-space: pre-wrap;
-        }
-        .type-passed {
-            font-size: 14px;
-            color: green;
-            font-family:'Courier New', Courier, monospace;
-            padding: 10px;
-        }
+      .type-error-log {
+        padding: 10px;
+        color: red;
+        font-family: 'Courier New', Courier, monospace;
+      }
+      .type-error-log pre {
+        margin: 5px 0;
+        padding: 0;
+        /* https://css-tricks.com/snippets/css/make-pre-text-wrap/ */
+        white-space: pre-wrap;
+      }
+      .type-passed {
+        font-size: 14px;
+        color: green;
+        font-family: 'Courier New', Courier, monospace;
+        padding: 10px;
+      }
     </style>
-
-</head>
-<body>
+  </head>
+  <body>
     <div id="app">
-        <el-tabs v-model="tab" type="border-card">
-            <el-tab-pane label="Type Checking" name="typechecking">
-                <div v-for="item in typeCheckingResult">
-                    <h3>{{ item.testName }}({{item.compileErrorsCount}})</h3>
-                    <el-row :gutter="30">
-                        <el-col :span="12">
-                            <el-card :body-style="{ padding: '0px' }">
-                                <div class="import-type-title">
-                                    <div>全量引入</div>
-                                    <div>Full Import</div>
-                                </div>
-                                <div class="type-error-log" v-if="item.compileErrors.full.length">
-                                    <div v-for="compileError in item.compileErrors.full">
-                                        <pre>[{{compileError.location.join(', ')}}] {{compileError.message}}</pre>
-                                    </div>
-                                </div>
-                                <div class="type-passed" v-else>
-                                    No Error
-                                </div>
-                            </el-card>
-                        </el-col>
-                        <el-col :span="12">
-                            <el-card :body-style="{ padding: '0px' }">
-                                <div class="import-type-title">
-                                    <div>按需引入</div>
-                                    <div>Minimal Import </div>
-                                </div>
-                                <div class="type-error-log" v-if="item.compileErrors.minimal.length">
-                                    <div v-for="compileError in item.compileErrors.minimal">
-                                        <pre>[{{compileError.location.join(', ')}}] {{compileError.message}}</pre>
-                                    </div>
-                                </div>
-                                <div class="type-passed" v-else>
-                                    No Error
-                                </div>
-                            </el-card>
-                        </el-col>
-                    </el-row>
-                </div>
-            </el-tab-pane>
-            <el-tab-pane label="Screenshots Compare" name="screenshots">
-                <div v-for="item in screenshotsCompareResult">
-                    <h3>{{ item.testName }}({{item.screenshotDiffRatio}})</h3>
-                    <el-row :gutter="10">
-                        <el-col :span="4">
-                            <el-card :body-style="{ padding: '0px' }">
-                                <el-image :src="SCREENSHOT_ROOT + item.testName + '.png'"></el-image>
-                                <div class="import-type-title">
-                                    <div>全量引入</div>
-                                    <div>Full Import</div>
-                                </div>
-                            </el-card>
-                        </el-col>
-                        <el-col :span="4">
-                            <el-card :body-style="{ padding: '0px' }">
-                                <el-image :src="SCREENSHOT_ROOT + item.testName + '.minimal.png'"></el-image>
-                                <div class="import-type-title">
-                                    <div>按需引入</div>
-                                    <div>Minimal Import </div>
-                                </div>
-                            </el-card>
-                        </el-col>
-                        <el-col :span="4">
-                            <el-card :body-style="{ padding: '0px' }">
-                                <el-image :src="SCREENSHOT_ROOT + item.testName + '.minimal.legacy.png'"></el-image>
-                                <div class="import-type-title">
-                                    <div>自注册方式按需引入</div>
-                                    <div>Minimal Import with Self Registion</div>
-                                </div>
-                            </el-card>
-                        </el-col>
-                        <el-col :span="4">
-                            <el-card :body-style="{ padding: '0px' }">
-                                <el-image :src="SCREENSHOT_ROOT + item.testName + '.minimal.diff.png'"></el-image>
-                                <div class="import-type-title">
-                                    <div>按需引入差异</div>
-                                    <div>Diff of Minimal Import </div>
-                                </div>
-                            </el-card>
-                        </el-col>
-                        <el-col :span="4">
-                            <el-card :body-style="{ padding: '0px' }">
-                                <el-image :src="SCREENSHOT_ROOT + item.testName + '.minimal.legacy.diff.png'"></el-image>
-                                <div class="import-type-title">
-                                    <div>自注册方式按需引入差异</div>
-                                    <div>Diff of Minimal Import with Self Registion</div>
-                                </div>
-                            </el-card>
-                        </el-col>
-                    </el-row>
-                </div>
-            </el-tab-pane>
-        </el-tabs>
+      <el-tabs v-model="tab" type="border-card">
+        <el-tab-pane label="Type Checking" name="typechecking">
+          <div v-for="item in typeCheckingResult">
+            <h3>{{ item.testName }}({{item.compileErrorsCount}})</h3>
+            <el-row :gutter="30">
+              <el-col :span="12">
+                <el-card :body-style="{ padding: '0px' }">
+                  <div class="import-type-title">
+                    <div>全量引入</div>
+                    <div>Full Import</div>
+                  </div>
+                  <div
+                    class="type-error-log"
+                    v-if="item.compileErrors.full.length"
+                  >
+                    <div v-for="compileError in item.compileErrors.full">
+                      <pre>
+[{{compileError.location.join(', ')}}] {{compileError.message}}</pre
+                      >
+                    </div>
+                  </div>
+                  <div class="type-passed" v-else>No Error</div>
+                </el-card>
+              </el-col>
+              <el-col :span="12">
+                <el-card :body-style="{ padding: '0px' }">
+                  <div class="import-type-title">
+                    <div>按需引入</div>
+                    <div>Minimal Import</div>
+                  </div>
+                  <div
+                    class="type-error-log"
+                    v-if="item.compileErrors.minimal.length"
+                  >
+                    <div v-for="compileError in item.compileErrors.minimal">
+                      <pre>
+[{{compileError.location.join(', ')}}] {{compileError.message}}</pre
+                      >
+                    </div>
+                  </div>
+                  <div class="type-passed" v-else>No Error</div>
+                </el-card>
+              </el-col>
+            </el-row>
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="Screenshots Compare" name="screenshots">
+          <div v-for="item in screenshotsCompareResult">
+            <h3>{{ item.testName }}({{item.screenshotDiffRatio}})</h3>
+            <el-row :gutter="10">
+              <el-col :span="4">
+                <el-card :body-style="{ padding: '0px' }">
+                  <el-image
+                    :src="SCREENSHOT_ROOT + item.testName + '.png'"
+                  ></el-image>
+                  <div class="import-type-title">
+                    <div>全量引入</div>
+                    <div>Full Import</div>
+                  </div>
+                </el-card>
+              </el-col>
+              <el-col :span="4">
+                <el-card :body-style="{ padding: '0px' }">
+                  <el-image
+                    :src="SCREENSHOT_ROOT + item.testName + '.minimal.png'"
+                  ></el-image>
+                  <div class="import-type-title">
+                    <div>按需引入</div>
+                    <div>Minimal Import</div>
+                  </div>
+                </el-card>
+              </el-col>
+              <el-col :span="4">
+                <el-card :body-style="{ padding: '0px' }">
+                  <el-image
+                    :src="SCREENSHOT_ROOT + item.testName + '.minimal.legacy.png'"
+                  ></el-image>
+                  <div class="import-type-title">
+                    <div>自注册方式按需引入</div>
+                    <div>Minimal Import with Self Registion</div>
+                  </div>
+                </el-card>
+              </el-col>
+              <el-col :span="4">
+                <el-card :body-style="{ padding: '0px' }">
+                  <el-image
+                    :src="SCREENSHOT_ROOT + item.testName + '.minimal.diff.png'"
+                  ></el-image>
+                  <div class="import-type-title">
+                    <div>按需引入差异</div>
+                    <div>Diff of Minimal Import</div>
+                  </div>
+                </el-card>
+              </el-col>
+              <el-col :span="4">
+                <el-card :body-style="{ padding: '0px' }">
+                  <el-image
+                    :src="SCREENSHOT_ROOT + item.testName + '.minimal.legacy.diff.png'"
+                  ></el-image>
+                  <div class="import-type-title">
+                    <div>自注册方式按需引入差异</div>
+                    <div>Diff of Minimal Import with Self Registion</div>
+                  </div>
+                </el-card>
+              </el-col>
+            </el-row>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
     </div>
     <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
     <script src="https://cdn.jsdelivr.net/npm/element-ui@2.14.1/lib/index.js"></script>
 
     <script>
-        const app = new Vue({
-            el: '#app',
-            data() {
-                return {
-                    typeCheckingResult: [],
-                    screenshotsCompareResult: [],
+      const app = new Vue({
+        el: '#app',
+        data() {
+          return {
+            typeCheckingResult: [],
+            screenshotsCompareResult: [],
 
-                    SCREENSHOT_ROOT: './tmp/screenshots/',
+            SCREENSHOT_ROOT: './tmp/screenshots/',
 
-                    tab: 'screenshots',
-                    splitterModel: 10
-                };
-            }
-        });
+            tab: 'screenshots',
+            splitterModel: 10
+          };
+        }
+      });
 
-        fetch('./tmp/result.json')
-            .then(response => response.json())
-            .then(json => {
-                const result = [];
-                function getCompilerErrorsCount({ full, minimal, minimalLegacy }) {
-                    return full.length + minimal.length + minimalLegacy.length;
-                }
-                function getScreenshotDiffRatio({ minimal, minimalLegacy }) {
-                    return minimal.ratio + minimalLegacy.ratio;
-                }
+      fetch('./tmp/result.json')
+        .then((response) => response.json())
+        .then((json) => {
+          const result = [];
+          function getCompilerErrorsCount({ full, minimal, minimalLegacy }) {
+            return full.length + minimal.length + minimalLegacy.length;
+          }
+          function getScreenshotDiffRatio({ minimal, minimalLegacy }) {
+            return minimal.ratio + minimalLegacy.ratio;
+          }
 
-                Object.keys(json).forEach(key => {
-                    result.push({
-                        ...json[key],
-                        compileErrorsCount: getCompilerErrorsCount(json[key].compileErrors),
-                        screenshotDiffRatio: getScreenshotDiffRatio(json[key].screenshotDiff),
-                        testName: key
-                    });
-                });
-                app.typeCheckingResult = result.slice().sort((a, b) => {
-                    return b.compileErrorsCount - a.compileErrorsCount;
-                });
-                app.screenshotsCompareResult = result.slice().sort((a, b) => {
-                    return b.screenshotDiffRatio - a.screenshotDiffRatio;
-                });
+          Object.keys(json).forEach((key) => {
+            result.push({
+              ...json[key],
+              compileErrorsCount: getCompilerErrorsCount(
+                json[key].compileErrors
+              ),
+              screenshotDiffRatio: getScreenshotDiffRatio(
+                json[key].screenshotDiff
+              ),
+              testName: key
             });
+          });
+          app.typeCheckingResult = result.slice().sort((a, b) => {
+            return b.compileErrorsCount - a.compileErrorsCount;
+          });
+          app.screenshotsCompareResult = result.slice().sort((a, b) => {
+            return b.screenshotDiffRatio - a.screenshotDiffRatio;
+          });
+        });
     </script>
-</body>
-</html>
\ No newline at end of file
+  </body>
+</html>
diff --git a/e2e/template.html b/e2e/template.html
index 71c3b5b..664924f 100644
--- a/e2e/template.html
+++ b/e2e/template.html
@@ -1,26 +1,33 @@
 <!DOCTYPE html>
 <html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@2.2.4/dist/jquery.min.js"></script>
-    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/dat.gui@0.6.5/build/dat.gui.min.js"></script>
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <script
+      type="text/javascript"
+      src="https://cdn.jsdelivr.net/npm/jquery@2.2.4/dist/jquery.min.js"
+    ></script>
+    <script
+      type="text/javascript"
+      src="https://cdn.jsdelivr.net/npm/dat.gui@0.6.5/build/dat.gui.min.js"
+    ></script>
     <title>Test Container</title>
-</head>
-<body>
+  </head>
+  <body>
     <style>
-        html, body {
-            margin: 0;
-            overflow: hidden;
-        }
-        #main {
-            position: absolute;
-            left: 0px;
-            top: 0px;
-            right: 0px;
-            bottom: 0px;
-        }
+      html,
+      body {
+        margin: 0;
+        overflow: hidden;
+      }
+      #main {
+        position: absolute;
+        left: 0px;
+        top: 0px;
+        right: 0px;
+        bottom: 0px;
+      }
     </style>
     <div id="main"></div>
-</body>
-</html>
\ No newline at end of file
+  </body>
+</html>
diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json
index ad6231a..8c0fd90 100644
--- a/e2e/tsconfig.json
+++ b/e2e/tsconfig.json
@@ -1,13 +1,13 @@
 {
-    "compilerOptions": {
-        "target": "ES6",
+  "compilerOptions": {
+    "target": "ES6",
 
-        "strict": true,
+    "strict": true,
 
-        "moduleResolution": "node",
-        "pretty": true,
-        "outDir": "tmp/tests",
+    "moduleResolution": "node",
+    "pretty": true,
+    "outDir": "tmp/tests",
 
-        "baseUrl": "./"
-    }
-}
\ No newline at end of file
+    "baseUrl": "./"
+  }
+}
diff --git a/e2e/webpack.config.js b/e2e/webpack.config.js
index 9d8c056..02610e6 100644
--- a/e2e/webpack.config.js
+++ b/e2e/webpack.config.js
@@ -1,20 +1,19 @@
 const path = require('path');
-const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
+const BundleAnalyzerPlugin =
+  require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 const config = require('./config');
 
 module.exports = {
-    entry: path.resolve(__dirname, 'tmp/tests/area-basic.minimal.js'),
-    plugins: [
-        new BundleAnalyzerPlugin()
-    ],
-    resolve: {
-        alias: {
-            echarts: config.echartsDir,
-            zrender: config.zrenderDir
-        }
-    },
-    output: {
-        path: path.resolve(__dirname, 'tmp/bundles/'),
-        filename: 'area-basic.minimal.js'
+  entry: path.resolve(__dirname, 'tmp/tests/area-basic.minimal.js'),
+  plugins: [new BundleAnalyzerPlugin()],
+  resolve: {
+    alias: {
+      echarts: config.echartsDir,
+      zrender: config.zrenderDir
     }
-}
\ No newline at end of file
+  },
+  output: {
+    path: path.resolve(__dirname, 'tmp/bundles/'),
+    filename: 'area-basic.minimal.js'
+  }
+};
diff --git a/public/en/editor.html b/public/en/editor.html
index 2a92cdc..006c037 100644
--- a/public/en/editor.html
+++ b/public/en/editor.html
@@ -1,38 +1,45 @@
 <!DOCTYPE html>
 <html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>ECharts Examples</title>
     <style>
-        body {
-            margin: 0;
-        }
-        ul, li {
-            margin: 0;
-            padding: 0;
-        }
+      body {
+        margin: 0;
+      }
+      ul,
+      li {
+        margin: 0;
+        padding: 0;
+      }
     </style>
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css">
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css">
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css"
+    />
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css"
+    />
     <script src="//cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/js/bootstrap.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/index.js"></script>
-</head>
-<body>
+  </head>
+  <body>
     <div id="main"></div>
 
-    <link rel="stylesheet" href="../css/example-bundle.css">
+    <link rel="stylesheet" href="../css/example-bundle.css" />
     <script src="../js/example-bundle.js"></script>
 
     <script>
-        echartsExample.init(document.querySelector('#main'), {
-            locale: 'en',
-            cdnRoot: '../',
-            page: 'editor',
-            version: Date.now()
-        });
+      echartsExample.init(document.querySelector('#main'), {
+        locale: 'en',
+        cdnRoot: '../',
+        page: 'editor',
+        version: Date.now()
+      });
     </script>
-</body>
-</html>
\ No newline at end of file
+  </body>
+</html>
diff --git a/public/en/index.html b/public/en/index.html
index 31a4ee6..f70e34c 100644
--- a/public/en/index.html
+++ b/public/en/index.html
@@ -1,39 +1,45 @@
 <!DOCTYPE html>
 <html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>ECharts Examples</title>
     <style>
-        body {
-            margin: 0;
-        }
-        ul, li {
-            margin: 0;
-            padding: 0;
-        }
-
+      body {
+        margin: 0;
+      }
+      ul,
+      li {
+        margin: 0;
+        padding: 0;
+      }
     </style>
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css">
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css">
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css"
+    />
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css"
+    />
     <script src="//cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/js/bootstrap.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/index.js"></script>
-</head>
-<body>
+  </head>
+  <body>
     <div id="main"></div>
 
-    <link rel="stylesheet" href="../css/example-bundle.css">
+    <link rel="stylesheet" href="../css/example-bundle.css" />
     <script src="../js/example-bundle.js"></script>
 
     <script>
-        echartsExample.init(document.querySelector('#main'), {
-            locale: 'en',
-            cdnRoot: '../',
-            page: 'explore',
-            version: Date.now()
-        });
+      echartsExample.init(document.querySelector('#main'), {
+        locale: 'en',
+        cdnRoot: '../',
+        page: 'explore',
+        version: Date.now()
+      });
     </script>
-</body>
-</html>
\ No newline at end of file
+  </body>
+</html>
diff --git a/public/en/view.html b/public/en/view.html
index 1d1cc5a..a2e1d01 100644
--- a/public/en/view.html
+++ b/public/en/view.html
@@ -1,38 +1,45 @@
 <!DOCTYPE html>
 <html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>ECharts Examples</title>
     <style>
-        body {
-            margin: 0;
-        }
-        ul, li {
-            margin: 0;
-            padding: 0;
-        }
+      body {
+        margin: 0;
+      }
+      ul,
+      li {
+        margin: 0;
+        padding: 0;
+      }
     </style>
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css">
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css">
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css"
+    />
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css"
+    />
     <script src="//cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/js/bootstrap.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/index.js"></script>
-</head>
-<body>
+  </head>
+  <body>
     <div id="main"></div>
 
-    <link rel="stylesheet" href="../css/example-bundle.css">
+    <link rel="stylesheet" href="../css/example-bundle.css" />
     <script src="../js/example-bundle.js"></script>
 
     <script>
-        echartsExample.init(document.querySelector('#main'), {
-            locale: 'en',
-            cdnRoot: '../',
-            page: 'view',
-            version: Date.now()
-        });
+      echartsExample.init(document.querySelector('#main'), {
+        locale: 'en',
+        cdnRoot: '../',
+        page: 'view',
+        version: Date.now()
+      });
     </script>
-</body>
-</html>
\ No newline at end of file
+  </body>
+</html>
diff --git a/public/zh/editor.html b/public/zh/editor.html
index ce69154..65edec1 100644
--- a/public/zh/editor.html
+++ b/public/zh/editor.html
@@ -1,38 +1,45 @@
 <!DOCTYPE html>
 <html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>ECharts Examples</title>
     <style>
-        body {
-            margin: 0;
-        }
-        ul, li {
-            margin: 0;
-            padding: 0;
-        }
+      body {
+        margin: 0;
+      }
+      ul,
+      li {
+        margin: 0;
+        padding: 0;
+      }
     </style>
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css">
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css">
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css"
+    />
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css"
+    />
     <script src="//cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/js/bootstrap.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/index.js"></script>
-</head>
-<body>
+  </head>
+  <body>
     <div id="main"></div>
 
-    <link rel="stylesheet" href="../css/example-bundle.css">
+    <link rel="stylesheet" href="../css/example-bundle.css" />
     <script src="../js/example-bundle.js"></script>
 
     <script>
-        echartsExample.init(document.querySelector('#main'), {
-            locale: 'zh',
-            cdnRoot: '../',
-            page: 'editor',
-            version: Date.now()
-        });
+      echartsExample.init(document.querySelector('#main'), {
+        locale: 'zh',
+        cdnRoot: '../',
+        page: 'editor',
+        version: Date.now()
+      });
     </script>
-</body>
-</html>
\ No newline at end of file
+  </body>
+</html>
diff --git a/public/zh/index.html b/public/zh/index.html
index 4d534de..4012cfa 100644
--- a/public/zh/index.html
+++ b/public/zh/index.html
@@ -1,39 +1,45 @@
 <!DOCTYPE html>
 <html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>ECharts Examples</title>
     <style>
-        body {
-            margin: 0;
-        }
-        ul, li {
-            margin: 0;
-            padding: 0;
-        }
-
+      body {
+        margin: 0;
+      }
+      ul,
+      li {
+        margin: 0;
+        padding: 0;
+      }
     </style>
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css">
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css">
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css"
+    />
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css"
+    />
     <script src="//cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/js/bootstrap.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/index.js"></script>
-</head>
-<body>
+  </head>
+  <body>
     <div id="main"></div>
 
-    <link rel="stylesheet" href="../css/example-bundle.css">
+    <link rel="stylesheet" href="../css/example-bundle.css" />
     <script src="../js/example-bundle.js"></script>
 
     <script>
-        echartsExample.init(document.querySelector('#main'), {
-            locale: 'zh',
-            cdnRoot: '../',
-            page: 'explore',
-            version: Date.now()
-        });
+      echartsExample.init(document.querySelector('#main'), {
+        locale: 'zh',
+        cdnRoot: '../',
+        page: 'explore',
+        version: Date.now()
+      });
     </script>
-</body>
-</html>
\ No newline at end of file
+  </body>
+</html>
diff --git a/public/zh/view.html b/public/zh/view.html
index b3d3927..5edb35b 100644
--- a/public/zh/view.html
+++ b/public/zh/view.html
@@ -1,38 +1,45 @@
 <!DOCTYPE html>
 <html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>ECharts Examples</title>
     <style>
-        body {
-            margin: 0;
-        }
-        ul, li {
-            margin: 0;
-            padding: 0;
-        }
+      body {
+        margin: 0;
+      }
+      ul,
+      li {
+        margin: 0;
+        padding: 0;
+      }
     </style>
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css">
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css">
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css"
+    />
+    <link
+      rel="stylesheet"
+      href="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/theme-chalk/index.css"
+    />
     <script src="//cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/js/bootstrap.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/element-ui@2.13.2/lib/index.js"></script>
-</head>
-<body>
+  </head>
+  <body>
     <div id="main"></div>
 
-    <link rel="stylesheet" href="../css/example-bundle.css">
+    <link rel="stylesheet" href="../css/example-bundle.css" />
     <script src="../js/example-bundle.js"></script>
 
     <script>
-        echartsExample.init(document.querySelector('#main'), {
-            locale: 'zh',
-            cdnRoot: '../',
-            page: 'view',
-            version: Date.now()
-        });
+      echartsExample.init(document.querySelector('#main'), {
+        locale: 'zh',
+        cdnRoot: '../',
+        page: 'view',
+        version: Date.now()
+      });
     </script>
-</body>
-</html>
\ No newline at end of file
+  </body>
+</html>
diff --git a/src/common/config.js b/src/common/config.js
index faab503..c737a41 100644
--- a/src/common/config.js
+++ b/src/common/config.js
@@ -1,134 +1,138 @@
-
 export const EXAMPLE_CATEGORIES = [
-    'line',
-    'bar',
-    'pie',
-    'scatter',
-    'map',
-    'candlestick',
-    'radar',
-    'boxplot',
-    'heatmap',
-    'graph',
-    'lines',
-    'tree',
-    'treemap',
-    'sunburst',
-    'parallel',
-    'sankey',
-    'funnel',
-    'gauge',
-    'pictorialBar',
-    'themeRiver',
-    'calendar',
-    'custom',
+  'line',
+  'bar',
+  'pie',
+  'scatter',
+  'map',
+  'candlestick',
+  'radar',
+  'boxplot',
+  'heatmap',
+  'graph',
+  'lines',
+  'tree',
+  'treemap',
+  'sunburst',
+  'parallel',
+  'sankey',
+  'funnel',
+  'gauge',
+  'pictorialBar',
+  'themeRiver',
+  'calendar',
+  'custom',
 
-    'dataset',
-    'dataZoom',
-    'drag',
-    'rich',
+  'dataset',
+  'dataZoom',
+  'drag',
+  'rich',
 
-    'globe',
-    'bar3D',
-    'scatter3D',
-    'surface',
-    'map3D',
-    'lines3D',
-    'line3D',
-    'scatterGL',
-    'linesGL',
-    'flowGL',
-    'graphGL'
+  'globe',
+  'bar3D',
+  'scatter3D',
+  'surface',
+  'map3D',
+  'lines3D',
+  'line3D',
+  'scatterGL',
+  'linesGL',
+  'flowGL',
+  'graphGL'
 ];
 
 export const THEMES = {
-    default: [
-        '#5470c6',
-        '#91cc75',
-        '#fac858',
-        '#ee6666',
-        '#73c0de',
-        '#3ba272',
-        '#fc8452',
-        '#9a60b4',
-        '#ea7ccc'
-    ],
-    dark: [
-        '#4992ff',
-        '#7cffb2',
-        '#fddd60',
-        '#ff6e76',
-        '#58d9f9',
-        '#05c091',
-        '#ff8a45',
-        '#8d48e3',
-        '#dd79ff'
-    ]
+  default: [
+    '#5470c6',
+    '#91cc75',
+    '#fac858',
+    '#ee6666',
+    '#73c0de',
+    '#3ba272',
+    '#fc8452',
+    '#9a60b4',
+    '#ea7ccc'
+  ],
+  dark: [
+    '#4992ff',
+    '#7cffb2',
+    '#fddd60',
+    '#ff6e76',
+    '#58d9f9',
+    '#05c091',
+    '#ff8a45',
+    '#8d48e3',
+    '#dd79ff'
+  ]
 };
 
 export const BLACK_MAP = (function (list) {
-    const map = {};
-    for (var i = 0; i < list.length; i++) {
-        map[list[i]] = 1;
-    }
-    return location.href.indexOf('github.io') >= 0 ? {} : map;
+  const map = {};
+  for (var i = 0; i < list.length; i++) {
+    map[list[i]] = 1;
+  }
+  return location.href.indexOf('github.io') >= 0 ? {} : map;
 })([
-    'effectScatter-map',
-    'geo-lines',
-    'geo-map-scatter',
-    'heatmap-map',
-    'lines-airline',
-    'map-china',
-    'map-china-dataRange',
-    'map-labels',
-    'map-locate',
-    'map-province',
-    'map-world',
-    'map-world-dataRange',
-    'scatter-map',
-    'scatter-map-brush',
-    'scatter-weibo',
-    'scatter-world-population',
-    'geo3d',
-    'geo3d-with-different-height',
-    'globe-country-carousel',
-    'globe-with-echarts-surface',
-    'map3d-alcohol-consumption',
-    'map3d-wood-map',
-    'scattergl-weibo'
+  'effectScatter-map',
+  'geo-lines',
+  'geo-map-scatter',
+  'heatmap-map',
+  'lines-airline',
+  'map-china',
+  'map-china-dataRange',
+  'map-labels',
+  'map-locate',
+  'map-province',
+  'map-world',
+  'map-world-dataRange',
+  'scatter-map',
+  'scatter-map-brush',
+  'scatter-weibo',
+  'scatter-world-population',
+  'geo3d',
+  'geo3d-with-different-height',
+  'globe-country-carousel',
+  'globe-with-echarts-surface',
+  'map3d-alcohol-consumption',
+  'map3d-wood-map',
+  'scattergl-weibo'
 ]);
 
-
 const URL_PARAMS = {};
-(location.search || '').substr(1).split('&').forEach(function (item) {
+(location.search || '')
+  .substr(1)
+  .split('&')
+  .forEach(function (item) {
     const kv = item.split('=');
     URL_PARAMS[kv[0]] = kv[1];
-});
+  });
 
-export {URL_PARAMS};
+export { URL_PARAMS };
 
 export const SUPPORT_WEBP = (function () {
-    var elem = document.createElement('canvas');
-    elem.width = elem.height = 1;
-    if (!!(elem.getContext && elem.getContext('2d'))) {
-        // was able or not to get WebP representation
-        return elem.toDataURL('image/webp').indexOf('data:image/webp') === 0;
-    }
-    // very old browser like IE 8, canvas not supported
-    return false;
+  var elem = document.createElement('canvas');
+  elem.width = elem.height = 1;
+  if (!!(elem.getContext && elem.getContext('2d'))) {
+    // was able or not to get WebP representation
+    return elem.toDataURL('image/webp').indexOf('data:image/webp') === 0;
+  }
+  // very old browser like IE 8, canvas not supported
+  return false;
 })();
 
 export const SCRIPT_URLS = {
-    echartsMinJS: 'https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js',
-    echartsDir: 'https://cdn.jsdelivr.net/npm/echarts@5',
+  echartsMinJS: 'https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js',
+  echartsDir: 'https://cdn.jsdelivr.net/npm/echarts@5',
 
-    localEChartsMinJS: 'http://localhost/echarts/dist/echarts.js',
-    localEChartsDir: 'http://localhost/echarts',
+  localEChartsMinJS: 'http://localhost/echarts/dist/echarts.js',
+  localEChartsDir: 'http://localhost/echarts',
 
-    echartsStatMinJS: 'https://cdn.jsdelivr.net/npm/echarts-stat@latest/dist/ecStat.min.js',
-    // echartsGLMinJS: 'http://localhost/echarts-gl/dist/echarts-gl.min.js',
-    echartsGLMinJS: 'https://cdn.jsdelivr.net/npm/echarts-gl@2/dist/echarts-gl.min.js',
-    datGUIMinJS: 'https://cdn.jsdelivr.net/npm/dat.gui@0.6.5/build/dat.gui.min.js',
-    monacoDir: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.21.2/min/vs',
-    aceDir: 'https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict'
+  echartsStatMinJS:
+    'https://cdn.jsdelivr.net/npm/echarts-stat@latest/dist/ecStat.min.js',
+  // echartsGLMinJS: 'http://localhost/echarts-gl/dist/echarts-gl.min.js',
+  echartsGLMinJS:
+    'https://cdn.jsdelivr.net/npm/echarts-gl@2/dist/echarts-gl.min.js',
+  datGUIMinJS:
+    'https://cdn.jsdelivr.net/npm/dat.gui@0.6.5/build/dat.gui.min.js',
+  monacoDir: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.21.2/min/vs',
+  aceDir: 'https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict'
 };
diff --git a/src/common/helper.js b/src/common/helper.js
index ac4397a..811442e 100644
--- a/src/common/helper.js
+++ b/src/common/helper.js
@@ -1,60 +1,59 @@
-
 const promisesCache = {};
 
 export function loadScriptsAsync(scripts) {
-    return Promise.all(scripts.map(function (scriptUrl) {
-        if (typeof scriptUrl === 'string') {
-            scriptUrl = {
-                url: scriptUrl,
-                // TODO Not supported type
-                type: scriptUrl.match(/\.css$/) ? 'css' : 'js'
-            };
-        }
-        if (promisesCache[scriptUrl.url]) {
-            return promisesCache[scriptUrl.url];
+  return Promise.all(
+    scripts.map(function (scriptUrl) {
+      if (typeof scriptUrl === 'string') {
+        scriptUrl = {
+          url: scriptUrl,
+          // TODO Not supported type
+          type: scriptUrl.match(/\.css$/) ? 'css' : 'js'
+        };
+      }
+      if (promisesCache[scriptUrl.url]) {
+        return promisesCache[scriptUrl.url];
+      }
+      const promise = new Promise((resolve, reject) => {
+        if (scriptUrl.type === 'js') {
+          const script = document.createElement('script');
+          script.src = scriptUrl.url;
+          script.async = false;
+          script.onload = function () {
+            resolve();
+          };
+          script.onerror = function () {
+            reject();
+          };
+          document.body.appendChild(script);
+        } else if (scriptUrl.type === 'css') {
+          const link = document.createElement('link');
+          link.rel = 'stylesheet';
+          link.href = scriptUrl.url;
+          link.onload = function () {
+            resolve();
+          };
+          link.onerror = function () {
+            reject();
+          };
+          document.body.appendChild(link);
         }
-        const promise = new Promise((resolve, reject) => {
-            if (scriptUrl.type === 'js') {
-                const script = document.createElement('script');
-                script.src = scriptUrl.url;
-                script.async = false;
-                script.onload = function () {
-                    resolve();
-                };
-                script.onerror = function () {
-                    reject();
-                };
-                document.body.appendChild(script);
-            }
-            else if (scriptUrl.type === 'css') {
-                const link = document.createElement('link');
-                link.rel = 'stylesheet';
-                link.href = scriptUrl.url;
-                link.onload = function () {
-                    resolve();
-                };
-                link.onerror = function () {
-                    reject();
-                };
-                document.body.appendChild(link);
-            }
-        });
-        promisesCache[scriptUrl.url] = promise;
-        return promise;
-    }));
+      });
+      promisesCache[scriptUrl.url] = promise;
+      return promise;
+    })
+  );
 }
 
 export function downloadBlob(blob, fileName) {
-    // for IE
-    if (typeof window.navigator.msSaveBlob === 'function') {
-        window.navigator.msSaveOrOpenBlob(blob, fileName);
-    }
-    else {
-        const a = document.createElement('a');
-        a.href = URL.createObjectURL(blob);
-        a.download = fileName;
-        a.click();
-        // should revoke the blob url after the download
-        URL.revokeObjectURL(a.href);
-    }
-}
\ No newline at end of file
+  // for IE
+  if (typeof window.navigator.msSaveBlob === 'function') {
+    window.navigator.msSaveOrOpenBlob(blob, fileName);
+  } else {
+    const a = document.createElement('a');
+    a.href = URL.createObjectURL(blob);
+    a.download = fileName;
+    a.click();
+    // should revoke the blob url after the download
+    URL.revokeObjectURL(a.href);
+  }
+}
diff --git a/src/common/i18n.js b/src/common/i18n.js
index 369cba4..88e6493 100644
--- a/src/common/i18n.js
+++ b/src/common/i18n.js
@@ -1,135 +1,135 @@
 export default {
-    en: {
-        editor: {
-            run: 'Run',
-            errorInEditor: 'Errors exist in code!',
-            chartOK: 'Chart has been generated successfully, ',
+  en: {
+    editor: {
+      run: 'Run',
+      errorInEditor: 'Errors exist in code!',
+      chartOK: 'Chart has been generated successfully, ',
 
-            darkMode: 'Dark Mode',
-            enableDecal: 'Decal Pattern',
-            // lightMode: 'Light Mode',
+      darkMode: 'Dark Mode',
+      enableDecal: 'Decal Pattern',
+      // lightMode: 'Light Mode',
 
-            renderCfgTitle: 'Render',
-            renderer: 'Renderer',
-            useDirtyRect: 'Use Dirty Rect',
+      renderCfgTitle: 'Render',
+      renderer: 'Renderer',
+      useDirtyRect: 'Use Dirty Rect',
 
-            download: 'Download',
+      download: 'Download',
 
-            edit: 'Edit',
-            monacoMode: 'Enable Type Checking',
+      edit: 'Edit',
+      monacoMode: 'Enable Type Checking',
 
-            tabEditor: 'Edit Example',
-            tabFullCodePreview: 'Full Code',
-            tabOptionPreview: 'Option Preview',
-            minimalBundle: 'Minimal Bundle'
-        },
+      tabEditor: 'Edit Example',
+      tabFullCodePreview: 'Full Code',
+      tabOptionPreview: 'Option Preview',
+      minimalBundle: 'Minimal Bundle'
+    },
 
-        chartTypes: {
-            line: 'Line',
-            bar: 'Bar',
-            pie: 'Pie',
-            scatter: 'Scatter',
-            map: 'GEO/Map',
-            candlestick: 'Candlestick',
-            radar: 'Radar',
-            boxplot: 'Boxplot',
-            heatmap: 'Heatmap',
-            graph: 'Graph',
-            lines: 'Lines',
-            tree: 'Tree',
-            treemap: 'Treemap',
-            sunburst: 'Sunburst',
-            parallel: 'Parallel',
-            sankey: 'Sankey',
-            funnel: 'Funnel',
-            gauge: 'Gauge',
-            pictorialBar: 'PictorialBar',
-            themeRiver: 'ThemeRiver',
-            calendar: 'Calendar',
-            custom: 'Custom',
+    chartTypes: {
+      line: 'Line',
+      bar: 'Bar',
+      pie: 'Pie',
+      scatter: 'Scatter',
+      map: 'GEO/Map',
+      candlestick: 'Candlestick',
+      radar: 'Radar',
+      boxplot: 'Boxplot',
+      heatmap: 'Heatmap',
+      graph: 'Graph',
+      lines: 'Lines',
+      tree: 'Tree',
+      treemap: 'Treemap',
+      sunburst: 'Sunburst',
+      parallel: 'Parallel',
+      sankey: 'Sankey',
+      funnel: 'Funnel',
+      gauge: 'Gauge',
+      pictorialBar: 'PictorialBar',
+      themeRiver: 'ThemeRiver',
+      calendar: 'Calendar',
+      custom: 'Custom',
 
-            dataset: 'Dataset',
-            dataZoom: 'DataZoom',
-            drag: 'Drag',
-            rich: 'Rich Text',
+      dataset: 'Dataset',
+      dataZoom: 'DataZoom',
+      drag: 'Drag',
+      rich: 'Rich Text',
 
-            globe: '3D Globe',
-            bar3D: '3D Bar',
-            scatter3D: '3D Scatter',
-            surface: '3D Surface',
-            map3D: '3D Map',
-            lines3D: '3D Lines',
-            line3D: '3D Line',
-            scatterGL: 'Scatter GL',
-            linesGL: 'Lines GL',
-            flowGL: 'Flow GL',
-            graphGL: 'Graph GL'
-        }
-    },
-    zh: {
-        editor: {
-            run: '运行',
-            errorInEditor: '编辑器内容有误!',
-            chartOK: '图表已生成, ',
+      globe: '3D Globe',
+      bar3D: '3D Bar',
+      scatter3D: '3D Scatter',
+      surface: '3D Surface',
+      map3D: '3D Map',
+      lines3D: '3D Lines',
+      line3D: '3D Line',
+      scatterGL: 'Scatter GL',
+      linesGL: 'Lines GL',
+      flowGL: 'Flow GL',
+      graphGL: 'Graph GL'
+    }
+  },
+  zh: {
+    editor: {
+      run: '运行',
+      errorInEditor: '编辑器内容有误!',
+      chartOK: '图表已生成, ',
 
-            darkMode: '深色模式',
-            enableDecal: '无障碍花纹',
-            // lightMode: '浅色模式',
+      darkMode: '深色模式',
+      enableDecal: '无障碍花纹',
+      // lightMode: '浅色模式',
 
-            renderCfgTitle: '渲染设置',
-            useDirtyRect: '开启脏矩形优化',
-            renderer: '渲染模式',
-            download: '下载示例',
+      renderCfgTitle: '渲染设置',
+      useDirtyRect: '开启脏矩形优化',
+      renderer: '渲染模式',
+      download: '下载示例',
 
-            edit: '编辑',
-            monacoMode: '开启类型检查',
+      edit: '编辑',
+      monacoMode: '开启类型检查',
 
-            tabEditor: '示例编辑',
-            tabFullCodePreview: '完整代码',
-            tabOptionPreview: '配置项',
-            minimalBundle: '按需引入'
-        },
+      tabEditor: '示例编辑',
+      tabFullCodePreview: '完整代码',
+      tabOptionPreview: '配置项',
+      minimalBundle: '按需引入'
+    },
 
-        chartTypes: {
-            line: '折线图',
-            bar: '柱状图',
-            pie: '饼图',
-            scatter: '散点图',
-            map: '地理坐标/地图',
-            candlestick: 'K 线图',
-            radar: '雷达图',
-            boxplot: '盒须图',
-            heatmap: '热力图',
-            graph: '关系图',
-            lines: '路径图',
-            tree: '树图',
-            treemap: '矩形树图',
-            sunburst: '旭日图',
-            parallel: '平行坐标系',
-            sankey: '桑基图',
-            funnel: '漏斗图',
-            gauge: '仪表盘',
-            pictorialBar: '象形柱图',
-            themeRiver: '主题河流图',
-            calendar: '日历坐标系',
-            custom: '自定义系列',
+    chartTypes: {
+      line: '折线图',
+      bar: '柱状图',
+      pie: '饼图',
+      scatter: '散点图',
+      map: '地理坐标/地图',
+      candlestick: 'K 线图',
+      radar: '雷达图',
+      boxplot: '盒须图',
+      heatmap: '热力图',
+      graph: '关系图',
+      lines: '路径图',
+      tree: '树图',
+      treemap: '矩形树图',
+      sunburst: '旭日图',
+      parallel: '平行坐标系',
+      sankey: '桑基图',
+      funnel: '漏斗图',
+      gauge: '仪表盘',
+      pictorialBar: '象形柱图',
+      themeRiver: '主题河流图',
+      calendar: '日历坐标系',
+      custom: '自定义系列',
 
-            dataset: '数据集',
-            dataZoom: '数据区域缩放',
-            drag: '拖拽',
-            rich: '富文本',
+      dataset: '数据集',
+      dataZoom: '数据区域缩放',
+      drag: '拖拽',
+      rich: '富文本',
 
-            globe: '3D 地球',
-            bar3D: '3D 柱状图',
-            scatter3D: '3D 散点图',
-            surface: '3D 曲面',
-            map3D: '3D 地图',
-            lines3D: '3D 路径图',
-            line3D: '3D 折线图',
-            scatterGL: 'GL 散点图',
-            linesGL: 'GL 路径图',
-            flowGL: 'GL 矢量场图',
-            graphGL: 'GL 关系图'
-        }
+      globe: '3D 地球',
+      bar3D: '3D 柱状图',
+      scatter3D: '3D 散点图',
+      surface: '3D 曲面',
+      map3D: '3D 地图',
+      lines3D: '3D 路径图',
+      line3D: '3D 折线图',
+      scatterGL: 'GL 散点图',
+      linesGL: 'GL 路径图',
+      flowGL: 'GL 矢量场图',
+      graphGL: 'GL 关系图'
     }
-};
\ No newline at end of file
+  }
+};
diff --git a/src/common/store.js b/src/common/store.js
index 95a0d0f..54cc80a 100644
--- a/src/common/store.js
+++ b/src/common/store.js
@@ -1,58 +1,60 @@
-
 // import * as matter from 'gray-matter';
-import {URL_PARAMS} from '../common/config';
+import { URL_PARAMS } from '../common/config';
 
 export const store = {
-    cdnRoot: '',
-    version: '',
-    locale: '',
+  cdnRoot: '',
+  version: '',
+  locale: '',
 
-    darkMode: URL_PARAMS.theme === 'dark',
-    enableDecal: 'decal' in URL_PARAMS,
-    renderer: URL_PARAMS.renderer || 'canvas',
+  darkMode: URL_PARAMS.theme === 'dark',
+  enableDecal: 'decal' in URL_PARAMS,
+  renderer: URL_PARAMS.renderer || 'canvas',
 
-    typeCheck: URL_PARAMS.editor === 'monaco',
-    useDirtyRect: 'useDirtyRect' in URL_PARAMS,
+  typeCheck: URL_PARAMS.editor === 'monaco',
+  useDirtyRect: 'useDirtyRect' in URL_PARAMS,
 
-    runCode: '',
-    sourceCode: '',
+  runCode: '',
+  sourceCode: '',
 
-    runHash: '',
+  runHash: '',
 
-    isMobile: window.innerWidth < 600,
+  isMobile: window.innerWidth < 600,
 
-    editorStatus: {
-        type: '',
-        message: ''
-    }
+  editorStatus: {
+    type: '',
+    message: ''
+  }
 };
 
 export function loadExampleCode() {
-    return new Promise(resolve => {
-        const dataRoot = URL_PARAMS.gl ? 'data-gl' : 'data';
-        $.ajax(
-            store.typeCheck
-                ?  `${store.cdnRoot}/examples/ts/${URL_PARAMS.c}.ts?_v_${store.version}`
-                : `${store.cdnRoot}/${dataRoot}/${URL_PARAMS.c}.js?_v_${store.version}`,
-            {
-                dataType: 'text',
-                success: (data) => {
-                    resolve(data);
-                }
-            }
-        );
-    });
+  return new Promise((resolve) => {
+    const dataRoot = URL_PARAMS.gl ? 'data-gl' : 'data';
+    $.ajax(
+      store.typeCheck
+        ? `${store.cdnRoot}/examples/ts/${URL_PARAMS.c}.ts?_v_${store.version}`
+        : `${store.cdnRoot}/${dataRoot}/${URL_PARAMS.c}.js?_v_${store.version}`,
+      {
+        dataType: 'text',
+        success: (data) => {
+          resolve(data);
+        }
+      }
+    );
+  });
 }
 
 export function parseSourceCode(code) {
-    return code
-        // remove front matter
-        .replace(/\/\*[\w\W]*?\*\//, '').trim()
-        // ts code needs add `export {}` to be a module. remove it.
-        .replace(/export\s+\{\s*\}\s*;?$/g, '');
+  return (
+    code
+      // remove front matter
+      .replace(/\/\*[\w\W]*?\*\//, '')
+      .trim()
+      // ts code needs add `export {}` to be a module. remove it.
+      .replace(/export\s+\{\s*\}\s*;?$/g, '')
+  );
 }
 
 let hashId = 123;
 export function updateRunHash() {
-    store.runHash = hashId++;
-}
\ No newline at end of file
+  store.runHash = hashId++;
+}
diff --git a/src/dep/showDebugDirtyRect.js b/src/dep/showDebugDirtyRect.js
index fcd6e64..5ee3204 100644
--- a/src/dep/showDebugDirtyRect.js
+++ b/src/dep/showDebugDirtyRect.js
@@ -1,79 +1,83 @@
 var DebugRect = (function () {
-    function DebugRect(style) {
-        var dom = this.dom = document.createElement('div');
-        dom.className = 'ec-debug-dirty-rect';
-        style = Object.assign({}, style);
-        Object.assign(style, {
-            backgroundColor: 'rgba(0, 0, 255, 0.2)',
-            border: '1px solid #00f'
-        });
-        dom.style.cssText = "\nposition: absolute;\nopacity: 0;\ntransition: opacity 0.5s linear;\npointer-events: none;\n";
-        for (var key in style) {
-            if (style.hasOwnProperty(key)) {
-                dom.style[key] = style[key];
-            }
-        }
+  function DebugRect(style) {
+    var dom = (this.dom = document.createElement('div'));
+    dom.className = 'ec-debug-dirty-rect';
+    style = Object.assign({}, style);
+    Object.assign(style, {
+      backgroundColor: 'rgba(0, 0, 255, 0.2)',
+      border: '1px solid #00f'
+    });
+    dom.style.cssText =
+      '\nposition: absolute;\nopacity: 0;\ntransition: opacity 0.5s linear;\npointer-events: none;\n';
+    for (var key in style) {
+      if (style.hasOwnProperty(key)) {
+        dom.style[key] = style[key];
+      }
     }
-    DebugRect.prototype.update = function (rect) {
-        var domStyle = this.dom.style;
-        domStyle.width = rect.width + 'px';
-        domStyle.height = rect.height + 'px';
-        domStyle.left = rect.x + 'px';
-        domStyle.top = rect.y + 'px';
-    };
-    DebugRect.prototype.hide = function () {
-        this.dom.style.opacity = '0';
-    };
-    DebugRect.prototype.show = function () {
-        var _this = this;
-        clearTimeout(this._hideTimeout);
-        this.dom.style.opacity = '1';
-        this._hideTimeout = setTimeout(function () {
-            _this.hide();
-        }, 500);
-    };
-    return DebugRect;
-}());
+  }
+  DebugRect.prototype.update = function (rect) {
+    var domStyle = this.dom.style;
+    domStyle.width = rect.width + 'px';
+    domStyle.height = rect.height + 'px';
+    domStyle.left = rect.x + 'px';
+    domStyle.top = rect.y + 'px';
+  };
+  DebugRect.prototype.hide = function () {
+    this.dom.style.opacity = '0';
+  };
+  DebugRect.prototype.show = function () {
+    var _this = this;
+    clearTimeout(this._hideTimeout);
+    this.dom.style.opacity = '1';
+    this._hideTimeout = setTimeout(function () {
+      _this.hide();
+    }, 500);
+  };
+  return DebugRect;
+})();
 export default function (zr, opts) {
-    opts = opts || {};
-    var painter = zr.painter;
-    if (!painter.getLayers) {
-        throw new Error('Debug dirty rect can only been used on canvas renderer.');
-    }
-    if (painter.isSingleCanvas()) {
-        throw new Error('Debug dirty rect can only been used on zrender inited with container.');
-    }
-    var debugViewRoot = document.createElement('div');
-    debugViewRoot.style.cssText = "\nposition:absolute;\nleft:0;\ntop:0;\nright:0;\nbottom:0;\npointer-events:none;\n";
-    debugViewRoot.className = 'ec-debug-dirty-rect-container';
-    var debugRects = [];
-    var dom = zr.dom;
-    dom.appendChild(debugViewRoot);
-    var computedStyle = getComputedStyle(dom);
-    if (computedStyle.position === 'static') {
-        dom.style.position = 'relative';
-    }
-    zr.on('rendered', function () {
-        if (painter.getLayers) {
-            var idx_1 = 0;
-            painter.eachBuiltinLayer(function (layer) {
-                if (!layer.debugGetPaintRects) {
-                    return;
-                }
-                var paintRects = layer.debugGetPaintRects();
-                for (var i = 0; i < paintRects.length; i++) {
-                    if (!debugRects[idx_1]) {
-                        debugRects[idx_1] = new DebugRect(opts.style);
-                        debugViewRoot.appendChild(debugRects[idx_1].dom);
-                    }
-                    debugRects[idx_1].show();
-                    debugRects[idx_1].update(paintRects[i]);
-                    idx_1++;
-                }
-            });
-            for (var i = idx_1; i < debugRects.length; i++) {
-                debugRects[i].hide();
-            }
+  opts = opts || {};
+  var painter = zr.painter;
+  if (!painter.getLayers) {
+    throw new Error('Debug dirty rect can only been used on canvas renderer.');
+  }
+  if (painter.isSingleCanvas()) {
+    throw new Error(
+      'Debug dirty rect can only been used on zrender inited with container.'
+    );
+  }
+  var debugViewRoot = document.createElement('div');
+  debugViewRoot.style.cssText =
+    '\nposition:absolute;\nleft:0;\ntop:0;\nright:0;\nbottom:0;\npointer-events:none;\n';
+  debugViewRoot.className = 'ec-debug-dirty-rect-container';
+  var debugRects = [];
+  var dom = zr.dom;
+  dom.appendChild(debugViewRoot);
+  var computedStyle = getComputedStyle(dom);
+  if (computedStyle.position === 'static') {
+    dom.style.position = 'relative';
+  }
+  zr.on('rendered', function () {
+    if (painter.getLayers) {
+      var idx_1 = 0;
+      painter.eachBuiltinLayer(function (layer) {
+        if (!layer.debugGetPaintRects) {
+          return;
         }
-    });
+        var paintRects = layer.debugGetPaintRects();
+        for (var i = 0; i < paintRects.length; i++) {
+          if (!debugRects[idx_1]) {
+            debugRects[idx_1] = new DebugRect(opts.style);
+            debugViewRoot.appendChild(debugRects[idx_1].dom);
+          }
+          debugRects[idx_1].show();
+          debugRects[idx_1].update(paintRects[i]);
+          idx_1++;
+        }
+      });
+      for (var i = idx_1; i < debugRects.length; i++) {
+        debugRects[i].hide();
+      }
+    }
+  });
 }
diff --git a/src/editor/CodeAce.vue b/src/editor/CodeAce.vue
index ef2a34c..72258ca 100644
--- a/src/editor/CodeAce.vue
+++ b/src/editor/CodeAce.vue
@@ -1,116 +1,115 @@
 <template>
-<div class="ace-editor-main" v-loading="loading"></div>
+  <div class="ace-editor-main" v-loading="loading"></div>
 </template>
 
 <script>
-
-import {keywords} from '../data/option-keywords';
-import {loadScriptsAsync} from '../common/helper';
-import {store} from '../common/store';
-import {SCRIPT_URLS} from '../common/config';
+import { keywords } from '../data/option-keywords';
+import { loadScriptsAsync } from '../common/helper';
+import { store } from '../common/store';
+import { SCRIPT_URLS } from '../common/config';
 
 function ensureACE() {
-    if (typeof ace === 'undefined') {
-        return loadScriptsAsync([
-            SCRIPT_URLS.aceDir + '/ace.js',
-            SCRIPT_URLS.aceDir + '/ext-language_tools.js'
-        ]).then(function () {
-            const lnTools = ace.require('ace/ext/language_tools');
-
-            const completions = [];
-            keywords.forEach(keyword => {
-                completions.push({
-                    caption: keyword.name,
-                    value: keyword.name,
-                    score: keyword.count,
-                    metal: 'local'
-                });
-            });
+  if (typeof ace === 'undefined') {
+    return loadScriptsAsync([
+      SCRIPT_URLS.aceDir + '/ace.js',
+      SCRIPT_URLS.aceDir + '/ext-language_tools.js'
+    ]).then(function () {
+      const lnTools = ace.require('ace/ext/language_tools');
+
+      const completions = [];
+      keywords.forEach((keyword) => {
+        completions.push({
+          caption: keyword.name,
+          value: keyword.name,
+          score: keyword.count,
+          metal: 'local'
+        });
+      });
 
-            lnTools.addCompleter({
-                getCompletions: function (editor, session, pos, prefix, callback) {
-                    callback(null, completions);
-                }
-            });
-        })
-    }
-    return Promise.resolve();
+      lnTools.addCompleter({
+        getCompletions: function (editor, session, pos, prefix, callback) {
+          callback(null, completions);
+        }
+      });
+    });
+  }
+  return Promise.resolve();
 }
 
 export default {
-
-    props: ['initialCode'],
-
-    data() {
-        return {
-            shared: store,
-            loading: false
-        }
-    },
-
-    mounted() {
-        this.loading = true;
-        ensureACE().then(() => {
-            this.loading = false;
-            const editor = ace.edit(this.$el);
-            editor.getSession().setMode('ace/mode/javascript');
-            editor.setOptions({
-                enableBasicAutocompletion: true,
-                enableSnippets: true,
-                enableLiveAutocompletion: true
-            });
-
-            this._editor = editor;
-
-            editor.on('change', () => {
-                store.sourceCode =
-                    store.runCode = editor.getValue();
-            });
-
-            if (this.initialCode) {
-                this.setInitialCode(this.initialCode);
-            }
+  props: ['initialCode'],
+
+  data() {
+    return {
+      shared: store,
+      loading: false
+    };
+  },
+
+  mounted() {
+    this.loading = true;
+    ensureACE().then(() => {
+      this.loading = false;
+      const editor = ace.edit(this.$el);
+      editor.getSession().setMode('ace/mode/javascript');
+      editor.setOptions({
+        enableBasicAutocompletion: true,
+        enableSnippets: true,
+        enableLiveAutocompletion: true
+      });
+
+      this._editor = editor;
+
+      editor.on('change', () => {
+        store.sourceCode = store.runCode = editor.getValue();
+      });
+
+      if (this.initialCode) {
+        this.setInitialCode(this.initialCode);
+      }
+    });
+  },
+
+  methods: {
+    setInitialCode(code) {
+      if (this._editor && code) {
+        this._editor.setValue(code || '');
+        this._editor.selection.setSelectionRange({
+          start: {
+            row: 1,
+            column: 4
+          },
+          end: {
+            row: 1,
+            column: 4
+          }
         });
-    },
-
-    methods: {
-        setInitialCode(code) {
-            if (this._editor && code) {
-                this._editor.setValue(code || '');
-                this._editor.selection.setSelectionRange({
-                    start: {
-                        row:1,
-                        column: 4
-                    }, end: {
-                        row:1,
-                        column: 4
-                    }
-                });
-            }
-        }
-    },
+      }
+    }
+  },
 
-    watch: {
-        initialCode(newVal) {
-            this.setInitialCode(newVal);
-        }
+  watch: {
+    initialCode(newVal) {
+      this.setInitialCode(newVal);
     }
-}
+  }
+};
 </script>
 
 <style lang="scss">
 .ace-editor-main {
-    font-family: 'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
-    font-size: 12px;
-    line-height: 18px;
-    padding: 10px;
-    // height: 100%;
-
-    // Fix safari
-    position: absolute;
-    left: 0;
-    top: 0;
-    bottom: 0;
-    right: 0;
+  font-family: 'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas',
+    monospace;
+  font-size: 12px;
+  line-height: 18px;
+  padding: 10px;
+  // height: 100%;
+
+  // Fix safari
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  right: 0;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/editor/CodeMonaco.vue b/src/editor/CodeMonaco.vue
index 128c900..695af20 100644
--- a/src/editor/CodeMonaco.vue
+++ b/src/editor/CodeMonaco.vue
@@ -1,53 +1,56 @@
 <template>
-<div class="monaco-editor-main" v-loading="loading"></div>
+  <div class="monaco-editor-main" v-loading="loading"></div>
 </template>
 
 <script>
-
-import {loadScriptsAsync} from '../common/helper';
-import {store} from '../common/store';
-import {SCRIPT_URLS, URL_PARAMS} from '../common/config';
+import { loadScriptsAsync } from '../common/helper';
+import { store } from '../common/store';
+import { SCRIPT_URLS, URL_PARAMS } from '../common/config';
 import { ensureECharts } from './Preview.vue';
 
 function loadTypes() {
-    return fetch(
-        ('local' in URL_PARAMS
-                ? SCRIPT_URLS.localEChartsDir : SCRIPT_URLS.echartsDir) + '/types/dist/echarts.d.ts', {
-        mode: 'cors'
-    }).then(response => response.text()).then(code => {
-
-        // validation settings
-        monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
-            noSemanticValidation: false,
-            noSyntaxValidation: false
-        });
-
-        // compiler options
-        monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
-            target: monaco.languages.typescript.ScriptTarget.ES6,
-            allowNonTsExtensions: true,
-            noResolve: false
-        });
-
-        // console.log('file:///node_modules/@types/' + res[i].path);
-        monaco.languages.typescript.typescriptDefaults.addExtraLib(
-            code,
-            // https://github.com/microsoft/monaco-editor/issues/667#issuecomment-468164794
-            'file:///node_modules/@types/echarts/echarts.d.ts'
-        );
-
-        monaco.languages.typescript.typescriptDefaults.addExtraLib(
-            `
+  return fetch(
+    ('local' in URL_PARAMS
+      ? SCRIPT_URLS.localEChartsDir
+      : SCRIPT_URLS.echartsDir) + '/types/dist/echarts.d.ts',
+    {
+      mode: 'cors'
+    }
+  )
+    .then((response) => response.text())
+    .then((code) => {
+      // validation settings
+      monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
+        noSemanticValidation: false,
+        noSyntaxValidation: false
+      });
+
+      // compiler options
+      monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
+        target: monaco.languages.typescript.ScriptTarget.ES6,
+        allowNonTsExtensions: true,
+        noResolve: false
+      });
+
+      // console.log('file:///node_modules/@types/' + res[i].path);
+      monaco.languages.typescript.typescriptDefaults.addExtraLib(
+        code,
+        // https://github.com/microsoft/monaco-editor/issues/667#issuecomment-468164794
+        'file:///node_modules/@types/echarts/echarts.d.ts'
+      );
+
+      monaco.languages.typescript.typescriptDefaults.addExtraLib(
+        `
 import * as echarts from './echarts';
 // Export for UMD module.
 export as namespace echarts
 export = echarts;`,
-            // https://github.com/microsoft/monaco-editor/issues/667#issuecomment-468164794
-            'file:///node_modules/@types/echarts/index.d.ts'
-        );
+        // https://github.com/microsoft/monaco-editor/issues/667#issuecomment-468164794
+        'file:///node_modules/@types/echarts/index.d.ts'
+      );
 
-        monaco.languages.typescript.typescriptDefaults.addExtraLib(
-`import * as echarts from 'echarts';
+      monaco.languages.typescript.typescriptDefaults.addExtraLib(
+        `import * as echarts from 'echarts';
 // Declare to global namespace.
 declare global {
     const ROOT_PATH: string
@@ -76,117 +79,115 @@ declare global {
     const echarts: typeof echarts
 }
 `,
-            'file:///example.d.ts'
-        );
-        return;
+        'file:///example.d.ts'
+      );
+      return;
     });
 }
 
 function ensureMonacoAndTsTransformer() {
-    function loadMonaco() {
-        if (typeof monaco === 'undefined') {
-            return loadScriptsAsync([
-                SCRIPT_URLS.monacoDir + '/loader.js',
-                // Prebuilt TS transformer with surcrase
-                store.cdnRoot + '/js/example-transform-ts-bundle.js'
-            ]).then(function () {
-                window.require.config({ paths: { 'vs': SCRIPT_URLS.monacoDir }});
-                return new Promise(resolve => {
-                    window.require([
-                        'vs/editor/editor.main'
-                    ], function () {
-                        loadTypes().then(() => {
-                            resolve();
-                        });
-                    })
-                });
-            })
-        }
-        return Promise.resolve();
+  function loadMonaco() {
+    if (typeof monaco === 'undefined') {
+      return loadScriptsAsync([
+        SCRIPT_URLS.monacoDir + '/loader.js',
+        // Prebuilt TS transformer with surcrase
+        store.cdnRoot + '/js/example-transform-ts-bundle.js'
+      ]).then(function () {
+        window.require.config({ paths: { vs: SCRIPT_URLS.monacoDir } });
+        return new Promise((resolve) => {
+          window.require(['vs/editor/editor.main'], function () {
+            loadTypes().then(() => {
+              resolve();
+            });
+          });
+        });
+      });
     }
+    return Promise.resolve();
+  }
 
-    // Must load echarts before monaco. Or the AMD loader will affect loading of echarts.
-    return ensureECharts().then(loadMonaco);
+  // Must load echarts before monaco. Or the AMD loader will affect loading of echarts.
+  return ensureECharts().then(loadMonaco);
 }
 
 export default {
+  props: ['initialCode'],
 
-    props: ['initialCode'],
-
-    data() {
-        return {
-            shared: store,
-            loading: false
-        }
-    },
-
-    mounted() {
-        this.loading = true;
-        ensureMonacoAndTsTransformer().then(() => {
-            this.loading = false;
-            const model = monaco.editor.createModel(
-                this.initialCode || '',
-                'typescript',
-                // Should also be a file path so it can resolve the lib.
-                monaco.Uri.parse('file:///main.ts')
-            );
-            const editor = monaco.editor.create(this.$el, {
-                model,
-                fontFamily: `'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace`,
-                minimap: {
-                    enabled: false
-                },
-                automaticLayout: true
-            });
+  data() {
+    return {
+      shared: store,
+      loading: false
+    };
+  },
+
+  mounted() {
+    this.loading = true;
+    ensureMonacoAndTsTransformer().then(() => {
+      this.loading = false;
+      const model = monaco.editor.createModel(
+        this.initialCode || '',
+        'typescript',
+        // Should also be a file path so it can resolve the lib.
+        monaco.Uri.parse('file:///main.ts')
+      );
+      const editor = monaco.editor.create(this.$el, {
+        model,
+        fontFamily: `'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace`,
+        minimap: {
+          enabled: false
+        },
+        automaticLayout: true
+      });
+
+      this._editor = editor;
+
+      if (this.initialCode) {
+        store.sourceCode = this.initialCode;
+        store.runCode = echartsExampleTransformTs(store.sourceCode);
+      }
+      editor.onDidChangeModelContent(() => {
+        store.sourceCode = editor.getValue();
+        store.runCode = echartsExampleTransformTs(store.sourceCode);
+      });
+    });
+  },
 
-            this._editor = editor;
+  destroyed() {
+    if (this._editor) {
+      this._editor.getModel().dispose();
+      this._editor.dispose();
+    }
+  },
 
-            if (this.initialCode) {
-                store.sourceCode = this.initialCode;
-                store.runCode = echartsExampleTransformTs(store.sourceCode);
-            }
-            editor.onDidChangeModelContent(() => {
-                store.sourceCode = editor.getValue();
-                store.runCode = echartsExampleTransformTs(store.sourceCode);
-            });
-        });
-    },
-
-    destroyed() {
-        if (this._editor) {
-            this._editor.getModel().dispose();
-            this._editor.dispose();
-        }
-    },
-
-    methods: {
-        setInitialCode(code) {
-            if (this._editor && code) {
-                this._editor.setValue(code || '');
-            }
-        }
-    },
+  methods: {
+    setInitialCode(code) {
+      if (this._editor && code) {
+        this._editor.setValue(code || '');
+      }
+    }
+  },
 
-    watch: {
-        initialCode(newVal) {
-            this.setInitialCode(newVal);
-        }
+  watch: {
+    initialCode(newVal) {
+      this.setInitialCode(newVal);
     }
-}
+  }
+};
 </script>
 
 <style lang="scss">
 .monaco-editor-main {
-    font-family: 'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
-    font-size: 12px;
-    padding: 0;
-    overflow-y: hidden;
-    // height: 100%;
-    // Fix safari
-    position: absolute;
-    left: 0;
-    top: 0;
-    bottom: 0;
-    right: 0;
+  font-family: 'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas',
+    monospace;
+  font-size: 12px;
+  padding: 0;
+  overflow-y: hidden;
+  // height: 100%;
+  // Fix safari
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  right: 0;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/editor/Editor.vue b/src/editor/Editor.vue
index fe5532d..284487c 100644
--- a/src/editor/Editor.vue
+++ b/src/editor/Editor.vue
@@ -1,236 +1,264 @@
 <template>
-<div id="main-container">
-    <div id="editor-left-container" :style="{width: leftContainerSize + '%'}" v-if="!shared.isMobile">
-        <el-tabs v-model="currentTab" type="border-card">
-            <el-tab-pane :label="$t('editor.tabEditor')" name="code-editor">
-                <el-container>
-                    <el-header id="editor-control-panel">
-                        <div id="code-info">
-                            <template v-if="shared.editorStatus.message">
-                                <span class="code-info-time">{{currentTime}}</span>
-                                <span :class="'code-info-type-' + shared.editorStatus.type">{{shared.editorStatus.message}}</span>
-                            </template>
-                        </div>
-                        <div class="editor-controls">
-                            <!-- <el-switch v-model="shared.typeCheck"
+  <div id="main-container">
+    <div
+      id="editor-left-container"
+      :style="{ width: leftContainerSize + '%' }"
+      v-if="!shared.isMobile"
+    >
+      <el-tabs v-model="currentTab" type="border-card">
+        <el-tab-pane :label="$t('editor.tabEditor')" name="code-editor">
+          <el-container>
+            <el-header id="editor-control-panel">
+              <div id="code-info">
+                <template v-if="shared.editorStatus.message">
+                  <span class="code-info-time">{{ currentTime }}</span>
+                  <span :class="'code-info-type-' + shared.editorStatus.type">{{
+                    shared.editorStatus.message
+                  }}</span>
+                </template>
+              </div>
+              <div class="editor-controls">
+                <!-- <el-switch v-model="shared.typeCheck"
                                 :active-text="$t('editor.monacoMode')"
                                 :inactive-text="''"
                             ></el-switch> -->
-                            <a href="javascript:;" class='btn btn-default btn-sm' @click='disposeAndRun'>{{$t('editor.run')}}</a>
-                        </div>
-                    </el-header>
-                    <el-main>
-                        <CodeMonaco v-if="shared.typeCheck" id="code-panel" :initialCode="initialCode"></CodeMonaco>
-                        <CodeAce v-else id="code-panel" :initialCode="initialCode"></CodeAce>
-                    </el-main>
-                </el-container>
-            </el-tab-pane>
-
-            <el-tab-pane :label="$t('editor.tabFullCodePreview')" name="full-code" :lazy="true">
-                <el-container style="width: 100%; height: 100%">
-                    <el-header id="full-code-generate-config">
-                        <span class="full-code-generate-config-label">
-                            <!-- <i class="el-icon-setting"></i> 配置 -->
-                        </span>
-                        <el-switch
-                            class="enable-decal"
-                            v-model="fullCodeConfig.minimal"
-                            :active-text="$t('editor.minimalBundle')"
-                            :inactive-text="''">
-                        </el-switch>
-                        <el-switch
-                            class="enable-decal"
-                            v-model="fullCodeConfig.esm"
-                            active-text="ES Modules"
-                            :inactive-text="''">
-                        </el-switch>
-                    </el-header>
-                    <el-main>
-                        <FullCodePreview :code="fullCode"></FullCodePreview>
-                    </el-main>
-                </el-container>
-            </el-tab-pane>
-            <el-tab-pane :label="$t('editor.tabOptionPreview')" name="full-option">
-                <div id="option-outline"></div>
-            </el-tab-pane>
-        </el-tabs>
+                <a
+                  href="javascript:;"
+                  class="btn btn-default btn-sm"
+                  @click="disposeAndRun"
+                  >{{ $t('editor.run') }}</a
+                >
+              </div>
+            </el-header>
+            <el-main>
+              <CodeMonaco
+                v-if="shared.typeCheck"
+                id="code-panel"
+                :initialCode="initialCode"
+              ></CodeMonaco>
+              <CodeAce
+                v-else
+                id="code-panel"
+                :initialCode="initialCode"
+              ></CodeAce>
+            </el-main>
+          </el-container>
+        </el-tab-pane>
+
+        <el-tab-pane
+          :label="$t('editor.tabFullCodePreview')"
+          name="full-code"
+          :lazy="true"
+        >
+          <el-container style="width: 100%; height: 100%">
+            <el-header id="full-code-generate-config">
+              <span class="full-code-generate-config-label">
+                <!-- <i class="el-icon-setting"></i> 配置 -->
+              </span>
+              <el-switch
+                class="enable-decal"
+                v-model="fullCodeConfig.minimal"
+                :active-text="$t('editor.minimalBundle')"
+                :inactive-text="''"
+              >
+              </el-switch>
+              <el-switch
+                class="enable-decal"
+                v-model="fullCodeConfig.esm"
+                active-text="ES Modules"
+                :inactive-text="''"
+              >
+              </el-switch>
+            </el-header>
+            <el-main>
+              <FullCodePreview :code="fullCode"></FullCodePreview>
+            </el-main>
+          </el-container>
+        </el-tab-pane>
+        <el-tab-pane :label="$t('editor.tabOptionPreview')" name="full-option">
+          <div id="option-outline"></div>
+        </el-tab-pane>
+      </el-tabs>
     </div>
-    <div class="handler" id="h-handler" @mousedown="onSplitterDragStart" :style="{left: leftContainerSize + '%'}" v-if="!shared.isMobile"></div>
-    <Preview :inEditor="true" class="right-container" ref="preview" :style="{
-        width: (100 - leftContainerSize) + '%',
+    <div
+      class="handler"
+      id="h-handler"
+      @mousedown="onSplitterDragStart"
+      :style="{ left: leftContainerSize + '%' }"
+      v-if="!shared.isMobile"
+    ></div>
+    <Preview
+      :inEditor="true"
+      class="right-container"
+      ref="preview"
+      :style="{
+        width: 100 - leftContainerSize + '%',
         left: leftContainerSize + '%'
-    }"></Preview>
-</div>
+      }"
+    ></Preview>
+  </div>
 </template>
 
 <script>
-
 import CodeAce from './CodeAce.vue';
 import CodeMonaco from './CodeMonaco.vue';
 import FullCodePreview from './FullCodePreview.vue';
 import Preview from './Preview.vue';
-import {store, loadExampleCode, parseSourceCode} from '../common/store';
-import {collectDeps, buildExampleCode} from '../../common/buildCode';
-import { mount } from "@lang/object-visualizer";
+import { store, loadExampleCode, parseSourceCode } from '../common/store';
+import { collectDeps, buildExampleCode } from '../../common/buildCode';
+import { mount } from '@lang/object-visualizer';
 
 import './object-visualizer.css';
 
 export default {
-    components: {
-        CodeAce,
-        CodeMonaco,
-        FullCodePreview,
-        Preview
-    },
-
-    data() {
-        return {
-            mousedown: false,
-            leftContainerSize: 40,
-            mobileMode: false,
-            shared: store,
-            initialCode: '',
-
-            currentTab: 'code-editor',
+  components: {
+    CodeAce,
+    CodeMonaco,
+    FullCodePreview,
+    Preview
+  },
+
+  data() {
+    return {
+      mousedown: false,
+      leftContainerSize: 40,
+      mobileMode: false,
+      shared: store,
+      initialCode: '',
+
+      currentTab: 'code-editor',
+
+      fullCode: '',
+
+      fullCodeConfig: {
+        mimimal: false,
+        esm: true,
+        node: false // If is in node
+      }
+    };
+  },
+
+  computed: {
+    currentTime() {
+      // Update time when message updated.
+      const message = this.shared.message;
+
+      const time = new Date();
+      const digits = [time.getHours(), time.getMinutes(), time.getSeconds()];
+      let timeStr = '';
+      for (let i = 0, len = digits.length; i < len; ++i) {
+        timeStr += (digits[i] < 10 ? '0' : '') + digits[i];
+        if (i < len - 1) {
+          timeStr += ':';
+        }
+      }
+      return timeStr;
+    }
+  },
+
+  mounted() {
+    if (store.isMobile) {
+      this.leftContainerSize = 0;
+      loadExampleCode().then((code) => {
+        // No editor available. Set to runCode directly.
+        store.runCode = parseSourceCode(code);
+      });
+    } else {
+      loadExampleCode().then((code) => {
+        // Only set the code in editor. editor will sync to the store.
+        this.initialCode = parseSourceCode(code);
+      });
+
+      window.addEventListener('mousemove', (e) => {
+        if (this.mousedown) {
+          let percentage = e.clientX / window.innerWidth;
+          percentage = Math.min(0.9, Math.max(0.1, percentage));
+          this.leftContainerSize = percentage * 100;
+        }
+      });
 
-            fullCode: '',
+      window.addEventListener('mouseup', (e) => {
+        this.mousedown = false;
+      });
+    }
+  },
 
-            fullCodeConfig: {
-                mimimal: false,
-                esm: true,
-                node: false // If is in node
-            }
-        };
+  methods: {
+    onSplitterDragStart() {
+      this.mousedown = true;
     },
-
-    computed: {
-        currentTime() {
-            // Update time when message updated.
-            const message = this.shared.message;
-
-            const time = new Date();
-            const digits = [time.getHours(), time.getMinutes(), time.getSeconds()];
-            let timeStr = '';
-            for (let i = 0, len = digits.length; i < len; ++i) {
-                timeStr += (digits[i] < 10 ? '0' : '') + digits[i];
-                if (i < len - 1) {
-                    timeStr += ':';
-                }
-            }
-            return timeStr;
-        }
+    disposeAndRun() {
+      this.$refs.preview.refreshAll();
     },
-
-    mounted() {
-
-        if (store.isMobile) {
-            this.leftContainerSize = 0;
-            loadExampleCode().then(code => {
-                // No editor available. Set to runCode directly.
-                store.runCode = parseSourceCode(code);
-            });
-        }
-        else {
-            loadExampleCode().then(code => {
-                // Only set the code in editor. editor will sync to the store.
-                this.initialCode = parseSourceCode(code);
-            });
-
-            window.addEventListener('mousemove', (e) => {
-                if (this.mousedown) {
-                    let percentage = e.clientX / window.innerWidth;
-                    percentage = Math.min(0.9, Math.max(0.1, percentage));
-                    this.leftContainerSize = percentage * 100;
-                }
-            });
-
-            window.addEventListener('mouseup', (e) => {
-                this.mousedown = false;
-            });
-        }
+    updateFullCode() {
+      const option = this.$refs.preview.getOption();
+      if (!option) {
+        return;
+      }
+      const deps = collectDeps(option);
+      deps.push(store.renderer === 'svg' ? 'SVGRenderer' : 'CanvasRenderer');
+      this.fullCode = buildExampleCode(store.sourceCode, deps, {
+        minimal: this.fullCodeConfig.minimal,
+        ts: false,
+        esm: this.fullCodeConfig.esm,
+        // legacy: true,
+        theme: store.darkMode ? 'dark' : '',
+        ROOT_PATH: store.cdnRoot
+      });
     },
-
-    methods: {
-        onSplitterDragStart() {
-            this.mousedown = true;
-        },
-        disposeAndRun() {
-            this.$refs.preview.refreshAll();
-        },
-        updateFullCode() {
-            const option = this.$refs.preview.getOption();
-            if (!option) {
-                return;
-            }
-            const deps = collectDeps(option);
-            deps.push(store.renderer === 'svg' ? 'SVGRenderer' : 'CanvasRenderer');
-            this.fullCode = buildExampleCode(store.sourceCode, deps, {
-                minimal: this.fullCodeConfig.minimal,
-                ts: false,
-                esm: this.fullCodeConfig.esm,
-                // legacy: true,
-                theme: store.darkMode ? 'dark' : '',
-                ROOT_PATH: store.cdnRoot
-            });
-        },
-        updateOptionOutline() {
-            const option = Object.freeze(this.$refs.preview.getOption());
-            if (!option) {
-                return;
+    updateOptionOutline() {
+      const option = Object.freeze(this.$refs.preview.getOption());
+      if (!option) {
+        return;
+      }
+      mount(option, this.$el.querySelector('#option-outline'), {
+        getKeys(object, path) {
+          return Object.keys(object).filter((key) => {
+            if (Array.isArray(object[key]) && !object[key].length) {
+              return false;
             }
-            mount(
-                option,
-                this.$el.querySelector('#option-outline'),
-                {
-                    getKeys(object, path) {
-                        return Object.keys(object).filter(key => {
-                            if (Array.isArray(object[key]) && !object[key].length) {
-                                return false;
-                            }
-                            return true;
-                        });
-                    },
-                    expandOnCreatedAndUpdated(path) {
-                        return path.length === 0
-                            || (path[0] === 'series' && path.length <= 1);
-                    },
-                }
-            );
+            return true;
+          });
         },
-        updateTabContent(tab) {
-            if (tab === 'full-code') {
-                this.updateFullCode();
-            }
-            else if (tab === 'full-option') {
-                this.updateOptionOutline();
-            }
+        expandOnCreatedAndUpdated(path) {
+          return (
+            path.length === 0 || (path[0] === 'series' && path.length <= 1)
+          );
         }
+      });
     },
+    updateTabContent(tab) {
+      if (tab === 'full-code') {
+        this.updateFullCode();
+      } else if (tab === 'full-option') {
+        this.updateOptionOutline();
+      }
+    }
+  },
 
-    watch: {
-        'shared.typeCheck'(enableTypeCheck) {
-            // Update initialCode to avoid code changed when switching editor
-            this.initialCode = store.sourceCode;
-            this.updateFullCode();
-        },
-        'currentTab'(tab) {
-            this.updateTabContent(tab);
-        },
-        'shared.runHash'() {
-            this.updateTabContent(this.currentTab);
-        },
-        fullCodeConfig: {
-            deep: true,
-            handler() {
-                this.updateFullCode();
-            }
-        }
+  watch: {
+    'shared.typeCheck'(enableTypeCheck) {
+      // Update initialCode to avoid code changed when switching editor
+      this.initialCode = store.sourceCode;
+      this.updateFullCode();
+    },
+    currentTab(tab) {
+      this.updateTabContent(tab);
+    },
+    'shared.runHash'() {
+      this.updateTabContent(this.currentTab);
+    },
+    fullCodeConfig: {
+      deep: true,
+      handler() {
+        this.updateFullCode();
+      }
     }
-}
+  }
+};
 </script>
 
 <style lang="scss">
-
 @import '../style/color.scss';
 
 $code-info-height: 25px;
@@ -239,215 +267,215 @@ $pd-basic: 10px;
 $handler-width: 5px;
 
 #main-container {
-    .handler {
-        position: absolute;
-        left: 50%;
-
-        top: 0;
-        bottom: 0;
-        width: $handler-width;
-
-        cursor: col-resize;
-        z-index: 100;
-        background-color: transparent;
-        border-left: 1px solid #ececec;
-        // border-right: 1px solid $clr-border;
-    }
+  .handler {
+    position: absolute;
+    left: 50%;
 
+    top: 0;
+    bottom: 0;
+    width: $handler-width;
+
+    cursor: col-resize;
+    z-index: 100;
+    background-color: transparent;
+    border-left: 1px solid #ececec;
+    // border-right: 1px solid $clr-border;
+  }
 }
 
 #editor-left-container {
-    position: absolute;
-    left: 0;
-    bottom: 0;
-    top: 0;
+  position: absolute;
+  left: 0;
+  bottom: 0;
+  top: 0;
 
-    width: 50%;
+  width: 50%;
 
-    .el-tab-pane {
-        height: 100%;
-
-        .el-container {
-            width: 100%;
-            height: 100%;
-        }
-
-        .el-header {
-            height: $control-panel-height!important;
-            position: relative;
-            z-index: 10;
-            padding: 0;
-        }
-        .el-main {
-            padding: 0;
-            position: relative;
-
-            ::-webkit-scrollbar {
-                height:8px;
-                width:8px;
-                transition:all 0.3s ease-in-out;
-                border-radius:2px;
-            }
-
-            ::-webkit-scrollbar-button {
-                display:none;
-            }
-
-            ::-webkit-scrollbar-thumb {
-                width:8px;
-                min-height:15px;
-                background:rgba(50, 50, 50, 0.6) !important;
-                transition:all 0.3s ease-in-out;border-radius:2px;
-            }
-
-            ::-webkit-scrollbar-thumb:hover {
-                background:rgba(0, 0, 0, 0.5) !important;
-            }
-        }
-    }
+  .el-tab-pane {
+    height: 100%;
 
-    .el-tabs {
-        box-shadow: none;
+    .el-container {
+      width: 100%;
+      height: 100%;
     }
 
-    .el-tabs--border-card>.el-tabs__header {
-        border-bottom: none;
+    .el-header {
+      height: $control-panel-height !important;
+      position: relative;
+      z-index: 10;
+      padding: 0;
     }
-
-    .el-tabs__content {
-        position: absolute;
-        top: 34px;
-        left: 0;
-        right: 0;
-        bottom: 0;
-        padding: 0;
+    .el-main {
+      padding: 0;
+      position: relative;
+
+      ::-webkit-scrollbar {
+        height: 8px;
+        width: 8px;
+        transition: all 0.3s ease-in-out;
+        border-radius: 2px;
+      }
+
+      ::-webkit-scrollbar-button {
+        display: none;
+      }
+
+      ::-webkit-scrollbar-thumb {
+        width: 8px;
+        min-height: 15px;
+        background: rgba(50, 50, 50, 0.6) !important;
+        transition: all 0.3s ease-in-out;
+        border-radius: 2px;
+      }
+
+      ::-webkit-scrollbar-thumb:hover {
+        background: rgba(0, 0, 0, 0.5) !important;
+      }
     }
+  }
 
-    .el-tabs__item {
-        height: 34px;
-        line-height: 34px;
-    }
-}
+  .el-tabs {
+    box-shadow: none;
+  }
 
-#editor-control-panel, #full-code-generate-config {
-    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
-}
+  .el-tabs--border-card > .el-tabs__header {
+    border-bottom: none;
+  }
 
-#option-outline {
-    // height: 100%;
-    // Fix safari
+  .el-tabs__content {
     position: absolute;
+    top: 34px;
     left: 0;
-    top: 0;
-    bottom: 0;
     right: 0;
+    bottom: 0;
+    padding: 0;
+  }
 
-    font-size: 13px;
-
-    font-family: 'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
+  .el-tabs__item {
+    height: 34px;
+    line-height: 34px;
+  }
 }
 
+#editor-control-panel,
 #full-code-generate-config {
-    .full-code-generate-config-label {
-        height: $control-panel-height;
-        line-height: $control-panel-height;
-        vertical-align: middle;
-        margin: 0 0 0 20px;
-    }
+  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+}
 
-    .el-switch {
-        margin-right: 10px;
-    }
+#option-outline {
+  // height: 100%;
+  // Fix safari
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  right: 0;
+
+  font-size: 13px;
+
+  font-family: 'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas',
+    monospace;
+}
 
-    .el-switch__label {
-        margin-left: 8px;
-        margin-top: -2px;
-    }
-    .el-switch__label * {
-        font-size: 12px;
-    }
+#full-code-generate-config {
+  .full-code-generate-config-label {
+    height: $control-panel-height;
+    line-height: $control-panel-height;
+    vertical-align: middle;
+    margin: 0 0 0 20px;
+  }
+
+  .el-switch {
+    margin-right: 10px;
+  }
+
+  .el-switch__label {
+    margin-left: 8px;
+    margin-top: -2px;
+  }
+  .el-switch__label * {
+    font-size: 12px;
+  }
 }
 
 #editor-control-panel {
-    .setting-panel {
-        display: inline-block;
+  .setting-panel {
+    display: inline-block;
 
-        .btn-group + .btn-group {
-            margin-left: $pd-basic;
-        }
+    .btn-group + .btn-group {
+      margin-left: $pd-basic;
     }
+  }
 
-    .editor-controls  {
-        float: right;
+  .editor-controls {
+    float: right;
 
-        .el-switch__label {
-            margin-top: -3px;
-        }
-        .el-switch__label * {
-            font-size: 12px;
-        }
-
-        .btn {
-            color: #FFF;
-            border-radius: 0;
-            background-color: #409eff;
-            margin-left: $pd-basic;
-            border: none;
-            height: 30px;
-            width: 50px;
-        }
-        .btn:hover {
-            background-color: lighten($color: #409eff, $amount: 5);
-        }
+    .el-switch__label {
+      margin-top: -3px;
     }
-}
-
-#code-info {
-    position: absolute;
-    bottom: 0;
-    overflow: hidden;
-
-    height: $control-panel-height;
-    line-height: $control-panel-height;
-    padding: 0px 10px;
-
-    // border-top: 1px solid $clr-border;
-    font-size: 0.9rem;
-
-    .code-info-time {
-        color: $clr-text;
-        display: inline-block;
-        margin-right: 10px;
-        font-size: 12px;
+    .el-switch__label * {
+      font-size: 12px;
     }
 
-    .code-info-type-info {
-        color: $clr-text;
-        font-size: 12px;
+    .btn {
+      color: #fff;
+      border-radius: 0;
+      background-color: #409eff;
+      margin-left: $pd-basic;
+      border: none;
+      height: 30px;
+      width: 50px;
     }
-
-    .code-info-type-warn {
-        color: $clr-warn;
+    .btn:hover {
+      background-color: lighten($color: #409eff, $amount: 5);
     }
+  }
+}
 
-    .code-info-type-error {
-        color: $clr-error;
-    }
+#code-info {
+  position: absolute;
+  bottom: 0;
+  overflow: hidden;
+
+  height: $control-panel-height;
+  line-height: $control-panel-height;
+  padding: 0px 10px;
+
+  // border-top: 1px solid $clr-border;
+  font-size: 0.9rem;
+
+  .code-info-time {
+    color: $clr-text;
+    display: inline-block;
+    margin-right: 10px;
+    font-size: 12px;
+  }
+
+  .code-info-type-info {
+    color: $clr-text;
+    font-size: 12px;
+  }
+
+  .code-info-type-warn {
+    color: $clr-warn;
+  }
+
+  .code-info-type-error {
+    color: $clr-error;
+  }
 }
 
 .right-container {
-    position: absolute;
-    right: 0;
+  position: absolute;
+  right: 0;
 
-    width: 50%;
-    height: 100%;
-    padding: 0;
-    padding-left: $handler-width;
-    border: none;
-    z-index: 30;
+  width: 50%;
+  height: 100%;
+  padding: 0;
+  padding-left: $handler-width;
+  border: none;
+  z-index: 30;
 
-    background: $clr-bg;
+  background: $clr-bg;
 }
-
-
-</style>
\ No newline at end of file
+</style>
diff --git a/src/editor/FullCodePreview.vue b/src/editor/FullCodePreview.vue
index e2f1c3f..19fce17 100644
--- a/src/editor/FullCodePreview.vue
+++ b/src/editor/FullCodePreview.vue
@@ -1,94 +1,91 @@
 <template>
-<div class="full-code-preview" v-loading="loading"></div>
+  <div class="full-code-preview" v-loading="loading"></div>
 </template>
 
 <script>
-
-import {loadScriptsAsync} from '../common/helper';
-import {store} from '../common/store';
-import {SCRIPT_URLS} from '../common/config';
+import { loadScriptsAsync } from '../common/helper';
+import { store } from '../common/store';
+import { SCRIPT_URLS } from '../common/config';
 
 function ensureACE() {
-    if (typeof ace === 'undefined') {
-        return loadScriptsAsync([
-            SCRIPT_URLS.aceDir + '/ace.js'
-        ]);
-    }
-    return Promise.resolve();
+  if (typeof ace === 'undefined') {
+    return loadScriptsAsync([SCRIPT_URLS.aceDir + '/ace.js']);
+  }
+  return Promise.resolve();
 }
 
 export default {
+  props: ['code'],
 
-    props: ['code'],
-
-    data() {
-        return {
-            shared: store,
-            loading: false
-        }
-    },
+  data() {
+    return {
+      shared: store,
+      loading: false
+    };
+  },
 
-    mounted() {
-        this.loading = true;
-        ensureACE().then(() => {
-            this.loading = false;
-            const editor = ace.edit(this.$el);
-            editor.getSession().setMode('ace/mode/javascript');
-            // https://stackoverflow.com/questions/32806060/is-there-a-programmatic-way-to-hide-the-cursor-in-ace-editor
-            editor.setOptions({
-                readOnly: true,
-                showLineNumbers: false,
-                showFoldWidgets: false,
-                highlightActiveLine: false,
-                highlightGutterLine: false
-            });
-            // editor.renderer.setShowGutter(false);
-            editor.renderer.$cursorLayer.element.style.display = 'none';
+  mounted() {
+    this.loading = true;
+    ensureACE().then(() => {
+      this.loading = false;
+      const editor = ace.edit(this.$el);
+      editor.getSession().setMode('ace/mode/javascript');
+      // https://stackoverflow.com/questions/32806060/is-there-a-programmatic-way-to-hide-the-cursor-in-ace-editor
+      editor.setOptions({
+        readOnly: true,
+        showLineNumbers: false,
+        showFoldWidgets: false,
+        highlightActiveLine: false,
+        highlightGutterLine: false
+      });
+      // editor.renderer.setShowGutter(false);
+      editor.renderer.$cursorLayer.element.style.display = 'none';
 
-            this._editor = editor;
+      this._editor = editor;
 
-            this.setCode(this.code);
+      this.setCode(this.code);
+    });
+  },
 
+  methods: {
+    setCode(code) {
+      if (this._editor) {
+        this._editor.setValue(code);
+        this._editor.selection.setSelectionRange({
+          start: {
+            row: 1,
+            column: 4
+          },
+          end: {
+            row: 1,
+            column: 4
+          }
         });
-    },
-
-    methods: {
-        setCode(code) {
-            if (this._editor) {
-                this._editor.setValue(code);
-                this._editor.selection.setSelectionRange({
-                    start: {
-                        row:1,
-                        column: 4
-                    }, end: {
-                        row:1,
-                        column: 4
-                    }
-                });
-            }
-        }
-    },
+      }
+    }
+  },
 
-    watch: {
-        code(newVal) {
-            this.setCode(newVal);
-        }
+  watch: {
+    code(newVal) {
+      this.setCode(newVal);
     }
-}
+  }
+};
 </script>
 
 <style lang="scss">
 .full-code-preview {
-    font-family: 'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
-    font-size: 12px;
-    line-height: 18px;
-    // height: 100%;
+  font-family: 'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas',
+    monospace;
+  font-size: 12px;
+  line-height: 18px;
+  // height: 100%;
 
-    // Fix safari
-    position: absolute;
-    left: 0;
-    top: 0;
-    bottom: 0;
-    right: 0;
+  // Fix safari
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  right: 0;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/editor/Preview.vue b/src/editor/Preview.vue
index 7903283..3d27e1d 100644
--- a/src/editor/Preview.vue
+++ b/src/editor/Preview.vue
@@ -1,424 +1,446 @@
 <template>
-<div :class="[(inEditor && !shared.isMobile) ? '' : 'full']">
-    <div v-loading="loading"
-        class="right-panel"
-        id="chart-panel"
-        :style="{background: backgroundColor}"
+  <div :class="[inEditor && !shared.isMobile ? '' : 'full']">
+    <div
+      v-loading="loading"
+      class="right-panel"
+      id="chart-panel"
+      :style="{ background: backgroundColor }"
     >
-        <div class="chart-container"></div>
+      <div class="chart-container"></div>
     </div>
     <div id="tool-panel">
-        <div class="left-panel">
-            <el-switch
-                class="dark-mode"
-                v-model="shared.darkMode"
-                active-color="#181432"
-                :active-text="$t('editor.darkMode')"
-                :inactive-text="''">
-            </el-switch>
-            <el-switch
-                v-if="!isGL"
-
-                class="enable-decal"
-                v-model="shared.enableDecal"
-                :active-text="$t('editor.enableDecal')"
-                :inactive-text="''">
-            </el-switch>
-
-            <el-popover
-                placement="bottom"
-                width="450"
-                trigger="click"
-                style="margin-top:3px;"
-
-                v-if="!isGL"
-            >
-                <div class="render-config-container">
-                    <el-row :gutter="2" type="flex" align="middle">
-                        <el-col :span="12">
-                            <label class="tool-label">{{ $t('editor.renderer') }}</label>
-                            <el-radio-group v-model="shared.renderer" size="mini" style="text-transform: uppercase">
-                                <el-radio-button label="svg"></el-radio-button>
-                                <el-radio-button label="canvas"></el-radio-button>
-                            </el-radio-group>
-                        </el-col>
-                        <el-col :span="12">
-                            <el-switch
-                                v-if="shared.renderer==='canvas'"
-                                v-model="shared.useDirtyRect"
-                                :active-text="$t('editor.useDirtyRect')"
-                                :inactive-text="''">
-                            </el-switch>
-                        </el-col>
-                    </el-row>
-                </div>
-                <span class="render-config-trigger" slot="reference"><i class="el-icon-setting el-icon--left"></i>{{$t('editor.renderCfgTitle')}}</span>
-            </el-popover>
-        </div>
-        <template v-if="inEditor">
-            <button v-if="!shared.isMobile" class="download btn btn-sm" @click="downloadExample">{{ $t('editor.download') }}</button>
-            <a class="screenshot" @click="screenshot" target="_blank"><i class="el-icon-camera-solid"></i></a>
-        </template>
-        <a :href="editLink" target="_blank" v-else class="edit btn btn-sm">{{ $t('editor.edit') }}</a>
+      <div class="left-panel">
+        <el-switch
+          class="dark-mode"
+          v-model="shared.darkMode"
+          active-color="#181432"
+          :active-text="$t('editor.darkMode')"
+          :inactive-text="''"
+        >
+        </el-switch>
+        <el-switch
+          v-if="!isGL"
+          class="enable-decal"
+          v-model="shared.enableDecal"
+          :active-text="$t('editor.enableDecal')"
+          :inactive-text="''"
+        >
+        </el-switch>
+
+        <el-popover
+          placement="bottom"
+          width="450"
+          trigger="click"
+          style="margin-top: 3px"
+          v-if="!isGL"
+        >
+          <div class="render-config-container">
+            <el-row :gutter="2" type="flex" align="middle">
+              <el-col :span="12">
+                <label class="tool-label">{{ $t('editor.renderer') }}</label>
+                <el-radio-group
+                  v-model="shared.renderer"
+                  size="mini"
+                  style="text-transform: uppercase"
+                >
+                  <el-radio-button label="svg"></el-radio-button>
+                  <el-radio-button label="canvas"></el-radio-button>
+                </el-radio-group>
+              </el-col>
+              <el-col :span="12">
+                <el-switch
+                  v-if="shared.renderer === 'canvas'"
+                  v-model="shared.useDirtyRect"
+                  :active-text="$t('editor.useDirtyRect')"
+                  :inactive-text="''"
+                >
+                </el-switch>
+              </el-col>
+            </el-row>
+          </div>
+          <span class="render-config-trigger" slot="reference"
+            ><i class="el-icon-setting el-icon--left"></i
+            >{{ $t('editor.renderCfgTitle') }}</span
+          >
+        </el-popover>
+      </div>
+      <template v-if="inEditor">
+        <button
+          v-if="!shared.isMobile"
+          class="download btn btn-sm"
+          @click="downloadExample"
+        >
+          {{ $t('editor.download') }}
+        </button>
+        <a class="screenshot" @click="screenshot" target="_blank"
+          ><i class="el-icon-camera-solid"></i
+        ></a>
+      </template>
+      <a :href="editLink" target="_blank" v-else class="edit btn btn-sm">{{
+        $t('editor.edit')
+      }}</a>
     </div>
-</div>
+  </div>
 </template>
 
 <script>
-
-import {store, updateRunHash} from '../common/store';
-import {SCRIPT_URLS, URL_PARAMS} from '../common/config';
-import {loadScriptsAsync} from '../common/helper';
-import {createSandbox} from './sandbox';
+import { store, updateRunHash } from '../common/store';
+import { SCRIPT_URLS, URL_PARAMS } from '../common/config';
+import { loadScriptsAsync } from '../common/helper';
+import { createSandbox } from './sandbox';
 import debounce from 'lodash/debounce';
 import { addListener, removeListener } from 'resize-detector';
 import CHART_LIST from '../data/chart-list-data';
 import CHART_LIST_GL from '../data/chart-list-data-gl';
-import {download} from './downloadExample';
+import { download } from './downloadExample';
 
 function findExample(item) {
-    return URL_PARAMS.c === item.id;
+  return URL_PARAMS.c === item.id;
 }
 const example = CHART_LIST.concat(CHART_LIST_GL).find(findExample);
 const isGL = CHART_LIST_GL.find(findExample);
 
 function addDecalIfNecessary(option) {
-    if (store.enableDecal) {
-        option.aria = option.aria || {};
-        option.aria.decal = option.aria.decal || {};
-        option.aria.decal.show = true;
-        option.aria.show = option.aria.enabled = true;
-    }
+  if (store.enableDecal) {
+    option.aria = option.aria || {};
+    option.aria.decal = option.aria.decal || {};
+    option.aria.decal.show = true;
+    option.aria.show = option.aria.enabled = true;
+  }
 }
 
 export function ensureECharts() {
-    if (typeof echarts === 'undefined') {
-
-        const hasBmap = example && example.tags.indexOf('bmap') >= 0;
-
-        // Code from https://api.map.baidu.com/api?v=2.0&ak=KOmVjPVUAey1G2E8zNhPiuQ6QiEmAwZu
-        if (hasBmap) {
-            window.HOST_TYPE = "2";
-            window.BMap_loadScriptTime = (new Date).getTime();
-        }
+  if (typeof echarts === 'undefined') {
+    const hasBmap = example && example.tags.indexOf('bmap') >= 0;
 
-        return loadScriptsAsync([
-            SCRIPT_URLS.datGUIMinJS,
-            'local' in URL_PARAMS
-                ? SCRIPT_URLS.localEChartsMinJS : SCRIPT_URLS.echartsMinJS,
-            SCRIPT_URLS.echartsDir + '/dist/extension/dataTool.js',
-            'https://cdn.jsdelivr.net/npm/echarts@4.9.0/map/js/world.js',
-            SCRIPT_URLS.echartsStatMinJS,
-            ...URL_PARAMS.gl ? [SCRIPT_URLS.echartsGLMinJS] : [],
-            ...hasBmap ? [
-                'https://api.map.baidu.com/getscript?v=3.0&ak=KOmVjPVUAey1G2E8zNhPiuQ6QiEmAwZu&services=&t=20200327103013',
-                SCRIPT_URLS.echartsDir + '/dist/extension/bmap.js'
-            ] : []
-        ]).then(() => {
-            echarts.registerPreprocessor(addDecalIfNecessary)
-        });
+    // Code from https://api.map.baidu.com/api?v=2.0&ak=KOmVjPVUAey1G2E8zNhPiuQ6QiEmAwZu
+    if (hasBmap) {
+      window.HOST_TYPE = '2';
+      window.BMap_loadScriptTime = new Date().getTime();
     }
-    return Promise.resolve();
-}
 
+    return loadScriptsAsync([
+      SCRIPT_URLS.datGUIMinJS,
+      'local' in URL_PARAMS
+        ? SCRIPT_URLS.localEChartsMinJS
+        : SCRIPT_URLS.echartsMinJS,
+      SCRIPT_URLS.echartsDir + '/dist/extension/dataTool.js',
+      'https://cdn.jsdelivr.net/npm/echarts@4.9.0/map/js/world.js',
+      SCRIPT_URLS.echartsStatMinJS,
+      ...(URL_PARAMS.gl ? [SCRIPT_URLS.echartsGLMinJS] : []),
+      ...(hasBmap
+        ? [
+            'https://api.map.baidu.com/getscript?v=3.0&ak=KOmVjPVUAey1G2E8zNhPiuQ6QiEmAwZu&services=&t=20200327103013',
+            SCRIPT_URLS.echartsDir + '/dist/extension/bmap.js'
+          ]
+        : [])
+    ]).then(() => {
+      echarts.registerPreprocessor(addDecalIfNecessary);
+    });
+  }
+  return Promise.resolve();
+}
 
 function log(text, type) {
-    if (type !== 'warn' && type !== 'error') {
-        type = 'info';
-    }
-    store.editorStatus.message = text;
-    store.editorStatus.type = type;
+  if (type !== 'warn' && type !== 'error') {
+    type = 'info';
+  }
+  store.editorStatus.message = text;
+  store.editorStatus.type = type;
 }
 
-
 function run() {
-
-    if (typeof echarts === 'undefined') {
-        return;
-    }
-    if (!this.sandbox) {
-        this.sandbox = createSandbox((chart) => {
-            const option = chart.getOption();
-            if (typeof option.backgroundColor === 'string' && option.backgroundColor !== 'transparent') {
-                this.backgroundColor = option.backgroundColor;
-            }
-            else {
-                this.backgroundColor = '#fff';
-            }
+  if (typeof echarts === 'undefined') {
+    return;
+  }
+  if (!this.sandbox) {
+    this.sandbox = createSandbox((chart) => {
+      const option = chart.getOption();
+      if (
+        typeof option.backgroundColor === 'string' &&
+        option.backgroundColor !== 'transparent'
+      ) {
+        this.backgroundColor = option.backgroundColor;
+      } else {
+        this.backgroundColor = '#fff';
+      }
+    });
+  }
+
+  try {
+    const updateTime = this.sandbox.run(
+      this.$el.querySelector('.chart-container'),
+      store
+    );
+
+    log(this.$t('editor.chartOK') + updateTime + 'ms');
+
+    // Find the appropriate throttle time
+    const debounceTime = 500;
+    const debounceTimeQuantities = [0, 500, 2000, 5000, 10000];
+    for (let i = debounceTimeQuantities.length - 1; i >= 0; i--) {
+      const quantity = debounceTimeQuantities[i];
+      const preferredDebounceTime = debounceTimeQuantities[i + 1] || 1000000;
+      if (
+        updateTime >= quantity &&
+        this.debouncedTime !== preferredDebounceTime
+      ) {
+        this.debouncedRun = debounce(run, preferredDebounceTime, {
+          trailing: true
         });
+        this.debouncedTime = preferredDebounceTime;
+        break;
+      }
     }
 
-    try {
-        const updateTime = this.sandbox.run(this.$el.querySelector('.chart-container'), store);
-
-        log(this.$t('editor.chartOK') + updateTime + 'ms');
-
-        // Find the appropriate throttle time
-        const debounceTime = 500;
-        const debounceTimeQuantities = [0, 500, 2000, 5000, 10000];
-        for (let i = debounceTimeQuantities.length - 1; i >= 0; i--) {
-            const quantity = debounceTimeQuantities[i];
-            const preferredDebounceTime = debounceTimeQuantities[i + 1] || 1000000;
-            if (updateTime >= quantity && this.debouncedTime !== preferredDebounceTime) {
-                this.debouncedRun = debounce(run, preferredDebounceTime, {
-                    trailing: true
-                });
-                this.debouncedTime = preferredDebounceTime;
-                break;
-            }
-        }
-
-        // Update run hash to let others known chart has been changed.
-        updateRunHash();
-
-    }
-    catch (e) {
-        log(this.$t('editor.errorInEditor'), 'error');
-        console.error(e);
-    }
+    // Update run hash to let others known chart has been changed.
+    updateRunHash();
+  } catch (e) {
+    log(this.$t('editor.errorInEditor'), 'error');
+    console.error(e);
+  }
 }
 
-
 export default {
-
-    props: ['inEditor'],
-
-    data() {
-        return {
-            shared: store,
-            debouncedTime: undefined,
-            backgroundColor: '',
-            autoRun: true,
-            loading: false,
-
-            isGL
+  props: ['inEditor'],
+
+  data() {
+    return {
+      shared: store,
+      debouncedTime: undefined,
+      backgroundColor: '',
+      autoRun: true,
+      loading: false,
+
+      isGL
+    };
+  },
+
+  mounted() {
+    this.loading = true;
+    ensureECharts().then(() => {
+      this.loading = false;
+      if (store.runCode) {
+        this.run();
+      }
+    });
+
+    addListener(this.$el, () => {
+      if (this.sandbox) {
+        this.sandbox.resize();
+      }
+    });
+  },
+
+  computed: {
+    editLink() {
+      const params = ['c=' + URL_PARAMS.c];
+      if (URL_PARAMS.theme) {
+        params.push(['theme=' + URL_PARAMS.theme]);
+      }
+      if (URL_PARAMS.gl) {
+        params.push(['gl=' + URL_PARAMS.gl]);
+      }
+      return './editor.html?' + params.join('&');
+    }
+  },
+
+  watch: {
+    'shared.runCode'(val) {
+      if (this.autoRun || !this.sandbox) {
+        if (!this.debouncedRun) {
+          // First run
+          this.run();
+        } else {
+          this.debouncedRun();
         }
+      }
     },
-
-    mounted() {
-        this.loading = true;
-        ensureECharts().then(() => {
-            this.loading = false;
-            if (store.runCode) {
-                this.run();
-            }
-        });
-
-        addListener(this.$el, () => {
-            if (this.sandbox) {
-                this.sandbox.resize();
-            }
-        })
+    'shared.renderer'() {
+      this.refreshAll();
     },
-
-    computed: {
-        editLink() {
-            const params = ['c=' + URL_PARAMS.c];
-            if (URL_PARAMS.theme) {
-                params.push(['theme=' + URL_PARAMS.theme]);
-            }
-            if (URL_PARAMS.gl) {
-                params.push(['gl=' + URL_PARAMS.gl]);
-            }
-            return './editor.html?' + params.join('&');
-        }
+    'shared.darkMode'() {
+      this.refreshAll();
     },
-
-    watch: {
-        'shared.runCode'(val) {
-            if (this.autoRun || !this.sandbox) {
-                if (!this.debouncedRun) {
-                    // First run
-                    this.run();
-                }
-                else {
-                    this.debouncedRun();
-                }
-            }
-        },
-        'shared.renderer'() {
-            this.refreshAll();
-        },
-        'shared.darkMode'() {
-            this.refreshAll();
-        },
-        'shared.enableDecal'() {
-            this.refreshAll();
-        },
-        'shared.useDirtyRect'() {
-            this.refreshAll();
-        }
+    'shared.enableDecal'() {
+      this.refreshAll();
     },
-
-    methods: {
-        run,
-        // debouncedRun will be created at first run
-        // debouncedRun: null,
-        refreshAll() {
-            this.dispose();
-            this.run();
-        },
-        dispose() {
-            if (this.sandbox) {
-                this.sandbox.dispose();
-            }
-        },
-        downloadExample() {
-            download();
-        },
-        screenshot() {
-            if (this.sandbox) {
-                const url = this.sandbox.getDataURL();
-                const $a = document.createElement('a');
-                $a.download = URL_PARAMS.c + '.' + (store.renderer === 'svg' ? 'svg' : 'png');
-                $a.target = '_blank';
-                $a.href = url;
-                const evt = new MouseEvent('click', {
-                    bubbles: true,
-                    cancelable: false
-                });
-                $a.dispatchEvent(evt);
-            }
-        },
-        getOption() {
-            return this.sandbox && this.sandbox.getOption();
-        }
-        // hasEditorError() {
-        //     const annotations = this.editor.getSession().getAnnotations();
-        //     for (let aid = 0, alen = annotations.length; aid < alen; ++aid) {
-        //         if (annotations[aid].type === 'error') {
-        //             return true;
-        //         }
-        //     }
-        //     return false;
-        // }
+    'shared.useDirtyRect'() {
+      this.refreshAll();
     }
-}
+  },
+
+  methods: {
+    run,
+    // debouncedRun will be created at first run
+    // debouncedRun: null,
+    refreshAll() {
+      this.dispose();
+      this.run();
+    },
+    dispose() {
+      if (this.sandbox) {
+        this.sandbox.dispose();
+      }
+    },
+    downloadExample() {
+      download();
+    },
+    screenshot() {
+      if (this.sandbox) {
+        const url = this.sandbox.getDataURL();
+        const $a = document.createElement('a');
+        $a.download =
+          URL_PARAMS.c + '.' + (store.renderer === 'svg' ? 'svg' : 'png');
+        $a.target = '_blank';
+        $a.href = url;
+        const evt = new MouseEvent('click', {
+          bubbles: true,
+          cancelable: false
+        });
+        $a.dispatchEvent(evt);
+      }
+    },
+    getOption() {
+      return this.sandbox && this.sandbox.getOption();
+    }
+    // hasEditorError() {
+    //     const annotations = this.editor.getSession().getAnnotations();
+    //     for (let aid = 0, alen = annotations.length; aid < alen; ++aid) {
+    //         if (annotations[aid].type === 'error') {
+    //             return true;
+    //         }
+    //     }
+    //     return false;
+    // }
+  }
+};
 </script>
 
 <style lang="scss">
-
 #chart-panel {
-    position: absolute;
-    // top: $control-panel-height;
-    top: 42px;
-    right: 15px;
-    bottom: 15px;
-    left: 15px;
-    box-sizing: border-box;
-    box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 20px;
-    border-radius: 5px;
-    background: #fff;
-    overflow: hidden;
-
-    padding: 10px;
-
-    .ec-debug-dirty-rect-container {
-        left: 10px!important;
-        top: 10px!important;
-        right: 10px!important;
-        bottom: 10px!important;
-
-        .ec-debug-dirty-rect {
-            background-color: rgba(255, 0, 0, 0.2)!important;
-            border: 1px solid red!important;
-        }
+  position: absolute;
+  // top: $control-panel-height;
+  top: 42px;
+  right: 15px;
+  bottom: 15px;
+  left: 15px;
+  box-sizing: border-box;
+  box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 20px;
+  border-radius: 5px;
+  background: #fff;
+  overflow: hidden;
+
+  padding: 10px;
+
+  .ec-debug-dirty-rect-container {
+    left: 10px !important;
+    top: 10px !important;
+    right: 10px !important;
+    bottom: 10px !important;
+
+    .ec-debug-dirty-rect {
+      background-color: rgba(255, 0, 0, 0.2) !important;
+      border: 1px solid red !important;
     }
+  }
 
-    .chart-container {
-        position: relative;
-        height: 100%;
-    }
+  .chart-container {
+    position: relative;
+    height: 100%;
+  }
 }
 
 .render-config-container {
-    .el-radio-group {
-        label {
-            margin-bottom: 0;
-        }
+  .el-radio-group {
+    label {
+      margin-bottom: 0;
     }
+  }
 }
 
 #tool-panel {
-    position: absolute;
-    top: 0;
-    right: 0;
-    left: 0;
-    padding-top: 5px;
-    padding-left: 15px;
-
-    // .el-switch__label * {
-    //     font-size: 12px;
-    // }
-
-    .render-config-trigger {
-        margin-left: 10px;
-        cursor: pointer;
-        font-weight: 500;
-        // font-size: 12px;
-    }
-
-    label {
-        margin-bottom: 0;
-    }
-
-    .left-panel {
-        float: left;
-    }
-
-    .left-panel>* {
-        vertical-align: middle;
-        display: inline-block;
-    }
-
-    .tool-label {
-        font-weight: bold;
-        text-transform: uppercase;
-        margin-left: 20px;
-    }
-
-    .screenshot, .download, .edit {
-        float: right;
-        margin-right: 15px;
-        cursor: pointer;
-    }
-    .screenshot {
-        font-size: 22px;
-        margin-right: 10px;
-    }
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  padding-top: 5px;
+  padding-left: 15px;
+
+  // .el-switch__label * {
+  //     font-size: 12px;
+  // }
+
+  .render-config-trigger {
+    margin-left: 10px;
+    cursor: pointer;
+    font-weight: 500;
+    // font-size: 12px;
+  }
+
+  label {
+    margin-bottom: 0;
+  }
+
+  .left-panel {
+    float: left;
+  }
+
+  .left-panel > * {
+    vertical-align: middle;
+    display: inline-block;
+  }
+
+  .tool-label {
+    font-weight: bold;
+    text-transform: uppercase;
+    margin-left: 20px;
+  }
+
+  .screenshot,
+  .download,
+  .edit {
+    float: right;
+    margin-right: 15px;
+    cursor: pointer;
+  }
+  .screenshot {
+    font-size: 22px;
+    margin-right: 10px;
+  }
 }
 
 .full {
-    #chart-panel {
-        top: 40px;
-        right: 5px;
-        bottom: 5px;
-        left: 5px;
-        box-shadow: rgba(10, 9, 9, 0.1) 0px 0px 5px;
-    }
-    #tool-panel {
-        padding-left: 5px;
-        .download, .edit {
-            margin-right: 5px;
-        }
+  #chart-panel {
+    top: 40px;
+    right: 5px;
+    bottom: 5px;
+    left: 5px;
+    box-shadow: rgba(10, 9, 9, 0.1) 0px 0px 5px;
+  }
+  #tool-panel {
+    padding-left: 5px;
+    .download,
+    .edit {
+      margin-right: 5px;
     }
+  }
 }
 
 .dg.main * {
-    box-sizing: content-box;
+  box-sizing: content-box;
 }
 .dg.main input {
-    line-height: normal;
+  line-height: normal;
 }
 
 .dg.main.a {
-    overflow-x: visible;
+  overflow-x: visible;
 }
 
 .dg.main .c {
-    select {
-        color: #000;
-    }
+  select {
+    color: #000;
+  }
 }
-
-</style>
\ No newline at end of file
+</style>
diff --git a/src/editor/View.vue b/src/editor/View.vue
index f6abe53..a8b1ca1 100644
--- a/src/editor/View.vue
+++ b/src/editor/View.vue
@@ -1,25 +1,22 @@
 <template>
-<preview></Preview>
+  <preview></preview>
 </template>
 
 <script>
-
 import Preview from './Preview.vue';
-import {store, loadExampleCode, parseSourceCode} from '../common/store';
+import { store, loadExampleCode, parseSourceCode } from '../common/store';
 
 export default {
-    components: {
-        Preview
-    },
+  components: {
+    Preview
+  },
 
-    mounted() {
-        loadExampleCode().then(code => {
-            store.runCode = parseSourceCode(code);
-        });
-    }
-}
+  mounted() {
+    loadExampleCode().then((code) => {
+      store.runCode = parseSourceCode(code);
+    });
+  }
+};
 </script>
 
-<style lang="scss">
-
-</style>
\ No newline at end of file
+<style lang="scss"></style>
diff --git a/src/editor/downloadExample.js b/src/editor/downloadExample.js
index b9f1a48..d4235df 100644
--- a/src/editor/downloadExample.js
+++ b/src/editor/downloadExample.js
@@ -1,12 +1,12 @@
-import {store} from '../common/store';
-import {URL_PARAMS, SCRIPT_URLS} from '../common/config';
-import {downloadBlob} from '../common/helper';
+import { store } from '../common/store';
+import { URL_PARAMS, SCRIPT_URLS } from '../common/config';
+import { downloadBlob } from '../common/helper';
 
 const hasRootPath = store.sourceCode.indexOf('ROOT_PATH') >= 0;
 const rootPathCode = hasRootPath ? `var ROOT_PATH = '${store.cdnRoot}'` : '';
 
 export function download() {
-    const code = `<!--
+  const code = `<!--
     THIS EXAMPLE WAS DOWNLOADED FROM ${window.location.href}
 -->
 <!DOCTYPE html>
@@ -55,10 +55,10 @@ if (option && typeof option === 'object') {
     </body>
 </html>
     `;
-    const file = new Blob([code], {
-        type: 'text/html;charset=UTF-8',
-        encoding: 'UTF-8'
-    });
-    // download the blob
-    downloadBlob(file, URL_PARAMS.c + '.html');
-}
\ No newline at end of file
+  const file = new Blob([code], {
+    type: 'text/html;charset=UTF-8',
+    encoding: 'UTF-8'
+  });
+  // download the blob
+  downloadBlob(file, URL_PARAMS.c + '.html');
+}
diff --git a/src/editor/object-visualizer.css b/src/editor/object-visualizer.css
index 372a9fd..f135039 100644
--- a/src/editor/object-visualizer.css
+++ b/src/editor/object-visualizer.css
@@ -1,72 +1,72 @@
 .object-visualizer {
-    border-radius: 4px;
-    overflow-x: auto;
-    margin: 0;
-    padding: 10px;
-    /* font-family: Menlo; */
-    font-size: 0.6em;
-    line-height: 1.7;
-  }
+  border-radius: 4px;
+  overflow-x: auto;
+  margin: 0;
+  padding: 10px;
+  /* font-family: Menlo; */
+  font-size: 0.6em;
+  line-height: 1.7;
+}
 
-  .array > .value,
-  .object > .value {
-    display: flex;
-    flex-direction: column;
-    margin-left: 2em;
-  }
+.array > .value,
+.object > .value {
+  display: flex;
+  flex-direction: column;
+  margin-left: 2em;
+}
 
-  .key {
-    /* color: #4078f2; */
-    color: #111;
-    user-select: none;
-  }
+.key {
+  /* color: #4078f2; */
+  color: #111;
+  user-select: none;
+}
 
-  .string > .value {
-    color: #50a14f;
-  }
+.string > .value {
+  color: #50a14f;
+}
 
-  .boolean > .value,
-  .number > .value {
-    color: #d19a66;
-  }
+.boolean > .value,
+.number > .value {
+  color: #d19a66;
+}
 
-  .null > .value,
-  .undefined > .value {
-    color: hsl(0, 0%, 40%);
-  }
+.null > .value,
+.undefined > .value {
+  color: hsl(0, 0%, 40%);
+}
 
-  .separator {
-    cursor: pointer;
-    font-size: 0.8em;
-    user-select: none;
-    color: hsl(0, 0%, 30%);
-  }
+.separator {
+  cursor: pointer;
+  font-size: 0.8em;
+  user-select: none;
+  color: hsl(0, 0%, 30%);
+}
 
-  .indicator {
-    cursor: pointer;
-    font-size: 0.8em;
-    padding-right: 0.5em;
-    user-select: none;
-    vertical-align: text-bottom;
-    color: hsl(0, 0%, 30%);
-  }
+.indicator {
+  cursor: pointer;
+  font-size: 0.8em;
+  padding-right: 0.5em;
+  user-select: none;
+  vertical-align: text-bottom;
+  color: hsl(0, 0%, 30%);
+}
 
-  .array > .key,
-  .object > .key {
-    cursor: pointer;
-  }
+.array > .key,
+.object > .key {
+  cursor: pointer;
+}
 
-  .value > .array,
-  .value > .object {
-    position: relative;
-    left: -0.8em;
-  }
+.value > .array,
+.value > .object {
+  position: relative;
+  left: -0.8em;
+}
 
-  .count,
-  .preview,
-  .quotes {
-    cursor: pointer;
-    font-size: 0.8em;
-    user-select: none;
-    color: hsl(0, 0%, 30%);
-  }
+.count,
+.preview,
+.quotes {
+  cursor: pointer;
+  font-size: 0.8em;
+  user-select: none;
+  color: hsl(0, 0%, 30%);
+}
diff --git a/src/editor/sandbox.js b/src/editor/sandbox.js
index 4786d75..de496c5 100644
--- a/src/editor/sandbox.js
+++ b/src/editor/sandbox.js
@@ -1,190 +1,210 @@
 import showDebugDirtyRect from '../dep/showDebugDirtyRect';
 
 export function createSandbox(optionUpdated) {
-    let appEnv = {};
-    let gui;
-
-    let _intervalIdList = [];
-    let _timeoutIdList = [];
-
-    const _oldSetTimeout = window.setTimeout;
-    const _oldSetInterval = window.setInterval;
-
-    function setTimeout(func, delay) {
-        var id = _oldSetTimeout(func, delay);
-        _timeoutIdList.push(id);
-        return id;
+  let appEnv = {};
+  let gui;
+
+  let _intervalIdList = [];
+  let _timeoutIdList = [];
+
+  const _oldSetTimeout = window.setTimeout;
+  const _oldSetInterval = window.setInterval;
+
+  function setTimeout(func, delay) {
+    var id = _oldSetTimeout(func, delay);
+    _timeoutIdList.push(id);
+    return id;
+  }
+  function setInterval(func, gap) {
+    var id = _oldSetInterval(func, gap);
+    _intervalIdList.push(id);
+    return id;
+  }
+  function _clearTimeTickers() {
+    for (var i = 0; i < _intervalIdList.length; i++) {
+      clearInterval(_intervalIdList[i]);
+    }
+    for (var i = 0; i < _timeoutIdList.length; i++) {
+      clearTimeout(_timeoutIdList[i]);
+    }
+    _intervalIdList = [];
+    _timeoutIdList = [];
+  }
+  const _events = [];
+  function _wrapOnMethods(chart) {
+    const oldOn = chart.on;
+    const oldSetOption = chart.setOption;
+    chart.on = function (eventName) {
+      const res = oldOn.apply(chart, arguments);
+      _events.push(eventName);
+      return res;
     };
-    function setInterval(func, gap) {
-        var id = _oldSetInterval(func, gap);
-        _intervalIdList.push(id);
-        return id;
+    chart.setOption = function () {
+      const res = oldSetOption.apply(this, arguments);
+      optionUpdated && optionUpdated(chart);
+      return res;
     };
-    function _clearTimeTickers() {
-        for (var i = 0; i < _intervalIdList.length; i++) {
-            clearInterval(_intervalIdList[i]);
-        }
-        for (var i = 0; i < _timeoutIdList.length; i++) {
-            clearTimeout(_timeoutIdList[i]);
+  }
+
+  function _clearChartEvents(chart) {
+    _events.forEach(function (eventName) {
+      if (chart) {
+        chart.off(eventName);
+      }
+    });
+
+    _events.length = 0;
+  }
+
+  let chartInstance;
+
+  return {
+    resize() {
+      if (chartInstance) {
+        chartInstance.resize();
+      }
+    },
+
+    dispose() {
+      if (chartInstance) {
+        chartInstance.dispose();
+        chartInstance = null;
+      }
+    },
+
+    getDataURL() {
+      return chartInstance.getDataURL({
+        pixelRatio: 2,
+        excludeComponents: ['toolbox']
+      });
+    },
+
+    getOption() {
+      return chartInstance.getOption();
+    },
+
+    run(el, store) {
+      if (!chartInstance) {
+        chartInstance = echarts.init(el, store.darkMode ? 'dark' : '', {
+          renderer: store.renderer,
+          useDirtyRect: store.useDirtyRect
+        });
+        if (store.useDirtyRect && store.renderer === 'canvas') {
+          try {
+            showDebugDirtyRect(chartInstance.getZr(), {
+              autoHideDelay: 500
+            });
+          } catch (e) {
+            console.error(e);
+          }
         }
-        _intervalIdList = [];
-        _timeoutIdList = [];
-    }
-    const _events = [];
-    function _wrapOnMethods(chart) {
-        const oldOn = chart.on;
-        const oldSetOption = chart.setOption;
-        chart.on = function (eventName) {
-            const res = oldOn.apply(chart, arguments);
-            _events.push(eventName);
-            return res;
-        };
-        chart.setOption = function () {
-            const res = oldSetOption.apply(this, arguments);
-            optionUpdated && optionUpdated(chart);
-            return res;
-        };
-    }
-
-    function _clearChartEvents(chart) {
-        _events.forEach(function (eventName) {
-            if (chart) {
-                chart.off(eventName);
-            }
+        _wrapOnMethods(chartInstance);
+      }
+
+      // if (this.hasEditorError()) {
+      //     log(this.$t('editor.errorInEditor'), 'error');
+      //     return;
+      // }
+
+      // TODO Scope the variables in component.
+      _clearTimeTickers();
+      _clearChartEvents(chartInstance);
+      // Reset
+      appEnv.config = null;
+
+      // run the code
+
+      const compiledCode = store.runCode;
+
+      const func = new Function(
+        'myChart',
+        'app',
+        'setTimeout',
+        'setInterval',
+        'ROOT_PATH',
+        'var option;\n' + compiledCode + '\nreturn option;'
+      );
+      const option = func(
+        chartInstance,
+        appEnv,
+        setTimeout,
+        setInterval,
+        store.cdnRoot
+      );
+      let updateTime = 0;
+
+      if (option && typeof option === 'object') {
+        const startTime = +new Date();
+        chartInstance.setOption(option, true);
+        const endTime = +new Date();
+        updateTime = endTime - startTime;
+      }
+
+      if (gui) {
+        $(gui.domElement).remove();
+        gui.destroy();
+        gui = null;
+      }
+
+      if (appEnv.config) {
+        gui = new dat.GUI({
+          autoPlace: false
         });
-
-        _events.length = 0;
-    }
-
-    let chartInstance;
-
-    return {
-        resize() {
-            if (chartInstance) {
-                chartInstance.resize();
-            }
-        },
-
-        dispose() {
-            if (chartInstance) {
-                chartInstance.dispose();
-                chartInstance = null;
+        $(gui.domElement).css({
+          position: 'absolute',
+          right: 5,
+          top: 0,
+          zIndex: 1000
+        });
+        $('.right-container').append(gui.domElement);
+
+        var configParameters = appEnv.configParameters || {};
+        for (var name in appEnv.config) {
+          var value = appEnv.config[name];
+          if (name !== 'onChange' && name !== 'onFinishChange') {
+            var isColor = false;
+            // var value = obj;
+            var controller = null;
+            if (configParameters[name]) {
+              if (configParameters[name].options) {
+                controller = gui.add(
+                  appEnv.config,
+                  name,
+                  configParameters[name].options
+                );
+              } else if (configParameters[name].min != null) {
+                controller = gui.add(
+                  appEnv.config,
+                  name,
+                  configParameters[name].min,
+                  configParameters[name].max
+                );
+              }
             }
-        },
-
-        getDataURL() {
-            return chartInstance.getDataURL({
-                pixelRatio: 2,
-                excludeComponents: ['toolbox']
-            });
-        },
-
-        getOption() {
-            return chartInstance.getOption();
-        },
-
-        run(el, store) {
-
-            if (!chartInstance) {
-                chartInstance = echarts.init(el, store.darkMode ? 'dark' : '', {
-                    renderer: store.renderer,
-                    useDirtyRect: store.useDirtyRect
-                });
-                if (store.useDirtyRect && store.renderer === 'canvas') {
-                    try {
-                        showDebugDirtyRect(chartInstance.getZr(), {
-                            autoHideDelay: 500
-                        });
-                    }
-                    catch (e) {
-                        console.error(e);
-                    }
+            if (typeof obj === 'string') {
+              try {
+                var colorArr = echarts.color.parse(value);
+                isColor = !!colorArr;
+                if (isColor) {
+                  value = echarts.color.stringify(colorArr, 'rgba');
                 }
-                _wrapOnMethods(chartInstance);
-            }
-
-            // if (this.hasEditorError()) {
-            //     log(this.$t('editor.errorInEditor'), 'error');
-            //     return;
-            // }
-
-            // TODO Scope the variables in component.
-            _clearTimeTickers();
-            _clearChartEvents(chartInstance);
-            // Reset
-            appEnv.config = null;
-
-            // run the code
-
-            const compiledCode = store.runCode;
-
-            const func = new Function(
-                'myChart', 'app', 'setTimeout', 'setInterval', 'ROOT_PATH',
-                'var option;\n' + compiledCode + '\nreturn option;'
-            );
-            const option = func(chartInstance, appEnv, setTimeout, setInterval, store.cdnRoot);
-            let updateTime = 0;
-
-            if (option && typeof option === 'object') {
-                const startTime = +new Date();
-                chartInstance.setOption(option, true);
-                const endTime = +new Date();
-                updateTime = endTime - startTime;
+              } catch (e) {}
             }
-
-            if (gui) {
-                $(gui.domElement).remove();
-                gui.destroy();
-                gui = null;
+            if (!controller) {
+              controller = gui[isColor ? 'addColor' : 'add'](
+                appEnv.config,
+                name
+              );
             }
-
-            if (appEnv.config) {
-                gui = new dat.GUI({
-                    autoPlace: false
-                });
-                $(gui.domElement).css({
-                    position: 'absolute',
-                    right: 5,
-                    top: 0,
-                    zIndex: 1000
-                });
-                $('.right-container').append(gui.domElement);
-
-                var configParameters = appEnv.configParameters || {};
-                for (var name in appEnv.config) {
-                    var value = appEnv.config[name];
-                    if (name !== 'onChange' && name !== 'onFinishChange') {
-                        var isColor = false;
-                        // var value = obj;
-                        var controller = null;
-                        if (configParameters[name]) {
-                            if (configParameters[name].options) {
-                                controller = gui.add(appEnv.config, name, configParameters[name].options);
-                            }
-                            else if (configParameters[name].min != null) {
-                                controller = gui.add(appEnv.config, name, configParameters[name].min, configParameters[name].max);
-                            }
-                        }
-                        if (typeof obj === 'string') {
-                            try {
-                                var colorArr = echarts.color.parse(value);
-                                isColor = !!colorArr;
-                                if (isColor) {
-                                    value = echarts.color.stringify(colorArr, 'rgba');
-                                }
-                            }
-                            catch (e) {}
-                        }
-                        if (!controller) {
-                            controller = gui[isColor ? 'addColor' : 'add'](appEnv.config, name);
-                        }
-                        appEnv.config.onChange && controller.onChange(appEnv.config.onChange);
-                        appEnv.config.onFinishChange && controller.onFinishChange(appEnv.config.onFinishChange);
-                    }
-                }
-            }
-
-            return updateTime;
+            appEnv.config.onChange &&
+              controller.onChange(appEnv.config.onChange);
+            appEnv.config.onFinishChange &&
+              controller.onFinishChange(appEnv.config.onFinishChange);
+          }
         }
-    };
-};
\ No newline at end of file
+      }
+
+      return updateTime;
+    }
+  };
+}
diff --git a/src/editor/transformTs.js b/src/editor/transformTs.js
index b47973e..cb2cb1c 100644
--- a/src/editor/transformTs.js
+++ b/src/editor/transformTs.js
@@ -1,7 +1,7 @@
-import {transform} from 'sucrase';
+import { transform } from 'sucrase';
 
 export default function (code) {
-    return transform(code, {
-        transforms: ['typescript']
-    }).code.trim();
-}
\ No newline at end of file
+  return transform(code, {
+    transforms: ['typescript']
+  }).code.trim();
+}
diff --git a/src/explore/ExampleCard.vue b/src/explore/ExampleCard.vue
index bd465b8..17d6959 100644
--- a/src/explore/ExampleCard.vue
+++ b/src/explore/ExampleCard.vue
@@ -1,140 +1,144 @@
 <template>
-<div class="example-list-item">
+  <div class="example-list-item">
     <a target="_blank" class="example-link" :href="exampleLink">
-        <img class="chart-area" src="../asset/placeholder.jpg" :data-src="screenshotURL" />
-        <h4 class="example-title">{{title}}</h4>
-        <h5 class="example-subtitle" v-if="showSubtitle">{{subtitle}}</h5>
+      <img
+        class="chart-area"
+        src="../asset/placeholder.jpg"
+        :data-src="screenshotURL"
+      />
+      <h4 class="example-title">{{ title }}</h4>
+      <h5 class="example-subtitle" v-if="showSubtitle">{{ subtitle }}</h5>
     </a>
-</div>
+  </div>
 </template>
 
 <script>
-
-import {store} from '../common/store';
-import {SUPPORT_WEBP, URL_PARAMS} from '../common/config';
+import { store } from '../common/store';
+import { SUPPORT_WEBP, URL_PARAMS } from '../common/config';
 
 export default {
-    props: ['example'],
-
-    computed: {
-
-        title() {
-            return (store.locale === 'zh' ? this.example.titleCN : this.example.title)
-                || this.example.title || '';
-        },
-
-        showSubtitle() {
-            return store.locale === 'zh';
-        },
-
-        subtitle() {
-            return this.example.title || '';
-        },
-
-        exampleTheme() {
-            const example = this.example;
-            return example.theme || (store.darkMode ? 'dark' : '');
-        },
-
-        exampleLink() {
-            const example = this.example;
-            const hash = ['c=' + example.id];
-            const exampleTheme = this.exampleTheme;
-            if (example.isGL) {
-                hash.push('gl=1');
-            }
-            if (exampleTheme) {
-                hash.push('theme=' + exampleTheme);
-            }
-            if ('local' in URL_PARAMS) {
-                hash.push('local');
-            }
-            if ('useDirtyRect' in URL_PARAMS) {
-                hash.push('useDirtyRect');
-            }
-            return './editor.html?' + hash.join('&');
-        },
-
-        screenshotURL() {
-            const example = this.example;
-            const themePostfix = this.exampleTheme ? ('-' + this.exampleTheme) : '';
-            const ext = SUPPORT_WEBP ? 'webp' : 'png';
-            const folder = example.isGL ? 'data-gl' : 'data';
-            return `${store.cdnRoot}/${folder}/thumb${themePostfix}/${example.id}.${ext}?_v_=${store.version}`;
-        }
+  props: ['example'],
+
+  computed: {
+    title() {
+      return (
+        (store.locale === 'zh' ? this.example.titleCN : this.example.title) ||
+        this.example.title ||
+        ''
+      );
+    },
+
+    showSubtitle() {
+      return store.locale === 'zh';
+    },
+
+    subtitle() {
+      return this.example.title || '';
+    },
+
+    exampleTheme() {
+      const example = this.example;
+      return example.theme || (store.darkMode ? 'dark' : '');
+    },
+
+    exampleLink() {
+      const example = this.example;
+      const hash = ['c=' + example.id];
+      const exampleTheme = this.exampleTheme;
+      if (example.isGL) {
+        hash.push('gl=1');
+      }
+      if (exampleTheme) {
+        hash.push('theme=' + exampleTheme);
+      }
+      if ('local' in URL_PARAMS) {
+        hash.push('local');
+      }
+      if ('useDirtyRect' in URL_PARAMS) {
+        hash.push('useDirtyRect');
+      }
+      return './editor.html?' + hash.join('&');
+    },
+
+    screenshotURL() {
+      const example = this.example;
+      const themePostfix = this.exampleTheme ? '-' + this.exampleTheme : '';
+      const ext = SUPPORT_WEBP ? 'webp' : 'png';
+      const folder = example.isGL ? 'data-gl' : 'data';
+      return `${store.cdnRoot}/${folder}/thumb${themePostfix}/${example.id}.${ext}?_v_=${store.version}`;
     }
-}
+  }
+};
 </script>
 
 <style lang="scss">
-
-@import "../style/color.scss";
+@import '../style/color.scss';
 
 .example-list-item {
-    width: 100%;
-    max-width: 350px;
-    margin-bottom: 30px;
-
-    border-radius: 2px;
-
-    .example-link {
-        position: relative;
-        display: block;
-
-        .chart-area {
-            width: 100%;
-            height: 100%;
-            border-radius: 5px;
-            box-shadow: 0 0 20px rgba(0, 0, 0, 0.05);
-            margin-top: 10px;
-        }
-
-        .example-title {
-            color: $clr-primary;
-            overflow: hidden;
-            text-overflow: ellipsis;
-            white-space: nowrap;
-
-            padding: 10px 10px 2px 10px;
-            margin: 0;
-            font-weight: normal;
-            font-size: 14px;
-            text-align: center;
-        }
-
-        .example-subtitle {
-            font-size: 12px;
-            text-align: center;
-            color: #aaa;
-            font-weight: normal;
-            // font-weight: 200;
-            overflow: hidden;
-            white-space: nowrap;
-            text-overflow: ellipsis;
-            margin: 3px 0 0 0;
-        }
+  width: 100%;
+  max-width: 350px;
+  margin-bottom: 30px;
+
+  border-radius: 2px;
+
+  .example-link {
+    position: relative;
+    display: block;
+
+    .chart-area {
+      width: 100%;
+      height: 100%;
+      border-radius: 5px;
+      box-shadow: 0 0 20px rgba(0, 0, 0, 0.05);
+      margin-top: 10px;
+    }
+
+    .example-title {
+      color: $clr-primary;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+
+      padding: 10px 10px 2px 10px;
+      margin: 0;
+      font-weight: normal;
+      font-size: 14px;
+      text-align: center;
+    }
+
+    .example-subtitle {
+      font-size: 12px;
+      text-align: center;
+      color: #aaa;
+      font-weight: normal;
+      // font-weight: 200;
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+      margin: 3px 0 0 0;
     }
+  }
 
-    .example-info {
-        padding: 5px 0;
+  .example-info {
+    padding: 5px 0;
 
-        font-weight: bold;
+    font-weight: bold;
 
-        .chart-icon {
-            float: right;
+    .chart-icon {
+      float: right;
 
-            .chart-delete {
-                display: none;
+      .chart-delete {
+        display: none;
 
-                transition: 1s;
-            }
-        }
+        transition: 1s;
+      }
     }
+  }
 
-    &:hover .example-info .chart-icon .chart-delete {
-        display: block;
+  &:hover .example-info .chart-icon .chart-delete {
+    display: block;
 
-        text-decoration: none;
-    }
+    text-decoration: none;
+  }
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/explore/Explore.vue b/src/explore/Explore.vue
index 873674e..cd81d4c 100644
--- a/src/explore/Explore.vue
+++ b/src/explore/Explore.vue
@@ -1,209 +1,251 @@
 <template>
-<div id="example-explore">
+  <div id="example-explore">
     <div id="left-container">
-        <div id="left-chart-nav">
-            <scrollactive
-                active-class="active"
-                :offset="80"
-                :duration="500"
-                :scroll-container-selector="'#example-explore'"
-                bezier-easing-value=".5,0,.35,1"
-                @itemchanged="onActiveNavChanged"
-            >
-                <ul>
-                    <li v-for="category in EXAMPLE_CATEGORIES" :key="category">
-                        <a class="left-chart-nav-link scrollactive-item" :id="'left-chart-nav-' + category"
-                            :href="'#chart-type-' + category"
-                        >
-                            <span class="chart-icon" v-html="icons[category]"></span>
-                            <span class="chart-name">{{$t('chartTypes.' + category)}}</span>
-                        </a>
-                    </li>
-                </ul>
-            </scrollactive>
-        </div>
+      <div id="left-chart-nav">
+        <scrollactive
+          active-class="active"
+          :offset="80"
+          :duration="500"
+          :scroll-container-selector="'#example-explore'"
+          bezier-easing-value=".5,0,.35,1"
+          @itemchanged="onActiveNavChanged"
+        >
+          <ul>
+            <li v-for="category in EXAMPLE_CATEGORIES" :key="category">
+              <a
+                class="left-chart-nav-link scrollactive-item"
+                :id="'left-chart-nav-' + category"
+                :href="'#chart-type-' + category"
+              >
+                <span class="chart-icon" v-html="icons[category]"></span>
+                <span class="chart-name">{{
+                  $t('chartTypes.' + category)
+                }}</span>
+              </a>
+            </li>
+          </ul>
+        </scrollactive>
+      </div>
     </div>
     <div id="explore-container">
-        <div class="example-list-panel">
-            <div v-for="categoryObj in exampleList" :key="categoryObj.category">
-                <h3 class="chart-type-head" :id="'chart-type-' + categoryObj.category">
-                    {{$t('chartTypes.' + categoryObj.category)}}
-                    <span>{{categoryObj.category}}</span>
-                </h3>
-
-                <div class="row" :id="'chart-row-' + categoryObj.category">
-                    <div class="col-xl-2 col-lg-3 col-md-4 col-sm-6"
-                        v-for="exampleItem in categoryObj.examples"
-                        :key="exampleItem.id"
-                    >
-                        <ExampleCard :example="exampleItem"></ExampleCard>
-                    </div>
-                </div>
+      <div class="example-list-panel">
+        <div v-for="categoryObj in exampleList" :key="categoryObj.category">
+          <h3
+            class="chart-type-head"
+            :id="'chart-type-' + categoryObj.category"
+          >
+            {{ $t('chartTypes.' + categoryObj.category) }}
+            <span>{{ categoryObj.category }}</span>
+          </h3>
+
+          <div class="row" :id="'chart-row-' + categoryObj.category">
+            <div
+              class="col-xl-2 col-lg-3 col-md-4 col-sm-6"
+              v-for="exampleItem in categoryObj.examples"
+              :key="exampleItem.id"
+            >
+              <ExampleCard :example="exampleItem"></ExampleCard>
             </div>
+          </div>
         </div>
+      </div>
     </div>
     <div id="toolbar">
-        <el-switch
-            v-model="shared.darkMode"
-            active-color="#181432"
-            :active-text="$t('editor.darkMode')"
-            :inactive-text="''">
-        </el-switch>
+      <el-switch
+        v-model="shared.darkMode"
+        active-color="#181432"
+        :active-text="$t('editor.darkMode')"
+        :inactive-text="''"
+      >
+      </el-switch>
     </div>
-</div>
+  </div>
 </template>
 
 <script>
-
 import CHART_LIST from '../data/chart-list-data';
 import CHART_LIST_GL from '../data/chart-list-data-gl';
-import {EXAMPLE_CATEGORIES, BLACK_MAP, URL_PARAMS} from '../common/config';
-import {store} from '../common/store';
+import { EXAMPLE_CATEGORIES, BLACK_MAP, URL_PARAMS } from '../common/config';
+import { store } from '../common/store';
 import ExampleCard from './ExampleCard.vue';
 import LazyLoad from 'vanilla-lazyload/dist/lazyload.esm';
 // import scrollIntoView from 'scroll-into-view';
 
 const icons = {};
 
-['line', 'bar', 'scatter', 'pie', 'radar', 'funnel', 'gauge', 'map',
-    'graph', 'treemap', 'parallel', 'sankey', 'candlestick', 'boxplot', 'heatmap',
-    'pictorialBar', 'themeRiver', 'calendar', 'custom', 'sunburst', 'tree', 'dataset', 'geo', 'lines',
-    'dataZoom', 'rich', 'drag'
+[
+  'line',
+  'bar',
+  'scatter',
+  'pie',
+  'radar',
+  'funnel',
+  'gauge',
+  'map',
+  'graph',
+  'treemap',
+  'parallel',
+  'sankey',
+  'candlestick',
+  'boxplot',
+  'heatmap',
+  'pictorialBar',
+  'themeRiver',
+  'calendar',
+  'custom',
+  'sunburst',
+  'tree',
+  'dataset',
+  'geo',
+  'lines',
+  'dataZoom',
+  'rich',
+  'drag'
 ].forEach(function (category) {
-    icons[category] = require('../asset/icon/' + category + '.svg');
+  icons[category] = require('../asset/icon/' + category + '.svg');
 });
 
 const glIcon = require('../asset/icon/gl.svg');
-['globe', 'bar3D', 'scatter3D', 'surface', 'map3D', 'lines3D', 'line3D',
-    'scatterGL', 'linesGL', 'flowGL', 'graphGL', 'geo3D'].forEach(function (category) {
-    icons[category] = glIcon;
+[
+  'globe',
+  'bar3D',
+  'scatter3D',
+  'surface',
+  'map3D',
+  'lines3D',
+  'line3D',
+  'scatterGL',
+  'linesGL',
+  'flowGL',
+  'graphGL',
+  'geo3D'
+].forEach(function (category) {
+  icons[category] = glIcon;
 });
 
 const LAZY_LOADED_CLASS = 'ec-shot-loaded';
 
 export default {
+  components: {
+    ExampleCard
+  },
+
+  data() {
+    const exampleListByCategory = {};
+
+    function addExamples(list, isGL) {
+      let categoryOrder = 0;
+      // Add by category order in each example.
+      do {
+        let added = false;
+        for (let i = 0; i < list.length; i++) {
+          const example = list[i];
+          if (BLACK_MAP.hasOwnProperty(example.id)) {
+            continue;
+          }
+          if (typeof example.category === 'string') {
+            example.category = [example.category];
+          }
+
+          const categoryStr = (example.category || [])[categoryOrder];
+          if (categoryStr) {
+            added = true;
+            let categoryObj = exampleListByCategory[categoryStr];
+            if (!categoryObj) {
+              categoryObj = {
+                category: categoryStr,
+                examples: []
+              };
+              exampleListByCategory[categoryStr] = categoryObj;
+            }
+            example.isGL = isGL;
 
-    components: {
-        ExampleCard
-    },
-
-    data() {
-        const exampleListByCategory = {};
-
-        function addExamples(list, isGL) {
-            let categoryOrder = 0;
-            // Add by category order in each example.
-            do {
-                let added = false;
-                for (let i = 0; i < list.length; i++) {
-                    const example = list[i];
-                    if (BLACK_MAP.hasOwnProperty(example.id)) {
-                        continue;
-                    }
-                    if (typeof example.category === 'string') {
-                        example.category = [example.category];
-                    }
-
-                    const categoryStr = (example.category || [])[categoryOrder];
-                    if (categoryStr) {
-                        added = true;
-                        let categoryObj = exampleListByCategory[categoryStr];
-                        if (!categoryObj) {
-                            categoryObj = {
-                                category: categoryStr,
-                                examples: []
-                            }
-                            exampleListByCategory[categoryStr] = categoryObj;
-                        }
-                        example.isGL = isGL;
-
-                        categoryObj.examples.push(example);
-                    }
-                }
-
-                if (!added) {
-                    break;
-                }
-            } while (++categoryOrder && categoryOrder < 4)  // At most 4 category
+            categoryObj.examples.push(example);
+          }
         }
 
-        addExamples(CHART_LIST, false);
-        addExamples(CHART_LIST_GL, true);
-
-        return {
-            shared: store,
-
-            icons,
-
-            EXAMPLE_CATEGORIES,
-            // [{
-            //  category: '',
-            //  isGL: false
-            //  examples: []
-            // }]
-            exampleListByCategory
-        }
-    },
-
-    watch: {
-        "shared.darkMode"() {
-            const imgs = this.$el.querySelectorAll('img.chart-area');
-            for (let i = 0; i < imgs.length; i++) {
-                // Force lazyload to update
-                imgs[i].classList.remove(LAZY_LOADED_CLASS);
-                imgs[i].setAttribute('data-was-processed', 'false');
-            }
-            this._lazyload.update();
+        if (!added) {
+          break;
         }
-    },
-
-    computed: {
-        exampleList() {
-            const list = [];
-            for (let i = 0; i < EXAMPLE_CATEGORIES.length; i++) {
-                const category = EXAMPLE_CATEGORIES[i];
-                const categoryObj = this.exampleListByCategory[category];
-                if (categoryObj && categoryObj.examples.length > 0) {
-                    list.push({
-                        category,
-                        examples: categoryObj.examples
-                    });
-                }
-            }
-            return list;
-        }
-    },
-
-    mounted() {
-        this._lazyload = new LazyLoad({
-            // Container should be the scroll viewport.
-            // container: this.$el.querySelector('#explore-container .example-list-panel'),
-            elements_selector: 'img.chart-area',
-            load_delay: 400,
-            class_loaded: LAZY_LOADED_CLASS
-        });
-    },
-
-    methods: {
-        onActiveNavChanged(event, currentItem, lastActiveItem) {
-            // currentItem && currentItem.scrollIntoView && currentItem.parentNode.scrollIntoView();
-            // scrollIntoView(currentItem, {
-            //     time: 100,
-            //     cancellable: false,
-            //     align: {
-            //         top: 0,
-            //         topOffset: 50
-            //     }
-            // });
+      } while (++categoryOrder && categoryOrder < 4); // At most 4 category
+    }
+
+    addExamples(CHART_LIST, false);
+    addExamples(CHART_LIST_GL, true);
+
+    return {
+      shared: store,
+
+      icons,
+
+      EXAMPLE_CATEGORIES,
+      // [{
+      //  category: '',
+      //  isGL: false
+      //  examples: []
+      // }]
+      exampleListByCategory
+    };
+  },
+
+  watch: {
+    'shared.darkMode'() {
+      const imgs = this.$el.querySelectorAll('img.chart-area');
+      for (let i = 0; i < imgs.length; i++) {
+        // Force lazyload to update
+        imgs[i].classList.remove(LAZY_LOADED_CLASS);
+        imgs[i].setAttribute('data-was-processed', 'false');
+      }
+      this._lazyload.update();
+    }
+  },
+
+  computed: {
+    exampleList() {
+      const list = [];
+      for (let i = 0; i < EXAMPLE_CATEGORIES.length; i++) {
+        const category = EXAMPLE_CATEGORIES[i];
+        const categoryObj = this.exampleListByCategory[category];
+        if (categoryObj && categoryObj.examples.length > 0) {
+          list.push({
+            category,
+            examples: categoryObj.examples
+          });
         }
+      }
+      return list;
     }
-}
+  },
+
+  mounted() {
+    this._lazyload = new LazyLoad({
+      // Container should be the scroll viewport.
+      // container: this.$el.querySelector('#explore-container .example-list-panel'),
+      elements_selector: 'img.chart-area',
+      load_delay: 400,
+      class_loaded: LAZY_LOADED_CLASS
+    });
+  },
+
+  methods: {
+    onActiveNavChanged(event, currentItem, lastActiveItem) {
+      // currentItem && currentItem.scrollIntoView && currentItem.parentNode.scrollIntoView();
+      // scrollIntoView(currentItem, {
+      //     time: 100,
+      //     cancellable: false,
+      //     align: {
+      //         top: 0,
+      //         topOffset: 50
+      //     }
+      // });
+    }
+  }
+};
 </script>
 
 <style lang="scss">
-
-@import "../style/color.scss";
-@import "../style/config.xl.scss";
+@import '../style/color.scss';
+@import '../style/config.xl.scss';
 
 $chart-nav-width: 200px;
 $chart-icon-width: 25px;
@@ -212,10 +254,10 @@ $chart-icon-border: 1px;
 $toolbar-height: 30px;
 
 $nav-height: 50px;
-$nav-active-bg: #5470C6;
+$nav-active-bg: #5470c6;
 $nav-hover-border: $nav-active-bg;
 
-$nav-text-color: #6E7079;
+$nav-text-color: #6e7079;
 $nav-hover-text-color: #464646;
 
 $pd-basic: 10px;
@@ -223,178 +265,176 @@ $pd-sm: 6px;
 $pd-lg: 20px;
 
 #example-explore {
-    background: $clr-bg;
-
-    // Use this as scrollable viewport insteadof window because echarts-www has a viewport.
-    position: absolute;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    left: 0;
-    overflow-y: auto;
-
-    ::-webkit-scrollbar {
-        height: 4px;
-        width: 4px;
-        -webkit-transition: all 0.3s ease-in-out;
-        transition: all 0.3s ease-in-out;
-        border-radius: 2px;
-        background: #fff;
-    }
-
-    ::-webkit-scrollbar-button {
-        display: none
-    }
-
-    ::-webkit-scrollbar-thumb {
-        width: 4px;
-        min-height: 15px;
-        background: rgba(50, 50, 50, 0.2) !important;
-        -webkit-transition: all 0.3s ease-in-out;
-        transition: all 0.3s ease-in-out;
-        border-radius: 2px
-    }
-
-    ::-webkit-scrollbar-thumb:hover {
-        background: rgba(0, 0, 0, 0.5) !important
-    }
+  background: $clr-bg;
+
+  // Use this as scrollable viewport insteadof window because echarts-www has a viewport.
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  overflow-y: auto;
+
+  ::-webkit-scrollbar {
+    height: 4px;
+    width: 4px;
+    -webkit-transition: all 0.3s ease-in-out;
+    transition: all 0.3s ease-in-out;
+    border-radius: 2px;
+    background: #fff;
+  }
+
+  ::-webkit-scrollbar-button {
+    display: none;
+  }
+
+  ::-webkit-scrollbar-thumb {
+    width: 4px;
+    min-height: 15px;
+    background: rgba(50, 50, 50, 0.2) !important;
+    -webkit-transition: all 0.3s ease-in-out;
+    transition: all 0.3s ease-in-out;
+    border-radius: 2px;
+  }
+
+  ::-webkit-scrollbar-thumb:hover {
+    background: rgba(0, 0, 0, 0.5) !important;
+  }
 }
 
 #explore-container {
-    margin-left: $chart-nav-width + 20px;
-    padding: 10px 10px;
-    // background-color: $clr-bg;
+  margin-left: $chart-nav-width + 20px;
+  padding: 10px 10px;
+  // background-color: $clr-bg;
 }
 
 .example-list-panel {
-    margin: 30px 15px 30px 15px;
-
-    h3 {
-        margin-bottom: 20px;
-        padding-bottom: 10px;
-        border-bottom: 1px solid #E1E5F2;
-        font-weight: normal;
-        color: #464646;
-        font-size: 20px;
-    }
-    .chart-type-head span {
-        font-size: 16px;
-        padding-left: 5px;
-        color: #949CB1;
-        font-weight: 200;
-    }
+  margin: 30px 15px 30px 15px;
+
+  h3 {
+    margin-bottom: 20px;
+    padding-bottom: 10px;
+    border-bottom: 1px solid #e1e5f2;
+    font-weight: normal;
+    color: #464646;
+    font-size: 20px;
+  }
+  .chart-type-head span {
+    font-size: 16px;
+    padding-left: 5px;
+    color: #949cb1;
+    font-weight: 200;
+  }
 }
 
 #left-container {
-    position: sticky;
-    left: 0;
-    top: 0;
-    float: left;
-    height: calc(100%);
-    width: $chart-nav-width;
-    box-shadow: 0 0 10px rgba(0,0,0,0.1);
-    overflow-y: auto;
-
+  position: sticky;
+  left: 0;
+  top: 0;
+  float: left;
+  height: calc(100%);
+  width: $chart-nav-width;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+  overflow-y: auto;
 }
 
 #toolbar {
-    position: fixed;
-    right: 30px;
-    top: 20px;
-    height: $toolbar-height;
-    background-color: #fff;
-    border-radius: $toolbar-height / 2;
+  position: fixed;
+  right: 30px;
+  top: 20px;
+  height: $toolbar-height;
+  background-color: #fff;
+  border-radius: $toolbar-height / 2;
+  // color: #fff;
+  padding: 4px 15px;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+
+  .el-switch__label * {
+    font-size: 12px;
     // color: #fff;
-    padding: 4px 15px;
-    box-shadow: 0 0 10px rgba(0,0,0,0.1);
-
-    .el-switch__label * {
-        font-size: 12px;
-        // color: #fff;
-        text-transform: uppercase;
-    }
-    .el-switch__label.is-active {
-        color: #181432;
-    }
+    text-transform: uppercase;
+  }
+  .el-switch__label.is-active {
+    color: #181432;
+  }
 }
 
 #left-chart-nav {
-    background-color: #fff;
-    overflow-y: hidden;
-    color: #111;
-    box-shadow: 0 0 20px rgba(0,0,0,0.2);
+  background-color: #fff;
+  overflow-y: hidden;
+  color: #111;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
 
-    &:hover {
-        overflow-y: auto;
+  &:hover {
+    overflow-y: auto;
 
-        a {
-            text-decoration: none;
-        }
+    a {
+      text-decoration: none;
     }
+  }
+
+  li {
+    // transition: background-color 0.5s;
+    cursor: pointer;
+
+    a {
+      height: 45px;
+      padding: 10px 0 10px 20px;
+      display: block;
+      // transition: background-color 0.5s;
+      text-decoration: none;
+      color: $nav-text-color;
+
+      .chart-name {
+        display: inline-block;
+        position: relative;
+        vertical-align: middle;
+        margin-left: 10px;
+      }
+
+      .chart-icon {
+        content: '';
+        width: 20px;
+        display: inline-block;
+        border-radius: 50%;
+        vertical-align: middle;
+
+        svg {
+          width: 100% !important;
+          height: auto !important;
+        }
+      }
 
-    li {
-        // transition: background-color 0.5s;
-        cursor: pointer;
-
-        a {
-            height: 45px;
-            padding: 10px 0 10px 20px;
-            display: block;
-            // transition: background-color 0.5s;
-            text-decoration: none;
-            color: $nav-text-color;
-
-            .chart-name {
-                display: inline-block;
-                position: relative;
-                vertical-align: middle;
-                margin-left: 10px;
-            }
-
-            .chart-icon {
-                content: '';
-                width: 20px;
-                display: inline-block;
-                border-radius: 50%;
-                vertical-align: middle;
-
-                svg {
-                    width: 100%!important;
-                    height: auto!important;
-                }
-            }
-
-            &.active {
-                background-color: $nav-active-bg;
-                color: #fff;
-
-                .chart-icon * {
-                    fill: #fff;
-                }
-            }
+      &.active {
+        background-color: $nav-active-bg;
+        color: #fff;
 
-            &.active:hover {
-                color: #fff;
-            }
+        .chart-icon * {
+          fill: #fff;
         }
+      }
 
-        &:hover {
-            border-right: 4px solid $nav-hover-border;
+      &.active:hover {
+        color: #fff;
+      }
+    }
 
-            a {
-                color: $nav-hover-text-color;
-            }
-        }
+    &:hover {
+      border-right: 4px solid $nav-hover-border;
+
+      a {
+        color: $nav-hover-text-color;
+      }
     }
+  }
 }
 
 @media (max-width: 768px) {
-    #left-container {
-        display: none;
-    }
-    #explore-container {
-        margin-left: 0;
-    }
+  #left-container {
+    display: none;
+  }
+  #explore-container {
+    margin-left: 0;
+  }
 }
-
-</style>
\ No newline at end of file
+</style>
diff --git a/src/main.js b/src/main.js
index bcb7e55..7f6bcf2 100644
--- a/src/main.js
+++ b/src/main.js
@@ -4,7 +4,7 @@ import messages from './common/i18n';
 import EditorPage from './editor/Editor.vue';
 import ExplorePage from './explore/Explore.vue';
 import ViewPage from './editor/View.vue';
-import {store} from './common/store';
+import { store } from './common/store';
 import VueScrollactive from 'vue-scrollactive';
 
 Vue.use(VueScrollactive);
@@ -19,35 +19,36 @@ Vue.use(VueScrollactive);
  * @param {string} [option.version]
  */
 export function init(el, option) {
-    const i18n = new VueI18n({
-        locale: option.locale,
-        fallbackLocale: 'en',
-        messages
-    });
-    store.cdnRoot = option.cdnRoot;
-    store.version = option.version;
-    store.locale = option.locale || 'en';
+  const i18n = new VueI18n({
+    locale: option.locale,
+    fallbackLocale: 'en',
+    messages
+  });
+  store.cdnRoot = option.cdnRoot;
+  store.version = option.version;
+  store.locale = option.locale || 'en';
 
+  if (typeof el === 'string') {
+    el = document.querySelector(el);
+  }
+  if (!el) {
+    throw new Error("Can't find el.");
+  }
 
-    if (typeof el === 'string') {
-        el = document.querySelector(el);
-    }
-    if (!el) {
-        throw new Error('Can\'t find el.');
-    }
+  const container = document.createElement('div');
+  el.appendChild(container);
 
-    const container = document.createElement('div');
-    el.appendChild(container);
-
-    new Vue({
-        i18n,
-        el: container,
-        render: h => {
-            return h(({
-                editor: EditorPage,
-                explore: ExplorePage,
-                view: ViewPage
-            })[option.page] || ExplorePage);
-        }
-    });
-}
\ No newline at end of file
+  new Vue({
+    i18n,
+    el: container,
+    render: (h) => {
+      return h(
+        {
+          editor: EditorPage,
+          explore: ExplorePage,
+          view: ViewPage
+        }[option.page] || ExplorePage
+      );
+    }
+  });
+}
diff --git a/src/style/color.scss b/src/style/color.scss
index fda7835..62ed085 100644
--- a/src/style/color.scss
+++ b/src/style/color.scss
@@ -1,38 +1,36 @@
-$clr-primary:        #293c55;
-$clr-primary-light:  #849dbe;
-$clr-primary-dark:   #162436;
+$clr-primary: #293c55;
+$clr-primary-light: #849dbe;
+$clr-primary-dark: #162436;
 $clr-primary-darker: #0e151f;
 
-$clr-primary-home:   #333743;
-$clr-text-home:      #9297A3;
+$clr-primary-home: #333743;
+$clr-text-home: #9297a3;
 
-$clr-secondary:      #a9334c;
+$clr-secondary: #a9334c;
 $clr-secondary-dark: darken($clr-secondary, 10%);
 
-$clr-contrast:       #e43c59;
-$clr-contrast-dark:  #bf465b;
+$clr-contrast: #e43c59;
+$clr-contrast-dark: #bf465b;
 
-$clr-darkest:        #000;
-$clr-darker:         #333;
-$clr-dark:           #666;
-$clr-light:          #999;
-$clr-lighter:        #eee;
-$clr-lightest:       #f9f9f9;
+$clr-darkest: #000;
+$clr-darker: #333;
+$clr-dark: #666;
+$clr-light: #999;
+$clr-lighter: #eee;
+$clr-lightest: #f9f9f9;
 
-$clr-thirdary:       #40A7DC;
+$clr-thirdary: #40a7dc;
 $clr-thirdary-light: lighten($clr-thirdary, 10%);
 
 $clr-border: rgba(78, 97, 118, 0.45);
 $clr-border-light: rgba(78, 97, 118, 0.25);
 
-$clr-gray:           #ccc;
-$clr-gray-dark:      #999;
-$clr-gray-light:     #f3f3f3;
-
-$clr-warn:           #f93;
-$clr-error:          $clr-contrast;
-
+$clr-gray: #ccc;
+$clr-gray-dark: #999;
+$clr-gray-light: #f3f3f3;
 
+$clr-warn: #f93;
+$clr-error: $clr-contrast;
 
 $clr-bg: #f3f4fa;
 $clr-text: $clr-dark;
diff --git a/src/style/config.xl.scss b/src/style/config.xl.scss
index 678b094..37e7de6 100644
--- a/src/style/config.xl.scss
+++ b/src/style/config.xl.scss
@@ -18,607 +18,676 @@
    Fix visible-lg and hidden-lg for resolutions over 1600px
    Remove if don't want to use
    ========================================================================== */
-   @media (min-width: 1600px) {
-    .visible-lg {
-      display: none !important;
-    }
-    .hidden-lg {
-      display: block !important;
-    }
-    table.hidden-lg {
-      display: table;
-    }
-    tr.hidden-lg {
-      display: table-row !important;
-    }
-    th.hidden-lg,
-    td.hidden-lg {
-      display: table-cell !important;
-    }
+@media (min-width: 1600px) {
+  .visible-lg {
+    display: none !important;
+  }
+  .hidden-lg {
+    display: block !important;
+  }
+  table.hidden-lg {
+    display: table;
   }
+  tr.hidden-lg {
+    display: table-row !important;
+  }
+  th.hidden-lg,
+  td.hidden-lg {
+    display: table-cell !important;
+  }
+}
 
-  /* ==========================================================================
+/* ==========================================================================
      Set containers fixed sizes for >1600px, >1920px, >2560px
      Remove all if don't want to use big fixed sizes for all blocks
      You still can use cols with .container-fluid blocks
      ========================================================================== */
-  @media (min-width: 1600px) {
-    .container {
-      width: 1530px;
-    }
+@media (min-width: 1600px) {
+  .container {
+    width: 1530px;
   }
-  @media (min-width: 1920px) {
-    .container {
-      width: 1830px;
-    }
+}
+@media (min-width: 1920px) {
+  .container {
+    width: 1830px;
   }
-  @media (min-width: 2560px) {
-    .container {
-      width: 2490px;
-    }
+}
+@media (min-width: 2560px) {
+  .container {
+    width: 2490px;
   }
+}
 
-  /* ==========================================================================
+/* ==========================================================================
      col-xl, col-xxl, col-xxxl setup.
      Don't remove anything below this line
      ========================================================================== */
 
-  .col-xl-1, .col-xxl-1, .col-xxxl-1, .col-xl-2, .col-xxl-2, .col-md-2, .col-xxxl-2, .col-xl-3, .col-xxl-3, .col-md-3, .col-xxxl-3, .col-xl-4, .col-xxl-4, .col-md-4, .col-xxxl-4, .col-xl-5, .col-xxl-5, .col-md-5, .col-xxxl-5, .col-xl-6, .col-xxl-6, .col-md-6, .col-xxxl-6, .col-xl-7, .col-xxl-7, .col-md-7, .col-xxxl-7, .col-xl-8, .col-xxl-8, .col-md-8, .col-xxxl-8, .col-xl-9, .col-xxl-9, .col-md-9, .col-xxxl-9, .col-xl-10, .col-xxl-100, .col-xxxl-10, .col-xl-11, .col-xxl-111, .col-xxxl-11 [...]
-    position: relative;
-    min-height: 1px;
-    padding-right: 15px;
-    padding-left: 15px;
-  }
-  @media (min-width: 1600px) {
-    .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 {
-      float: left;
-    }
-    .col-xl-12 {
-      width: 100%;
-    }
-    .col-xl-11 {
-      width: 91.66666667%;
-    }
-    .col-xl-10 {
-      width: 83.33333333%;
-    }
-    .col-xl-9 {
-      width: 75%;
-    }
-    .col-xl-8 {
-      width: 66.66666667%;
-    }
-    .col-xl-7 {
-      width: 58.33333333%;
-    }
-    .col-xl-6 {
-      width: 50%;
-    }
-    .col-xl-5 {
-      width: 41.66666667%;
-    }
-    .col-xl-4 {
-      width: 33.33333333%;
-    }
-    .col-xl-3 {
-      width: 25%;
-    }
-    .col-xl-2 {
-      width: 16.66666667%;
-    }
-    .col-xl-1 {
-      width: 8.33333333%;
-    }
-    .col-xl-pull-12 {
-      right: 100%;
-    }
-    .col-xl-pull-11 {
-      right: 91.66666667%;
-    }
-    .col-xl-pull-10 {
-      right: 83.33333333%;
-    }
-    .col-xl-pull-9 {
-      right: 75%;
-    }
-    .col-xl-pull-8 {
-      right: 66.66666667%;
-    }
-    .col-xl-pull-7 {
-      right: 58.33333333%;
-    }
-    .col-xl-pull-6 {
-      right: 50%;
-    }
-    .col-xl-pull-5 {
-      right: 41.66666667%;
-    }
-    .col-xl-pull-4 {
-      right: 33.33333333%;
-    }
-    .col-xl-pull-3 {
-      right: 25%;
-    }
-    .col-xl-pull-2 {
-      right: 16.66666667%;
-    }
-    .col-xl-pull-1 {
-      right: 8.33333333%;
-    }
-    .col-xl-pull-0 {
-      right: 0;
-    }
-    .col-xl-push-12 {
-      left: 100%;
-    }
-    .col-xl-push-11 {
-      left: 91.66666667%;
-    }
-    .col-xl-push-10 {
-      left: 83.33333333%;
-    }
-    .col-xl-push-9 {
-      left: 75%;
-    }
-    .col-xl-push-8 {
-      left: 66.66666667%;
-    }
-    .col-xl-push-7 {
-      left: 58.33333333%;
-    }
-    .col-xl-push-6 {
-      left: 50%;
-    }
-    .col-xl-push-5 {
-      left: 41.66666667%;
-    }
-    .col-xl-push-4 {
-      left: 33.33333333%;
-    }
-    .col-xl-push-3 {
-      left: 25%;
-    }
-    .col-xl-push-2 {
-      left: 16.66666667%;
-    }
-    .col-xl-push-1 {
-      left: 8.33333333%;
-    }
-    .col-xl-push-0 {
-      left: 0;
-    }
-    .col-xl-offset-12 {
-      margin-left: 100%;
-    }
-    .col-xl-offset-11 {
-      margin-left: 91.66666667%;
-    }
-    .col-xl-offset-10 {
-      margin-left: 83.33333333%;
-    }
-    .col-xl-offset-9 {
-      margin-left: 75%;
-    }
-    .col-xl-offset-8 {
-      margin-left: 66.66666667%;
-    }
-    .col-xl-offset-7 {
-      margin-left: 58.33333333%;
-    }
-    .col-xl-offset-6 {
-      margin-left: 50%;
-    }
-    .col-xl-offset-5 {
-      margin-left: 41.66666667%;
-    }
-    .col-xl-offset-4 {
-      margin-left: 33.33333333%;
-    }
-    .col-xl-offset-3 {
-      margin-left: 25%;
-    }
-    .col-xl-offset-2 {
-      margin-left: 16.66666667%;
-    }
-    .col-xl-offset-1 {
-      margin-left: 8.33333333%;
-    }
-    .col-xl-offset-0 {
-      margin-left: 0;
-    }
+.col-xl-1,
+.col-xxl-1,
+.col-xxxl-1,
+.col-xl-2,
+.col-xxl-2,
+.col-md-2,
+.col-xxxl-2,
+.col-xl-3,
+.col-xxl-3,
+.col-md-3,
+.col-xxxl-3,
+.col-xl-4,
+.col-xxl-4,
+.col-md-4,
+.col-xxxl-4,
+.col-xl-5,
+.col-xxl-5,
+.col-md-5,
+.col-xxxl-5,
+.col-xl-6,
+.col-xxl-6,
+.col-md-6,
+.col-xxxl-6,
+.col-xl-7,
+.col-xxl-7,
+.col-md-7,
+.col-xxxl-7,
+.col-xl-8,
+.col-xxl-8,
+.col-md-8,
+.col-xxxl-8,
+.col-xl-9,
+.col-xxl-9,
+.col-md-9,
+.col-xxxl-9,
+.col-xl-10,
+.col-xxl-100,
+.col-xxxl-10,
+.col-xl-11,
+.col-xxl-111,
+.col-xxxl-11,
+.col-xl-12,
+.col-xxl-122,
+.col-xxxl-12 {
+  position: relative;
+  min-height: 1px;
+  padding-right: 15px;
+  padding-left: 15px;
+}
+@media (min-width: 1600px) {
+  .col-xl-1,
+  .col-xl-2,
+  .col-xl-3,
+  .col-xl-4,
+  .col-xl-5,
+  .col-xl-6,
+  .col-xl-7,
+  .col-xl-8,
+  .col-xl-9,
+  .col-xl-10,
+  .col-xl-11,
+  .col-xl-12 {
+    float: left;
   }
-
-  @media (min-width: 1920px) {
-    .col-xxl-1, .col-xxl-2, .col-xxl-3, .col-xxl-4, .col-xxl-5, .col-xxl-6, .col-xxl-7, .col-xxl-8, .col-xxl-9, .col-xxl-10, .col-xxl-11, .col-xxl-12 {
-      float: left;
-    }
-    .col-xxl-12 {
-      width: 100%;
-    }
-    .col-xxl-11 {
-      width: 91.66666667%;
-    }
-    .col-xxl-10 {
-      width: 83.33333333%;
-    }
-    .col-xxl-9 {
-      width: 75%;
-    }
-    .col-xxl-8 {
-      width: 66.66666667%;
-    }
-    .col-xxl-7 {
-      width: 58.33333333%;
-    }
-    .col-xxl-6 {
-      width: 50%;
-    }
-    .col-xxl-5 {
-      width: 41.66666667%;
-    }
-    .col-xxl-4 {
-      width: 33.33333333%;
-    }
... 2617 lines suppressed ...

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


[echarts-examples] 02/02: format example code

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

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

commit 5743f814891088758e986038e655e9207c4c31cf
Author: pissang <bm...@gmail.com>
AuthorDate: Mon Sep 6 14:21:30 2021 +0800

    format example code
---
 .eslintrc.yaml                                     |  194 ++
 .vscode/settings.json                              |    4 +-
 public/examples/ts/area-basic.ts                   |   30 +-
 public/examples/ts/area-pieces.ts                  |  110 +-
 public/examples/ts/area-rainfall.ts                |  304 +--
 public/examples/ts/area-simple.ts                  |  126 +-
 public/examples/ts/area-stack-gradient.ts          |  339 +--
 public/examples/ts/area-stack.ts                   |  182 +-
 public/examples/ts/area-time-axis.ts               |  100 +-
 public/examples/ts/bar-animation-delay.ts          |  110 +-
 public/examples/ts/bar-background.ts               |   34 +-
 public/examples/ts/bar-brush.ts                    |  169 +-
 public/examples/ts/bar-data-color.ts               |   44 +-
 public/examples/ts/bar-drilldown.ts                |  167 +-
 public/examples/ts/bar-gradient.ts                 |  143 +-
 public/examples/ts/bar-histogram.ts                |  247 +-
 public/examples/ts/bar-label-rotation.ts           |  296 +--
 public/examples/ts/bar-large.ts                    |  150 +-
 public/examples/ts/bar-negative.ts                 |  135 +-
 public/examples/ts/bar-negative2.ts                |  118 +-
 public/examples/ts/bar-polar-label-radial.ts       |   58 +-
 public/examples/ts/bar-polar-label-tangential.ts   |   58 +-
 public/examples/ts/bar-polar-real-estate.ts        |  184 +-
 public/examples/ts/bar-polar-stack-radial.ts       |   78 +-
 public/examples/ts/bar-polar-stack.ts              |   80 +-
 public/examples/ts/bar-race-country.ts             |  255 +-
 public/examples/ts/bar-race.ts                     |   99 +-
 public/examples/ts/bar-rich-text.ts                |  265 +-
 public/examples/ts/bar-simple.ts                   |   26 +-
 public/examples/ts/bar-stack.ts                    |  222 +-
 public/examples/ts/bar-tick-align.ts               |   68 +-
 public/examples/ts/bar-waterfall.ts                |  108 +-
 public/examples/ts/bar-waterfall2.ts               |  153 +-
 public/examples/ts/bar-y-category-stack.ts         |  161 +-
 public/examples/ts/bar-y-category.ts               |   75 +-
 public/examples/ts/bar1.ts                         |  131 +-
 public/examples/ts/boxplot-light-velocity.ts       |  151 +-
 public/examples/ts/boxplot-light-velocity2.ts      |  155 +-
 public/examples/ts/boxplot-multi.ts                |  182 +-
 public/examples/ts/bubble-gradient.ts              |  238 +-
 public/examples/ts/calendar-charts.ts              |  314 ++-
 public/examples/ts/calendar-effectscatter.ts       |  293 +--
 public/examples/ts/calendar-graph.ts               |  189 +-
 public/examples/ts/calendar-heatmap.ts             |   84 +-
 public/examples/ts/calendar-horizontal.ts          |  107 +-
 public/examples/ts/calendar-lunar.ts               |  889 ++++---
 public/examples/ts/calendar-pie.ts                 |  178 +-
 public/examples/ts/calendar-simple.ts              |   52 +-
 public/examples/ts/calendar-vertical.ts            |  123 +-
 public/examples/ts/candlestick-brush.ts            |  490 ++--
 public/examples/ts/candlestick-large.ts            |  361 +--
 public/examples/ts/candlestick-sh-2015.ts          |  228 +-
 public/examples/ts/candlestick-sh.ts               |  576 +++--
 public/examples/ts/candlestick-simple.ts           |   30 +-
 public/examples/ts/candlestick-touch.ts            |  453 ++--
 public/examples/ts/circle-packing-with-d3.ts       |  380 +--
 public/examples/ts/confidence-band.ts              |  152 +-
 public/examples/ts/custom-bar-trend.ts             |  185 +-
 public/examples/ts/custom-calendar-icon.ts         |  213 +-
 public/examples/ts/custom-cartesian-polygon.js     |   96 +-
 public/examples/ts/custom-error-bar.js             |  197 +-
 public/examples/ts/custom-error-scatter.js         |  218 +-
 public/examples/ts/custom-gantt-flight.js          |  969 ++++----
 public/examples/ts/custom-gauge.js                 |  281 +--
 public/examples/ts/custom-hexbin.js                |  450 ++--
 public/examples/ts/custom-ohlc.js                  |  292 +--
 public/examples/ts/custom-polar-heatmap.js         |  128 +-
 public/examples/ts/custom-profile.js               |  193 +-
 public/examples/ts/custom-profit.js                |  113 +-
 public/examples/ts/custom-spiral-race.js           |  403 ++--
 public/examples/ts/custom-wind.js                  |  195 +-
 public/examples/ts/cycle-plot.js                   |  203 +-
 public/examples/ts/data-transform-aggregate.js     |  232 +-
 public/examples/ts/data-transform-filter.ts        |  147 +-
 public/examples/ts/data-transform-multiple-pie.ts  |  159 +-
 public/examples/ts/data-transform-sort-bar.ts      |   60 +-
 public/examples/ts/dataset-default.ts              |   87 +-
 public/examples/ts/dataset-encode0.ts              |   80 +-
 public/examples/ts/dataset-encode1.ts              |  189 +-
 public/examples/ts/dataset-link.ts                 |  140 +-
 public/examples/ts/dataset-series-layout-by.ts     |   60 +-
 public/examples/ts/dataset-simple0.ts              |   36 +-
 public/examples/ts/dataset-simple1.ts              |   36 +-
 public/examples/ts/dynamic-data.ts                 |  246 +-
 public/examples/ts/dynamic-data2.ts                |  120 +-
 public/examples/ts/effectScatter-bmap.ts           | 1135 ++++-----
 public/examples/ts/effectScatter-map.ts            |  974 ++++----
 public/examples/ts/funnel-align.ts                 |  188 +-
 public/examples/ts/funnel-customize.ts             |  154 +-
 public/examples/ts/funnel-mutiple.ts               |  184 +-
 public/examples/ts/funnel.ts                       |  118 +-
 public/examples/ts/gauge-barometer.ts              |  233 +-
 public/examples/ts/gauge-car.ts                    | 1005 ++++----
 public/examples/ts/gauge-clock.ts                  |  414 ++--
 public/examples/ts/gauge-grade.ts                  |  159 +-
 public/examples/ts/gauge-multi-title.ts            |  125 +-
 public/examples/ts/gauge-progress.ts               |  169 +-
 public/examples/ts/gauge-ring.ts                   |  161 +-
 public/examples/ts/gauge-simple.ts                 |   42 +-
 public/examples/ts/gauge-speed.ts                  |   98 +-
 public/examples/ts/gauge-stage.ts                  |  118 +-
 public/examples/ts/gauge-temperature.ts            |  242 +-
 public/examples/ts/gauge.ts                        |   34 +-
 public/examples/ts/geo-beef-cuts.ts                |  127 +-
 public/examples/ts/geo-lines.js                    |  531 ++--
 public/examples/ts/geo-map-scatter.js              |  653 +++--
 public/examples/ts/geo-organ.js                    |  133 +-
 public/examples/ts/geo-seatmap-flight.ts           |  147 +-
 public/examples/ts/geo-svg-lines.ts                |  149 +-
 public/examples/ts/geo-svg-map.ts                  |  359 +--
 public/examples/ts/geo-svg-scatter-simple.ts       |   90 +-
 public/examples/ts/geo-svg-traffic.ts              |  307 +--
 public/examples/ts/graph-circular-layout.ts        |  100 +-
 public/examples/ts/graph-force-dynamic.ts          |   76 +-
 public/examples/ts/graph-force.ts                  |   84 +-
 public/examples/ts/graph-force2.ts                 |   86 +-
 public/examples/ts/graph-grid.ts                   |   72 +-
 public/examples/ts/graph-label-overlap.ts          |   78 +-
 public/examples/ts/graph-life-expectancy.ts        |  181 +-
 public/examples/ts/graph-npm.ts                    |   84 +-
 public/examples/ts/graph-simple.ts                 |  166 +-
 public/examples/ts/graph-webkit-dep.ts             |   58 +-
 public/examples/ts/graph.ts                        |  108 +-
 public/examples/ts/grid-multiple.ts                |  216 +-
 public/examples/ts/heatmap-bmap.js                 |   76 +-
 public/examples/ts/heatmap-cartesian.ts            |  108 +-
 public/examples/ts/heatmap-large-piecewise.js      |  418 ++--
 public/examples/ts/heatmap-large.js                |  402 ++--
 public/examples/ts/heatmap-map.js                  |  862 +++----
 public/examples/ts/line-aqi.ts                     |  194 +-
 public/examples/ts/line-draggable.ts               |  227 +-
 public/examples/ts/line-easing.ts                  |  467 ++--
 public/examples/ts/line-function.ts                |  114 +-
 public/examples/ts/line-gradient.ts                |  129 +-
 public/examples/ts/line-graphic.ts                 |  210 +-
 .../ts/line-in-cartesian-coordinate-system.ts      |   20 +-
 public/examples/ts/line-log.ts                     |  103 +-
 public/examples/ts/line-marker.ts                  |  149 +-
 public/examples/ts/line-markline.ts                |  133 +-
 public/examples/ts/line-pen.ts                     |  114 +-
 public/examples/ts/line-polar.ts                   |   59 +-
 public/examples/ts/line-polar2.ts                  |   70 +-
 public/examples/ts/line-race.ts                    |  163 +-
 public/examples/ts/line-sections.ts                |  168 +-
 public/examples/ts/line-simple.ts                  |   26 +-
 public/examples/ts/line-smooth.ts                  |   28 +-
 public/examples/ts/line-stack.ts                   |  114 +-
 public/examples/ts/line-step.ts                    |   92 +-
 public/examples/ts/line-style.ts                   |   50 +-
 public/examples/ts/line-tooltip-touch.ts           |  256 +-
 public/examples/ts/line-y-category.ts              |   88 +-
 public/examples/ts/lines-airline.ts                |  107 +-
 public/examples/ts/lines-bmap-bus.ts               |  299 +--
 public/examples/ts/lines-bmap-effect.ts            |  371 +--
 public/examples/ts/lines-bmap.ts                   |  265 +-
 public/examples/ts/lines-ny.ts                     |  148 +-
 public/examples/ts/map-HK.ts                       |  176 +-
 public/examples/ts/map-bar-morph.ts                |  260 +-
 public/examples/ts/map-bin.js                      |  395 +--
 public/examples/ts/map-china-dataRange.js          |  250 +-
 public/examples/ts/map-china.js                    |   36 +-
 public/examples/ts/map-labels.js                   |  294 +--
 public/examples/ts/map-locate.js                   |   76 +-
 public/examples/ts/map-polygon.js                  | 1265 +++++-----
 public/examples/ts/map-province.js                 |  150 +-
 public/examples/ts/map-usa.ts                      |  265 +-
 public/examples/ts/map-world-dataRange.js          |  459 ++--
 public/examples/ts/map-world.js                    |  404 ++--
 public/examples/ts/mix-line-bar.ts                 |  139 +-
 public/examples/ts/mix-timeline-finance.js         |  598 ++---
 public/examples/ts/mix-zoom-on-value.ts            |  166 +-
 public/examples/ts/multiple-x-axis.ts              |  173 +-
 public/examples/ts/multiple-y-axis.ts              |  191 +-
 public/examples/ts/parallel-aqi.ts                 |  386 +--
 public/examples/ts/parallel-nutrients.ts           |  306 ++-
 public/examples/ts/parallel-simple.ts              |   45 +-
 public/examples/ts/pictorialBar-bar-transition.ts  |  253 +-
 public/examples/ts/pictorialBar-body-fill.ts       |  270 ++-
 public/examples/ts/pictorialBar-dotted.ts          |  178 +-
 public/examples/ts/pictorialBar-forest.ts          |  170 +-
 public/examples/ts/pictorialBar-hill.ts            |  214 +-
 public/examples/ts/pictorialBar-spirit.ts          |  193 +-
 public/examples/ts/pictorialBar-vehicle.ts         |  200 +-
 public/examples/ts/pictorialBar-velocity.ts        |  186 +-
 public/examples/ts/pie-alignTo.ts                  |  160 +-
 public/examples/ts/pie-borderRadius.ts             |   82 +-
 public/examples/ts/pie-custom.ts                   |  118 +-
 public/examples/ts/pie-doughnut.ts                 |   72 +-
 public/examples/ts/pie-labelLine-adjust.ts         |  162 +-
 public/examples/ts/pie-legend.ts                   |  124 +-
 public/examples/ts/pie-nest.ts                     |  163 +-
 public/examples/ts/pie-parliament-transition.ts    |  242 +-
 public/examples/ts/pie-pattern.ts                  |   92 +-
 public/examples/ts/pie-rich-text.ts                |  240 +-
 public/examples/ts/pie-roseType-simple.ts          |   70 +-
 public/examples/ts/pie-roseType.ts                 |  153 +-
 public/examples/ts/pie-simple.ts                   |   66 +-
 public/examples/ts/polar-roundCap.ts               |   80 +-
 public/examples/ts/radar-aqi.ts                    |  371 +--
 public/examples/ts/radar-custom.ts                 |  226 +-
 public/examples/ts/radar-multiple.ts               |  168 +-
 public/examples/ts/radar.ts                        |   66 +-
 public/examples/ts/radar2.ts                       |  128 +-
 public/examples/ts/sankey-energy.ts                |   52 +-
 public/examples/ts/sankey-itemstyle.ts             | 2544 ++++++++++----------
 public/examples/ts/sankey-levels.ts                |  125 +-
 public/examples/ts/sankey-nodeAlign-left.ts        |   54 +-
 public/examples/ts/sankey-nodeAlign-right.ts       |   55 +-
 public/examples/ts/sankey-simple.ts                |  106 +-
 public/examples/ts/sankey-vertical.ts              |   80 +-
 public/examples/ts/scatter-aggregate-bar.ts        |  134 +-
 public/examples/ts/scatter-anscombe-quartet.ts     |  255 +-
 public/examples/ts/scatter-aqi-color.ts            |  458 ++--
 public/examples/ts/scatter-clustering-process.js   |  405 ++--
 public/examples/ts/scatter-clustering.ts           |  221 +-
 public/examples/ts/scatter-effect.ts               |   40 +-
 .../examples/ts/scatter-exponential-regression.ts  |  146 +-
 public/examples/ts/scatter-label-align-right.ts    |   93 +-
 public/examples/ts/scatter-label-align-top.ts      |   80 +-
 public/examples/ts/scatter-large.ts                |  114 +-
 .../ts/scatter-life-expectancy-timeline.js         |  309 +--
 public/examples/ts/scatter-linear-regression.ts    |  507 ++--
 .../examples/ts/scatter-logarithmic-regression.ts  |  244 +-
 public/examples/ts/scatter-map-brush.ts            | 1389 ++++++-----
 public/examples/ts/scatter-map.js                  |  908 +++----
 public/examples/ts/scatter-matrix.ts               |  528 ++--
 public/examples/ts/scatter-nebula.ts               |  119 +-
 public/examples/ts/scatter-nutrients-matrix.ts     |  774 +++---
 public/examples/ts/scatter-nutrients.ts            |  267 +-
 public/examples/ts/scatter-painter-choice.ts       |   77 +-
 public/examples/ts/scatter-polar-punchCard.ts      |  117 +-
 .../examples/ts/scatter-polynomial-regression.ts   |  141 +-
 public/examples/ts/scatter-punchCard.ts            |  123 +-
 public/examples/ts/scatter-simple.ts               |   65 +-
 public/examples/ts/scatter-single-axis.ts          |   86 +-
 public/examples/ts/scatter-stream-visual.ts        |   88 +-
 public/examples/ts/scatter-symbol-morph.ts         |  189 +-
 public/examples/ts/scatter-weibo.ts                |  119 +-
 public/examples/ts/scatter-weight.ts               |  511 ++--
 public/examples/ts/scatter-world-population.js     |  985 ++++----
 public/examples/ts/sunburst-book.js                |  561 +++--
 public/examples/ts/sunburst-borderRadius.ts        |   84 +-
 public/examples/ts/sunburst-drink.ts               |  729 +++---
 public/examples/ts/sunburst-label-rotate.ts        |  194 +-
 public/examples/ts/sunburst-monochrome.ts          |  250 +-
 public/examples/ts/sunburst-simple.ts              |   82 +-
 public/examples/ts/sunburst-visualMap.ts           |  127 +-
 public/examples/ts/themeRiver-basic.ts             |  259 +-
 public/examples/ts/themeRiver-lastfm.ts            |  123 +-
 public/examples/ts/tree-basic.ts                   |  100 +-
 public/examples/ts/tree-legend.ts                  |  429 ++--
 public/examples/ts/tree-orient-bottom-top.ts       |   81 +-
 public/examples/ts/tree-orient-right-left.ts       |   86 +-
 public/examples/ts/tree-polyline.ts                |  310 ++-
 public/examples/ts/tree-radial.ts                  |   50 +-
 public/examples/ts/tree-vertical.ts                |   92 +-
 public/examples/ts/treemap-disk.ts                 |  127 +-
 public/examples/ts/treemap-drill-down.ts           |  157 +-
 public/examples/ts/treemap-obama.ts                |  355 +--
 public/examples/ts/treemap-show-parent.ts          |  157 +-
 public/examples/ts/treemap-simple.ts               |   64 +-
 public/examples/ts/treemap-sunburst-transition.ts  |   80 +-
 public/examples/ts/treemap-visual.ts               |  204 +-
 public/examples/ts/watermark.ts                    |  390 +--
 public/examples/ts/wind-barb.ts                    |  510 ++--
 src/common/config.js                               |    2 +-
 src/editor/CodeMonaco.vue                          |    1 +
 267 files changed, 31570 insertions(+), 28787 deletions(-)

diff --git a/.eslintrc.yaml b/.eslintrc.yaml
new file mode 100644
index 0000000..e4a2cee
--- /dev/null
+++ b/.eslintrc.yaml
@@ -0,0 +1,194 @@
+# Note:
+# If eslint does not work in VSCode, please check:
+# (1) Whether "@typescript-eslint/eslint-plugin" and "@typescript-eslint/parser"
+# are npm installed locally. Should better in the same version.
+# (2) Whether "VSCode ESlint extension" is installed.
+# (3) If the project folder is not the root folder of your working space, please
+# config the "VSCode ESlint extension" in "settings":
+# ```json
+# "eslint.workingDirectories": [{"mode": "auto"}]
+# ```
+# Note that it should be "workingDirectories" rather than "WorkingDirectories".
+
+rules:
+    # Check the rules in: node_modules/@typescript-eslint/eslint-plugin/README.md
+    no-console:
+        - 2
+        -
+            allow:
+                - "warn"
+                - "error"
+    prefer-const: 1
+    no-constant-condition: 0
+    comma-dangle: 2
+    no-debugger: 2
+    no-dupe-keys: 2
+    no-empty-character-class: 2
+    no-ex-assign: 2
+    no-extra-boolean-cast: 0
+    no-func-assign: 2
+    no-inner-declarations: 2
+    no-invalid-regexp: 2
+    no-negated-in-lhs: 2
+    no-obj-calls: 2
+    no-sparse-arrays: 2
+    no-unreachable: 2
+    use-isnan: 2
+    valid-typeof: 2
+    block-scoped-var: 2
+    curly:
+        - 2
+        - "all"
+    eqeqeq:
+        - 2
+        - "allow-null"
+    guard-for-in: 2
+    no-else-return: 0
+    no-labels:
+        - 2
+        -
+            allowLoop: true
+    no-eval: 2
+    no-extend-native: 2
+    no-extra-bind: 0
+    no-implied-eval: 2
+    no-iterator: 2
+    no-irregular-whitespace: 2
+    no-lone-blocks: 2
+    no-loop-func: 2
+    no-multi-str: 2
+    no-native-reassign: 2
+    no-new-wrappers: 2
+    no-octal: 2
+    no-octal-escape: 2
+    no-proto: 2
+    no-redeclare: 2
+    no-self-compare: 2
+    no-unneeded-ternary: 2
+    no-with: 2
+    radix: 2
+    wrap-iife:
+        - 2
+        - "any"
+    no-delete-var: 2
+    no-dupe-args: 2
+    no-duplicate-case: 2
+    no-label-var: 2
+    no-shadow-restricted-names: 2
+    no-undef: 2
+    no-undef-init: 2
+    "no-use-before-define": 0
+    brace-style:
+        - 2
+        - "stroustrup"
+        - {}
+    comma-spacing:
+        - 2
+        -
+            before: false
+            after: true
+    comma-style:
+        - 2
+        - "last"
+    new-parens: 2
+    no-array-constructor: 2
+    no-multi-spaces:
+        - 1
+        -
+            ignoreEOLComments: true
+            exceptions:
+                Property: true
+    no-new-object: 2
+    no-trailing-spaces: 2
+    no-extra-parens:
+        - 2
+        - "functions"
+    no-mixed-spaces-and-tabs: 2
+    one-var:
+        - 2
+        - "never"
+    operator-linebreak:
+        - 2
+        - "before"
+        -
+            overrides:
+                "=": "after"
+    "quotes":
+        - 2
+        - "single"
+    "semi":
+        - 2
+        - "always"
+    semi-spacing: 2
+    keyword-spacing: 2
+    key-spacing:
+        - 2
+        -
+            beforeColon: false
+            afterColon: true
+    "space-before-function-paren":
+        - 2
+        -
+            anonymous: "always"
+            named: "never"
+    space-before-blocks:
+        - 2
+        - "always"
+    computed-property-spacing:
+        - 2
+        - "never"
+    space-in-parens:
+        - 2
+        - "never"
+    space-unary-ops: 2
+    spaced-comment: 0
+
+    max-nested-callbacks:
+        - 1
+        - 5
+    max-depth:
+        - 1
+        - 6
+    max-len:
+        - 2
+        - 120
+        - 4
+        -
+            ignoreUrls: true
+            ignoreComments: true
+    max-params:
+        - 1
+        - 15
+
+    space-infix-ops: 2
+    dot-notation:
+        - 2
+        -
+            allowKeywords: true
+            allowPattern: "^catch$"
+
+    arrow-spacing: 2
+    constructor-super: 2
+    no-confusing-arrow:
+        - 2
+        -
+            allowParens: true
+    no-class-assign: 2
+    no-const-assign: 2
+    # no-dupe-class-members: 2
+    no-this-before-super: 0
+    no-duplicate-imports: 2
+    prefer-rest-params: 0
+    unicode-bom: 2
+    max-statements-per-line: 2
+
+    no-useless-constructor: 0
+    indent: ["warn", 4]
+
+    "func-call-spacing": "error"
+
+    "no-unused-vars":
+        - 1
+        -
+            vars: "local"
+            args: "none"
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 1b6457c..afd540a 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,4 +1,6 @@
 {
   "editor.formatOnSave": true,
-  "editor.defaultFormatter": "esbenp.prettier-vscode"
+  "editor.defaultFormatter": "esbenp.prettier-vscode",
+  "editor.tabSize": 2,
+  "editor.detectIndentation": false
 }
diff --git a/public/examples/ts/area-basic.ts b/public/examples/ts/area-basic.ts
index 13cfbc5..32c848f 100644
--- a/public/examples/ts/area-basic.ts
+++ b/public/examples/ts/area-basic.ts
@@ -6,19 +6,21 @@ difficulty: 1
 */
 
 option = {
-    xAxis: {
-        type: 'category',
-        boundaryGap: false,
-        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-    },
-    yAxis: {
-        type: 'value'
-    },
-    series: [{
-        data: [820, 932, 901, 934, 1290, 1330, 1320],
-        type: 'line',
-        areaStyle: {}
-    }]
+  xAxis: {
+    type: 'category',
+    boundaryGap: false,
+    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+  },
+  yAxis: {
+    type: 'value'
+  },
+  series: [
+    {
+      data: [820, 932, 901, 934, 1290, 1330, 1320],
+      type: 'line',
+      areaStyle: {}
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/area-pieces.ts b/public/examples/ts/area-pieces.ts
index 70f3ea5..b621430 100644
--- a/public/examples/ts/area-pieces.ts
+++ b/public/examples/ts/area-pieces.ts
@@ -6,62 +6,60 @@ difficulty: 3
 */
 
 option = {
-    xAxis: {
-        type: 'category',
-        boundaryGap: false
-    },
-    yAxis: {
-        type: 'value',
-        boundaryGap: [0, '30%']
-    },
-    visualMap: {
-        type: 'piecewise',
-        show: false,
-        dimension: 0,
-        seriesIndex: 0,
-        pieces: [{
-            gt: 1,
-            lt: 3,
-            color: 'rgba(0, 0, 180, 0.4)'
-        }, {
-            gt: 5,
-            lt: 7,
-            color: 'rgba(0, 0, 180, 0.4)'
-        }]
-    },
-    series: [
-        {
-            type: 'line',
-            smooth: 0.6,
-            symbol: 'none',
-            lineStyle: {
-                color: '#5470C6',
-                width: 5
-            },
-            markLine: {
-                symbol: ['none', 'none'],
-                label: {show: false},
-                data: [
-                    {xAxis: 1},
-                    {xAxis: 3},
-                    {xAxis: 5},
-                    {xAxis: 7}
-                ]
-            },
-            areaStyle: {},
-            data: [
-                ['2019-10-10', 200],
-                ['2019-10-11', 560],
-                ['2019-10-12', 750],
-                ['2019-10-13', 580],
-                ['2019-10-14', 250],
-                ['2019-10-15', 300],
-                ['2019-10-16', 450],
-                ['2019-10-17', 300],
-                ['2019-10-18', 100]
-            ]
-        }
+  xAxis: {
+    type: 'category',
+    boundaryGap: false
+  },
+  yAxis: {
+    type: 'value',
+    boundaryGap: [0, '30%']
+  },
+  visualMap: {
+    type: 'piecewise',
+    show: false,
+    dimension: 0,
+    seriesIndex: 0,
+    pieces: [
+      {
+        gt: 1,
+        lt: 3,
+        color: 'rgba(0, 0, 180, 0.4)'
+      },
+      {
+        gt: 5,
+        lt: 7,
+        color: 'rgba(0, 0, 180, 0.4)'
+      }
     ]
+  },
+  series: [
+    {
+      type: 'line',
+      smooth: 0.6,
+      symbol: 'none',
+      lineStyle: {
+        color: '#5470C6',
+        width: 5
+      },
+      markLine: {
+        symbol: ['none', 'none'],
+        label: { show: false },
+        data: [{ xAxis: 1 }, { xAxis: 3 }, { xAxis: 5 }, { xAxis: 7 }]
+      },
+      areaStyle: {},
+      data: [
+        ['2019-10-10', 200],
+        ['2019-10-11', 560],
+        ['2019-10-12', 750],
+        ['2019-10-13', 580],
+        ['2019-10-14', 250],
+        ['2019-10-15', 300],
+        ['2019-10-16', 450],
+        ['2019-10-17', 300],
+        ['2019-10-18', 100]
+      ]
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/area-rainfall.ts b/public/examples/ts/area-rainfall.ts
index a8d833b..7dd5632 100644
--- a/public/examples/ts/area-rainfall.ts
+++ b/public/examples/ts/area-rainfall.ts
@@ -6,185 +6,143 @@ difficulty: 5
 */
 
 option = {
-    title: {
-        text: 'Rainfall and Flow Relationship',
-        left: 'center',
-        textAlign: 'right'
+  title: {
+    text: 'Rainfall and Flow Relationship',
+    left: 'center',
+    textAlign: 'right'
+  },
+  grid: {
+    bottom: 80
+  },
+  toolbox: {
+    feature: {
+      dataZoom: {
+        yAxisIndex: 'none'
+      },
+      restore: {},
+      saveAsImage: {}
+    }
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'cross',
+      animation: false,
+      label: {
+        backgroundColor: '#505765'
+      }
+    }
+  },
+  legend: {
+    data: ['Flow', 'Rainfall'],
+    left: 10
+  },
+  dataZoom: [
+    {
+      show: true,
+      realtime: true,
+      start: 65,
+      end: 85
     },
-    grid: {
-        bottom: 80
+    {
+      type: 'inside',
+      realtime: true,
+      start: 65,
+      end: 85
+    }
+  ],
+  xAxis: [
+    {
+      type: 'category',
+      boundaryGap: false,
+      axisLine: { onZero: false },
+      // prettier-ignore
+      data: [
+        '2009/6/12 2:00', '2009/6/12 3:00', '2009/6/12 4:00', '2009/6/12 5:00', '2009/6/12 6:00', '2009/6/12 7:00', '2009/6/12 8:00', '2009/6/12 9:00', '2009/6/12 10:00', '2009/6/12 11:00', '2009/6/12 12:00', '2009/6/12 13:00', '2009/6/12 14:00', '2009/6/12 15:00', '2009/6/12 16:00', '2009/6/12 17:00', '2009/6/12 18:00', '2009/6/12 19:00', '2009/6/12 20:00', '2009/6/12 21:00', '2009/6/12 22:00', '2009/6/12 23:00','2009/6/13 0:00', '2009/6/13 1:00', '2009/6/13 2:00', '2009/6/13 3:00', '20 [...]
+      ].map(function (str) {
+        return str.replace(' ', '\n');
+      })
+    }
+  ],
+  yAxis: [
+    {
+      name: 'Flow(m^3/s)',
+      type: 'value',
+      max: 500
     },
-    toolbox: {
-        feature: {
-            dataZoom: {
-                yAxisIndex: 'none'
+    {
+      name: 'Rainfall(mm)',
+      nameLocation: 'start',
+      max: 5,
+      type: 'value',
+      inverse: true
+    }
+  ],
+  series: [
+    {
+      name: 'Flow',
+      type: 'line',
+      areaStyle: {},
+      lineStyle: {
+        width: 1
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      markArea: {
+        silent: true,
+        itemStyle: {
+          opacity: 0.3
+        },
+        data: [
+          [
+            {
+              xAxis: '2009/9/12\n7:00'
             },
-            restore: {},
-            saveAsImage: {}
-        }
-    },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'cross',
-            animation: false,
-            label: {
-                backgroundColor: '#505765'
+            {
+              xAxis: '2009/9/22\n7:00'
             }
-        }
-    },
-    legend: {
-        data: ['Flow', 'Rainfall'],
-        left: 10
+          ]
+        ]
+      },
+      // prettier-ignore
+      data: [
+        0.97,0.96,0.96,0.95,0.95,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94 [...]
+      ]
     },
-    dataZoom: [
-        {
-            show: true,
-            realtime: true,
-            start: 65,
-            end: 85
-        },
-        {
-            type: 'inside',
-            realtime: true,
-            start: 65,
-            end: 85
-        }
-    ],
-    xAxis: [
-        {
-            type: 'category',
-            boundaryGap: false,
-            axisLine: {onZero: false},
-            data: [
-                '2009/6/12 2:00', '2009/6/12 3:00', '2009/6/12 4:00', '2009/6/12 5:00', '2009/6/12 6:00', '2009/6/12 7:00', '2009/6/12 8:00', '2009/6/12 9:00', '2009/6/12 10:00', '2009/6/12 11:00', '2009/6/12 12:00', '2009/6/12 13:00', '2009/6/12 14:00', '2009/6/12 15:00', '2009/6/12 16:00', '2009/6/12 17:00', '2009/6/12 18:00', '2009/6/12 19:00', '2009/6/12 20:00', '2009/6/12 21:00', '2009/6/12 22:00', '2009/6/12 23:00',
-                '2009/6/13 0:00', '2009/6/13 1:00', '2009/6/13 2:00', '2009/6/13 3:00', '2009/6/13 4:00', '2009/6/13 5:00', '2009/6/13 6:00', '2009/6/13 7:00', '2009/6/13 8:00', '2009/6/13 9:00', '2009/6/13 10:00', '2009/6/13 11:00', '2009/6/13 12:00', '2009/6/13 13:00', '2009/6/13 14:00', '2009/6/13 15:00', '2009/6/13 16:00', '2009/6/13 17:00', '2009/6/13 18:00', '2009/6/13 19:00', '2009/6/13 20:00', '2009/6/13 21:00', '2009/6/13 22:00', '2009/6/13 23:00',
-                '2009/6/14 0:00', '2009/6/14 1:00', '2009/6/14 2:00', '2009/6/14 3:00', '2009/6/14 4:00', '2009/6/14 5:00', '2009/6/14 6:00', '2009/6/14 7:00', '2009/6/14 8:00', '2009/6/14 9:00', '2009/6/14 10:00', '2009/6/14 11:00', '2009/6/14 12:00', '2009/6/14 13:00', '2009/6/14 14:00', '2009/6/14 15:00', '2009/6/14 16:00', '2009/6/14 17:00', '2009/6/14 18:00', '2009/6/14 19:00', '2009/6/14 20:00', '2009/6/14 21:00', '2009/6/14 22:00', '2009/6/14 23:00',
-                '2009/6/15 0:00', '2009/6/15 1:00', '2009/6/15 2:00', '2009/6/15 3:00', '2009/6/15 4:00', '2009/6/15 5:00', '2009/6/15 6:00', '2009/6/15 7:00', '2009/6/15 8:00', '2009/6/15 9:00', '2009/6/15 10:00', '2009/6/15 11:00', '2009/6/15 12:00', '2009/6/15 13:00', '2009/6/15 14:00', '2009/6/15 15:00', '2009/6/15 16:00', '2009/6/15 17:00', '2009/6/15 18:00', '2009/6/15 19:00', '2009/6/15 20:00', '2009/6/15 21:00', '2009/6/15 22:00', '2009/6/15 23:00',
-                '2009/6/15 0:00', '2009/6/16 1:00', '2009/6/16 2:00', '2009/6/16 3:00', '2009/6/16 4:00', '2009/6/16 5:00', '2009/6/16 6:00', '2009/6/16 7:00', '2009/6/16 8:00', '2009/6/16 9:00', '2009/6/16 10:00', '2009/6/16 11:00', '2009/6/16 12:00', '2009/6/16 13:00', '2009/6/16 14:00', '2009/6/16 15:00', '2009/6/16 16:00', '2009/6/16 17:00', '2009/6/16 18:00', '2009/6/16 19:00', '2009/6/16 20:00', '2009/6/16 21:00', '2009/6/16 22:00', '2009/6/16 23:00',
-                '2009/6/15 0:00', '2009/6/17 1:00', '2009/6/17 2:00', '2009/6/17 3:00', '2009/6/17 4:00', '2009/6/17 5:00', '2009/6/17 6:00', '2009/6/17 7:00', '2009/6/17 8:00', '2009/6/17 9:00', '2009/6/17 10:00', '2009/6/17 11:00', '2009/6/17 12:00', '2009/6/17 13:00', '2009/6/17 14:00', '2009/6/17 15:00', '2009/6/17 16:00', '2009/6/17 17:00', '2009/6/17 18:00', '2009/6/17 19:00', '2009/6/17 20:00', '2009/6/17 21:00', '2009/6/17 22:00', '2009/6/17 23:00',
-                '2009/6/18 0:00', '2009/6/18 1:00', '2009/6/18 2:00', '2009/6/18 3:00', '2009/6/18 4:00', '2009/6/18 5:00', '2009/6/18 6:00', '2009/6/18 7:00', '2009/6/18 8:00', '2009/6/18 9:00', '2009/6/18 10:00', '2009/6/18 11:00', '2009/6/18 12:00', '2009/6/18 13:00', '2009/6/18 14:00', '2009/6/18 15:00', '2009/6/18 16:00', '2009/6/18 17:00', '2009/6/18 18:00', '2009/6/18 19:00', '2009/6/18 20:00', '2009/6/18 21:00', '2009/6/18 22:00', '2009/6/18 23:00',
-                '2009/6/15 0:00', '2009/6/19 1:00', '2009/6/19 2:00', '2009/6/19 3:00', '2009/6/19 4:00', '2009/6/19 5:00', '2009/6/19 6:00', '2009/6/19 7:00', '2009/6/19 8:00', '2009/6/19 9:00', '2009/6/19 10:00', '2009/6/19 11:00', '2009/6/19 12:00', '2009/6/19 13:00', '2009/6/19 14:00', '2009/6/19 15:00', '2009/6/19 16:00', '2009/6/19 17:00', '2009/6/19 18:00', '2009/6/19 19:00', '2009/6/19 20:00', '2009/6/19 21:00', '2009/6/19 22:00', '2009/6/19 23:00',
-                '2009/6/20 0:00', '2009/6/20 1:00', '2009/6/20 2:00', '2009/6/20 3:00', '2009/6/20 4:00', '2009/6/20 5:00', '2009/6/20 6:00', '2009/6/20 7:00', '2009/6/20 8:00', '2009/6/20 9:00', '2009/6/20 10:00', '2009/6/20 11:00', '2009/6/20 12:00', '2009/6/20 13:00', '2009/6/20 14:00', '2009/6/20 15:00', '2009/6/20 16:00', '2009/6/20 17:00', '2009/6/20 18:00', '2009/6/20 19:00', '2009/6/20 20:00', '2009/6/20 21:00', '2009/6/20 22:00', '2009/6/20 23:00',
-                '2009/6/21 0:00', '2009/6/21 1:00', '2009/6/21 2:00', '2009/6/21 3:00', '2009/6/21 4:00', '2009/6/21 5:00', '2009/6/21 6:00', '2009/6/21 7:00', '2009/6/21 8:00', '2009/6/21 9:00', '2009/6/21 10:00', '2009/6/21 11:00', '2009/6/21 12:00', '2009/6/21 13:00', '2009/6/21 14:00', '2009/6/21 15:00', '2009/6/21 16:00', '2009/6/21 17:00', '2009/6/21 18:00', '2009/6/21 19:00', '2009/6/21 20:00', '2009/6/21 21:00', '2009/6/21 22:00', '2009/6/21 23:00',
-                '2009/6/22 0:00', '2009/6/22 1:00', '2009/6/22 2:00', '2009/6/22 3:00', '2009/6/22 4:00', '2009/6/22 5:00', '2009/6/22 6:00', '2009/6/22 7:00', '2009/6/22 8:00', '2009/6/22 9:00', '2009/6/22 10:00', '2009/6/22 11:00', '2009/6/22 12:00', '2009/6/22 13:00', '2009/6/22 14:00', '2009/6/22 15:00', '2009/6/22 16:00', '2009/6/22 17:00', '2009/6/22 18:00', '2009/6/22 19:00', '2009/6/22 20:00', '2009/6/22 21:00', '2009/6/22 22:00', '2009/6/22 23:00',
-                '2009/6/23 0:00', '2009/6/23 1:00', '2009/6/23 2:00', '2009/6/23 3:00', '2009/6/23 4:00', '2009/6/23 5:00', '2009/6/23 6:00', '2009/6/23 7:00', '2009/6/23 8:00', '2009/6/23 9:00', '2009/6/23 10:00', '2009/6/23 11:00', '2009/6/23 12:00', '2009/6/23 13:00', '2009/6/23 14:00', '2009/6/23 15:00', '2009/6/23 16:00', '2009/6/23 17:00', '2009/6/23 18:00', '2009/6/23 19:00', '2009/6/23 20:00', '2009/6/23 21:00', '2009/6/23 22:00', '2009/6/23 23:00',
-                '2009/6/24 0:00', '2009/6/24 1:00', '2009/6/24 2:00', '2009/6/24 3:00', '2009/6/24 4:00', '2009/6/24 5:00', '2009/6/24 6:00', '2009/6/24 7:00', '2009/6/24 8:00', '2009/6/24 9:00', '2009/6/24 10:00', '2009/6/24 11:00', '2009/6/24 12:00', '2009/6/24 13:00', '2009/6/24 14:00', '2009/6/24 15:00', '2009/6/24 16:00', '2009/6/24 17:00', '2009/6/24 18:00', '2009/6/24 19:00', '2009/6/24 20:00', '2009/6/24 21:00', '2009/6/24 22:00', '2009/6/24 23:00',
-                '2009/6/25 0:00', '2009/6/25 1:00', '2009/6/25 2:00', '2009/6/25 3:00', '2009/6/25 4:00', '2009/6/25 5:00', '2009/6/25 6:00', '2009/6/25 7:00', '2009/6/25 8:00', '2009/6/25 9:00', '2009/6/25 10:00', '2009/6/25 11:00', '2009/6/25 12:00', '2009/6/25 13:00', '2009/6/25 14:00', '2009/6/25 15:00', '2009/6/25 16:00', '2009/6/25 17:00', '2009/6/25 18:00', '2009/6/25 19:00', '2009/6/25 20:00', '2009/6/25 21:00', '2009/6/25 22:00', '2009/6/25 23:00',
-                '2009/6/26 0:00', '2009/6/26 1:00', '2009/6/26 2:00', '2009/6/26 3:00', '2009/6/26 4:00', '2009/6/26 5:00', '2009/6/26 6:00', '2009/6/26 7:00', '2009/6/26 8:00', '2009/6/26 9:00', '2009/6/26 10:00', '2009/6/26 11:00', '2009/6/26 12:00', '2009/6/26 13:00', '2009/6/26 14:00', '2009/6/26 15:00', '2009/6/26 16:00', '2009/6/26 17:00', '2009/6/26 18:00', '2009/6/26 19:00', '2009/6/26 20:00', '2009/6/26 21:00', '2009/6/26 22:00', '2009/6/26 23:00',
-                '2009/6/27 0:00', '2009/6/27 1:00', '2009/6/27 2:00', '2009/6/27 3:00', '2009/6/27 4:00', '2009/6/27 5:00', '2009/6/27 6:00', '2009/6/27 7:00', '2009/6/27 8:00', '2009/6/27 9:00', '2009/6/27 10:00', '2009/6/27 11:00', '2009/6/27 12:00', '2009/6/27 13:00', '2009/6/27 14:00', '2009/6/27 15:00', '2009/6/27 16:00', '2009/6/27 17:00', '2009/6/27 18:00', '2009/6/27 19:00', '2009/6/27 20:00', '2009/6/27 21:00', '2009/6/27 22:00', '2009/6/27 23:00',
-                '2009/6/28 0:00', '2009/6/28 1:00', '2009/6/28 2:00', '2009/6/28 3:00', '2009/6/28 4:00', '2009/6/28 5:00', '2009/6/28 6:00', '2009/6/28 7:00', '2009/6/28 8:00', '2009/6/28 9:00', '2009/6/28 10:00', '2009/6/28 11:00', '2009/6/28 12:00', '2009/6/28 13:00', '2009/6/28 14:00', '2009/6/28 15:00', '2009/6/28 16:00', '2009/6/28 17:00', '2009/6/28 18:00', '2009/6/28 19:00', '2009/6/28 20:00', '2009/6/28 21:00', '2009/6/28 22:00', '2009/6/28 23:00',
-                '2009/6/29 0:00', '2009/6/29 1:00', '2009/6/29 2:00', '2009/6/29 3:00', '2009/6/29 4:00', '2009/6/29 5:00', '2009/6/29 6:00', '2009/6/29 7:00', '2009/6/29 8:00', '2009/6/29 9:00', '2009/6/29 10:00', '2009/6/29 11:00', '2009/6/29 12:00', '2009/6/29 13:00', '2009/6/29 14:00', '2009/6/29 15:00', '2009/6/29 16:00', '2009/6/29 17:00', '2009/6/29 18:00', '2009/6/29 19:00', '2009/6/29 20:00', '2009/6/29 21:00', '2009/6/29 22:00', '2009/6/29 23:00',
-                '2009/6/30 0:00', '2009/6/30 1:00', '2009/6/30 2:00', '2009/6/30 3:00', '2009/6/30 4:00', '2009/6/30 5:00', '2009/6/30 6:00', '2009/6/30 7:00', '2009/6/30 8:00', '2009/6/30 9:00', '2009/6/30 10:00', '2009/6/30 11:00', '2009/6/30 12:00', '2009/6/30 13:00', '2009/6/30 14:00', '2009/6/30 15:00', '2009/6/30 16:00', '2009/6/30 17:00', '2009/6/30 18:00', '2009/6/30 19:00', '2009/6/30 20:00', '2009/6/30 21:00', '2009/6/30 22:00', '2009/6/30 23:00',
-                '2009/7/1 0:00', '2009/7/1 1:00', '2009/7/1 2:00', '2009/7/1 3:00', '2009/7/1 4:00', '2009/7/1 5:00', '2009/7/1 6:00', '2009/7/1 7:00', '2009/7/1 8:00', '2009/7/1 9:00', '2009/7/1 10:00', '2009/7/1 11:00', '2009/7/1 12:00', '2009/7/1 13:00', '2009/7/1 14:00', '2009/7/1 15:00', '2009/7/1 16:00', '2009/7/1 17:00', '2009/7/1 18:00', '2009/7/1 19:00', '2009/7/1 20:00', '2009/7/1 21:00', '2009/7/1 22:00', '2009/7/1 23:00',
-                '2009/7/2 0:00', '2009/7/2 1:00', '2009/7/2 2:00', '2009/7/2 3:00', '2009/7/2 4:00', '2009/7/2 5:00', '2009/7/2 6:00', '2009/7/2 7:00', '2009/7/2 8:00', '2009/7/2 9:00', '2009/7/2 10:00', '2009/7/2 11:00', '2009/7/2 12:00', '2009/7/2 13:00', '2009/7/2 14:00', '2009/7/2 15:00', '2009/7/2 16:00', '2009/7/2 17:00', '2009/7/2 18:00', '2009/7/2 19:00', '2009/7/2 20:00', '2009/7/2 21:00', '2009/7/2 22:00', '2009/7/2 23:00',
-                '2009/7/3 0:00', '2009/7/3 1:00', '2009/7/3 2:00', '2009/7/3 3:00', '2009/7/3 4:00', '2009/7/3 5:00', '2009/7/3 6:00', '2009/7/3 7:00', '2009/7/3 8:00', '2009/7/3 9:00', '2009/7/3 10:00', '2009/7/3 11:00', '2009/7/3 12:00', '2009/7/3 13:00', '2009/7/3 14:00', '2009/7/3 15:00', '2009/7/3 16:00', '2009/7/3 17:00', '2009/7/3 18:00', '2009/7/3 19:00', '2009/7/3 20:00', '2009/7/3 21:00', '2009/7/3 22:00', '2009/7/3 23:00',
-                '2009/7/4 0:00', '2009/7/4 1:00', '2009/7/4 2:00', '2009/7/4 3:00', '2009/7/4 4:00', '2009/7/4 5:00', '2009/7/4 6:00', '2009/7/4 7:00', '2009/7/4 8:00', '2009/7/4 9:00', '2009/7/4 10:00', '2009/7/4 11:00', '2009/7/4 12:00', '2009/7/4 13:00', '2009/7/4 14:00', '2009/7/4 15:00', '2009/7/4 16:00', '2009/7/4 17:00', '2009/7/4 18:00', '2009/7/4 19:00', '2009/7/4 20:00', '2009/7/4 21:00', '2009/7/4 22:00', '2009/7/4 23:00',
-                '2009/7/5 0:00', '2009/7/5 1:00', '2009/7/5 2:00', '2009/7/5 3:00', '2009/7/5 4:00', '2009/7/5 5:00', '2009/7/5 6:00', '2009/7/5 7:00', '2009/7/5 8:00', '2009/7/5 9:00', '2009/7/5 10:00', '2009/7/5 11:00', '2009/7/5 12:00', '2009/7/5 13:00', '2009/7/5 14:00', '2009/7/5 15:00', '2009/7/5 16:00', '2009/7/5 17:00', '2009/7/5 18:00', '2009/7/5 19:00', '2009/7/5 20:00', '2009/7/5 21:00', '2009/7/5 22:00', '2009/7/5 23:00',
-                '2009/7/6 0:00', '2009/7/6 1:00', '2009/7/6 2:00', '2009/7/6 3:00', '2009/7/6 4:00', '2009/7/6 5:00', '2009/7/6 6:00', '2009/7/6 7:00', '2009/7/6 8:00', '2009/7/6 9:00', '2009/7/6 10:00', '2009/7/6 11:00', '2009/7/6 12:00', '2009/7/6 13:00', '2009/7/6 14:00', '2009/7/6 15:00', '2009/7/6 16:00', '2009/7/6 17:00', '2009/7/6 18:00', '2009/7/6 19:00', '2009/7/6 20:00', '2009/7/6 21:00', '2009/7/6 22:00', '2009/7/6 23:00',
-                '2009/7/7 0:00', '2009/7/7 1:00', '2009/7/7 2:00', '2009/7/7 3:00', '2009/7/7 4:00', '2009/7/7 5:00', '2009/7/7 6:00', '2009/7/7 7:00', '2009/7/7 8:00', '2009/7/7 9:00', '2009/7/7 10:00', '2009/7/7 11:00', '2009/7/7 12:00', '2009/7/7 13:00', '2009/7/7 14:00', '2009/7/7 15:00', '2009/7/7 16:00', '2009/7/7 17:00', '2009/7/7 18:00', '2009/7/7 19:00', '2009/7/7 20:00', '2009/7/7 21:00', '2009/7/7 22:00', '2009/7/7 23:00',
-                '2009/7/8 0:00', '2009/7/8 1:00', '2009/7/8 2:00', '2009/7/8 3:00', '2009/7/8 4:00', '2009/7/8 5:00', '2009/7/8 6:00', '2009/7/8 7:00', '2009/7/8 8:00', '2009/7/8 9:00', '2009/7/8 10:00', '2009/7/8 11:00', '2009/7/8 12:00', '2009/7/8 13:00', '2009/7/8 14:00', '2009/7/8 15:00', '2009/7/8 16:00', '2009/7/8 17:00', '2009/7/8 18:00', '2009/7/8 19:00', '2009/7/8 20:00', '2009/7/8 21:00', '2009/7/8 22:00', '2009/7/8 23:00',
-                '2009/7/9 0:00', '2009/7/9 1:00', '2009/7/9 2:00', '2009/7/9 3:00', '2009/7/9 4:00', '2009/7/9 5:00', '2009/7/9 6:00', '2009/7/9 7:00', '2009/7/9 8:00', '2009/7/9 9:00', '2009/7/9 10:00', '2009/7/9 11:00', '2009/7/9 12:00', '2009/7/9 13:00', '2009/7/9 14:00', '2009/7/9 15:00', '2009/7/9 16:00', '2009/7/9 17:00', '2009/7/9 18:00', '2009/7/9 19:00', '2009/7/9 20:00', '2009/7/9 21:00', '2009/7/9 22:00', '2009/7/9 23:00',
-                '2009/7/10 0:00', '2009/7/10 1:00', '2009/7/10 2:00', '2009/7/10 3:00', '2009/7/10 4:00', '2009/7/10 5:00', '2009/7/10 6:00', '2009/7/10 7:00', '2009/7/10 8:00', '2009/7/10 9:00', '2009/7/10 10:00', '2009/7/10 11:00', '2009/7/10 12:00', '2009/7/10 13:00', '2009/7/10 14:00', '2009/7/10 15:00', '2009/7/10 16:00', '2009/7/10 17:00', '2009/7/10 18:00', '2009/7/10 19:00', '2009/7/10 20:00', '2009/7/10 21:00', '2009/7/10 22:00', '2009/7/10 23:00',
-                '2009/7/11 0:00', '2009/7/11 1:00', '2009/7/11 2:00', '2009/7/11 3:00', '2009/7/11 4:00', '2009/7/11 5:00', '2009/7/11 6:00', '2009/7/11 7:00', '2009/7/11 8:00', '2009/7/11 9:00', '2009/7/11 10:00', '2009/7/11 11:00', '2009/7/11 12:00', '2009/7/11 13:00', '2009/7/11 14:00', '2009/7/11 15:00', '2009/7/11 16:00', '2009/7/11 17:00', '2009/7/11 18:00', '2009/7/11 19:00', '2009/7/11 20:00', '2009/7/11 21:00', '2009/7/11 22:00', '2009/7/11 23:00',
-                '2009/7/12 0:00', '2009/7/12 1:00', '2009/7/12 2:00', '2009/7/12 3:00', '2009/7/12 4:00', '2009/7/12 5:00', '2009/7/12 6:00', '2009/7/12 7:00', '2009/7/12 8:00', '2009/7/12 9:00', '2009/7/12 10:00', '2009/7/12 11:00', '2009/7/12 12:00', '2009/7/12 13:00', '2009/7/12 14:00', '2009/7/12 15:00', '2009/7/12 16:00', '2009/7/12 17:00', '2009/7/12 18:00', '2009/7/12 19:00', '2009/7/12 20:00', '2009/7/12 21:00', '2009/7/12 22:00', '2009/7/12 23:00',
-                '2009/7/13 0:00', '2009/7/13 1:00', '2009/7/13 2:00', '2009/7/13 3:00', '2009/7/13 4:00', '2009/7/13 5:00', '2009/7/13 6:00', '2009/7/13 7:00', '2009/7/13 8:00', '2009/7/13 9:00', '2009/7/13 10:00', '2009/7/13 11:00', '2009/7/13 12:00', '2009/7/13 13:00', '2009/7/13 14:00', '2009/7/13 15:00', '2009/7/13 16:00', '2009/7/13 17:00', '2009/7/13 18:00', '2009/7/13 19:00', '2009/7/13 20:00', '2009/7/13 21:00', '2009/7/13 22:00', '2009/7/13 23:00',
-                '2009/7/14 0:00', '2009/7/14 1:00', '2009/7/14 2:00', '2009/7/14 3:00', '2009/7/14 4:00', '2009/7/14 5:00', '2009/7/14 6:00', '2009/7/14 7:00', '2009/7/14 8:00', '2009/7/14 9:00', '2009/7/14 10:00', '2009/7/14 11:00', '2009/7/14 12:00', '2009/7/14 13:00', '2009/7/14 14:00', '2009/7/14 15:00', '2009/7/14 16:00', '2009/7/14 17:00', '2009/7/14 18:00', '2009/7/14 19:00', '2009/7/14 20:00', '2009/7/14 21:00', '2009/7/14 22:00', '2009/7/14 23:00',
-                '2009/7/15 0:00', '2009/7/15 1:00', '2009/7/15 2:00', '2009/7/15 3:00', '2009/7/15 4:00', '2009/7/15 5:00', '2009/7/15 6:00', '2009/7/15 7:00', '2009/7/15 8:00', '2009/7/15 9:00', '2009/7/15 10:00', '2009/7/15 11:00', '2009/7/15 12:00', '2009/7/15 13:00', '2009/7/15 14:00', '2009/7/15 15:00', '2009/7/15 16:00', '2009/7/15 17:00', '2009/7/15 18:00', '2009/7/15 19:00', '2009/7/15 20:00', '2009/7/15 21:00', '2009/7/15 22:00', '2009/7/15 23:00',
-                '2009/7/16 0:00', '2009/7/16 1:00', '2009/7/16 2:00', '2009/7/16 3:00', '2009/7/16 4:00', '2009/7/16 5:00', '2009/7/16 6:00', '2009/7/16 7:00', '2009/7/16 8:00', '2009/7/16 9:00', '2009/7/16 10:00', '2009/7/16 11:00', '2009/7/16 12:00', '2009/7/16 13:00', '2009/7/16 14:00', '2009/7/16 15:00', '2009/7/16 16:00', '2009/7/16 17:00', '2009/7/16 18:00', '2009/7/16 19:00', '2009/7/16 20:00', '2009/7/16 21:00', '2009/7/16 22:00', '2009/7/16 23:00',
-                '2009/7/17 0:00', '2009/7/17 1:00', '2009/7/17 2:00', '2009/7/17 3:00', '2009/7/17 4:00', '2009/7/17 5:00', '2009/7/17 6:00', '2009/7/17 7:00', '2009/7/17 8:00', '2009/7/17 9:00', '2009/7/17 10:00', '2009/7/17 11:00', '2009/7/17 12:00', '2009/7/17 13:00', '2009/7/17 14:00', '2009/7/17 15:00', '2009/7/17 16:00', '2009/7/17 17:00', '2009/7/17 18:00', '2009/7/17 19:00', '2009/7/17 20:00', '2009/7/17 21:00', '2009/7/17 22:00', '2009/7/17 23:00',
-                '2009/7/18 0:00', '2009/7/18 1:00', '2009/7/18 2:00', '2009/7/18 3:00', '2009/7/18 4:00', '2009/7/18 5:00', '2009/7/18 6:00', '2009/7/18 7:00', '2009/7/18 8:00', '2009/7/18 9:00', '2009/7/18 10:00', '2009/7/18 11:00', '2009/7/18 12:00', '2009/7/18 13:00', '2009/7/18 14:00', '2009/7/18 15:00', '2009/7/18 16:00', '2009/7/18 17:00', '2009/7/18 18:00', '2009/7/18 19:00', '2009/7/18 20:00', '2009/7/18 21:00', '2009/7/18 22:00', '2009/7/18 23:00',
-                '2009/7/19 0:00', '2009/7/19 1:00', '2009/7/19 2:00', '2009/7/19 3:00', '2009/7/19 4:00', '2009/7/19 5:00', '2009/7/19 6:00', '2009/7/19 7:00', '2009/7/19 8:00', '2009/7/19 9:00', '2009/7/19 10:00', '2009/7/19 11:00', '2009/7/19 12:00', '2009/7/19 13:00', '2009/7/19 14:00', '2009/7/19 15:00', '2009/7/19 16:00', '2009/7/19 17:00', '2009/7/19 18:00', '2009/7/19 19:00', '2009/7/19 20:00', '2009/7/19 21:00', '2009/7/19 22:00', '2009/7/19 23:00',
-                '2009/7/20 0:00', '2009/7/20 1:00', '2009/7/20 2:00', '2009/7/20 3:00', '2009/7/20 4:00', '2009/7/20 5:00', '2009/7/20 6:00', '2009/7/20 7:00', '2009/7/20 8:00', '2009/7/20 9:00', '2009/7/20 10:00', '2009/7/20 11:00', '2009/7/20 12:00', '2009/7/20 13:00', '2009/7/20 14:00', '2009/7/20 15:00', '2009/7/20 16:00', '2009/7/20 17:00', '2009/7/20 18:00', '2009/7/20 19:00', '2009/7/20 20:00', '2009/7/20 21:00', '2009/7/20 22:00', '2009/7/20 23:00',
-                '2009/7/21 0:00', '2009/7/21 1:00', '2009/7/21 2:00', '2009/7/21 3:00', '2009/7/21 4:00', '2009/7/21 5:00', '2009/7/21 6:00', '2009/7/21 7:00', '2009/7/21 8:00', '2009/7/21 9:00', '2009/7/21 10:00', '2009/7/21 11:00', '2009/7/21 12:00', '2009/7/21 13:00', '2009/7/21 14:00', '2009/7/21 15:00', '2009/7/21 16:00', '2009/7/21 17:00', '2009/7/21 18:00', '2009/7/21 19:00', '2009/7/21 20:00', '2009/7/21 21:00', '2009/7/21 22:00', '2009/7/21 23:00',
-                '2009/7/22 0:00', '2009/7/22 1:00', '2009/7/22 2:00', '2009/7/22 3:00', '2009/7/22 4:00', '2009/7/22 5:00', '2009/7/22 6:00', '2009/7/22 7:00', '2009/7/22 8:00', '2009/7/22 9:00', '2009/7/22 10:00', '2009/7/22 11:00', '2009/7/22 12:00', '2009/7/22 13:00', '2009/7/22 14:00', '2009/7/22 15:00', '2009/7/22 16:00', '2009/7/22 17:00', '2009/7/22 18:00', '2009/7/22 19:00', '2009/7/22 20:00', '2009/7/22 21:00', '2009/7/22 22:00', '2009/7/22 23:00',
-                '2009/7/23 0:00', '2009/7/23 1:00', '2009/7/23 2:00', '2009/7/23 3:00', '2009/7/23 4:00', '2009/7/23 5:00', '2009/7/23 6:00', '2009/7/23 7:00', '2009/7/23 8:00', '2009/7/23 9:00', '2009/7/23 10:00', '2009/7/23 11:00', '2009/7/23 12:00', '2009/7/23 13:00', '2009/7/23 14:00', '2009/7/23 15:00', '2009/7/23 16:00', '2009/7/23 17:00', '2009/7/23 18:00', '2009/7/23 19:00', '2009/7/23 20:00', '2009/7/23 21:00', '2009/7/23 22:00', '2009/7/23 23:00',
-                '2009/7/24 0:00', '2009/7/24 1:00', '2009/7/24 2:00', '2009/7/24 3:00', '2009/7/24 4:00', '2009/7/24 5:00', '2009/7/24 6:00', '2009/7/24 7:00', '2009/7/24 8:00', '2009/7/24 9:00', '2009/7/24 10:00', '2009/7/24 11:00', '2009/7/24 12:00', '2009/7/24 13:00', '2009/7/24 14:00', '2009/7/24 15:00', '2009/7/24 16:00', '2009/7/24 17:00', '2009/7/24 18:00', '2009/7/24 19:00', '2009/7/24 20:00', '2009/7/24 21:00', '2009/7/24 22:00', '2009/7/24 23:00',
-                '2009/7/25 0:00', '2009/7/25 1:00', '2009/7/25 2:00', '2009/7/25 3:00', '2009/7/25 4:00', '2009/7/25 5:00', '2009/7/25 6:00', '2009/7/25 7:00', '2009/7/25 8:00', '2009/7/25 9:00', '2009/7/25 10:00', '2009/7/25 11:00', '2009/7/25 12:00', '2009/7/25 13:00', '2009/7/25 14:00', '2009/7/25 15:00', '2009/7/25 16:00', '2009/7/25 17:00', '2009/7/25 18:00', '2009/7/25 19:00', '2009/7/25 20:00', '2009/7/25 21:00', '2009/7/25 22:00', '2009/7/25 23:00',
-                '2009/7/26 0:00', '2009/7/26 1:00', '2009/7/26 2:00', '2009/7/26 3:00', '2009/7/26 4:00', '2009/7/26 5:00', '2009/7/26 6:00', '2009/7/26 7:00', '2009/7/26 8:00', '2009/7/26 9:00', '2009/7/26 10:00', '2009/7/26 11:00', '2009/7/26 12:00', '2009/7/26 13:00', '2009/7/26 14:00', '2009/7/26 15:00', '2009/7/26 16:00', '2009/7/26 17:00', '2009/7/26 18:00', '2009/7/26 19:00', '2009/7/26 20:00', '2009/7/26 21:00', '2009/7/26 22:00', '2009/7/26 23:00',
-                '2009/7/27 0:00', '2009/7/27 1:00', '2009/7/27 2:00', '2009/7/27 3:00', '2009/7/27 4:00', '2009/7/27 5:00', '2009/7/27 6:00', '2009/7/27 7:00', '2009/7/27 8:00', '2009/7/27 9:00', '2009/7/27 10:00', '2009/7/27 11:00', '2009/7/27 12:00', '2009/7/27 13:00', '2009/7/27 14:00', '2009/7/27 15:00', '2009/7/27 16:00', '2009/7/27 17:00', '2009/7/27 18:00', '2009/7/27 19:00', '2009/7/27 20:00', '2009/7/27 21:00', '2009/7/27 22:00', '2009/7/27 23:00',
-                '2009/7/28 0:00', '2009/7/28 1:00', '2009/7/28 2:00', '2009/7/28 3:00', '2009/7/28 4:00', '2009/7/28 5:00', '2009/7/28 6:00', '2009/7/28 7:00', '2009/7/28 8:00', '2009/7/28 9:00', '2009/7/28 10:00', '2009/7/28 11:00', '2009/7/28 12:00', '2009/7/28 13:00', '2009/7/28 14:00', '2009/7/28 15:00', '2009/7/28 16:00', '2009/7/28 17:00', '2009/7/28 18:00', '2009/7/28 19:00', '2009/7/28 20:00', '2009/7/28 21:00', '2009/7/28 22:00', '2009/7/28 23:00',
-                '2009/7/29 0:00', '2009/7/29 1:00', '2009/7/29 2:00', '2009/7/29 3:00', '2009/7/29 4:00', '2009/7/29 5:00', '2009/7/29 6:00', '2009/7/29 7:00', '2009/7/29 8:00', '2009/7/29 9:00', '2009/7/29 10:00', '2009/7/29 11:00', '2009/7/29 12:00', '2009/7/29 13:00', '2009/7/29 14:00', '2009/7/29 15:00', '2009/7/29 16:00', '2009/7/29 17:00', '2009/7/29 18:00', '2009/7/29 19:00', '2009/7/29 20:00', '2009/7/29 21:00', '2009/7/29 22:00', '2009/7/29 23:00',
-                '2009/7/30 0:00', '2009/7/30 1:00', '2009/7/30 2:00', '2009/7/30 3:00', '2009/7/30 4:00', '2009/7/30 5:00', '2009/7/30 6:00', '2009/7/30 7:00', '2009/7/30 8:00', '2009/7/30 9:00', '2009/7/30 10:00', '2009/7/30 11:00', '2009/7/30 12:00', '2009/7/30 13:00', '2009/7/30 14:00', '2009/7/30 15:00', '2009/7/30 16:00', '2009/7/30 17:00', '2009/7/30 18:00', '2009/7/30 19:00', '2009/7/30 20:00', '2009/7/30 21:00', '2009/7/30 22:00', '2009/7/30 23:00',
-                '2009/7/31 0:00', '2009/7/31 1:00', '2009/7/31 2:00', '2009/7/31 3:00', '2009/7/31 4:00', '2009/7/31 5:00', '2009/7/31 6:00', '2009/7/31 7:00', '2009/7/31 8:00', '2009/7/31 9:00', '2009/7/31 10:00', '2009/7/31 11:00', '2009/7/31 12:00', '2009/7/31 13:00', '2009/7/31 14:00', '2009/7/31 15:00', '2009/7/31 16:00', '2009/7/31 17:00', '2009/7/31 18:00', '2009/7/31 19:00', '2009/7/31 20:00', '2009/7/31 21:00', '2009/7/31 22:00', '2009/7/31 23:00',
-                '2009/8/1 0:00', '2009/8/1 1:00', '2009/8/1 2:00', '2009/8/1 3:00', '2009/8/1 4:00', '2009/8/1 5:00', '2009/8/1 6:00', '2009/8/1 7:00', '2009/8/1 8:00', '2009/8/1 9:00', '2009/8/1 10:00', '2009/8/1 11:00', '2009/8/1 12:00', '2009/8/1 13:00', '2009/8/1 14:00', '2009/8/1 15:00', '2009/8/1 16:00', '2009/8/1 17:00', '2009/8/1 18:00', '2009/8/1 19:00', '2009/8/1 20:00', '2009/8/1 21:00', '2009/8/1 22:00', '2009/8/1 23:00', '2009/8/2 0:00', '2009/8/2 1:00', '2009/8/2 2:00', '20 [...]
-                '2009/9/1 0:00', '2009/9/1 1:00', '2009/9/1 2:00', '2009/9/1 3:00', '2009/9/1 4:00', '2009/9/1 5:00', '2009/9/1 6:00', '2009/9/1 7:00', '2009/9/1 8:00', '2009/9/1 9:00', '2009/9/1 10:00', '2009/9/1 11:00', '2009/9/1 12:00', '2009/9/1 13:00', '2009/9/1 14:00', '2009/9/1 15:00', '2009/9/1 16:00', '2009/9/1 17:00', '2009/9/1 18:00', '2009/9/1 19:00', '2009/9/1 20:00', '2009/9/1 21:00', '2009/9/1 22:00', '2009/9/1 23:00', '2009/9/2 0:00', '2009/9/2 1:00', '2009/9/2 2:00', '20 [...]
-                '2009/10/1 0:00', '2009/10/1 1:00', '2009/10/1 2:00', '2009/10/1 3:00', '2009/10/1 4:00', '2009/10/1 5:00', '2009/10/1 6:00', '2009/10/1 7:00', '2009/10/1 8:00', '2009/10/1 9:00', '2009/10/1 10:00', '2009/10/1 11:00', '2009/10/1 12:00', '2009/10/1 13:00', '2009/10/1 14:00', '2009/10/1 15:00', '2009/10/1 16:00', '2009/10/1 17:00', '2009/10/1 18:00', '2009/10/1 19:00', '2009/10/1 20:00', '2009/10/1 21:00', '2009/10/1 22:00', '2009/10/1 23:00', '2009/10/2 0:00', '2009/10/2 1 [...]
-            ].map(function (str) {
-                return str.replace(' ', '\n');
-            })
-        }
-    ],
-    yAxis: [
-        {
-            name: 'Flow(m^3/s)',
-            type: 'value',
-            max: 500
-        },
-        {
-            name: 'Rainfall(mm)',
-            nameLocation: 'start',
-            max: 5,
-            type: 'value',
-            inverse: true
-        }
-    ],
-    series: [
-        {
-            name: 'Flow',
-            type: 'line',
-            areaStyle: {},
-            lineStyle: {
-                width: 1
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            markArea: {
-                silent: true,
-                itemStyle: {
-                    opacity: 0.3
-                },
-                data: [[{
-                    xAxis: '2009/9/12\n7:00'
-                }, {
-                    xAxis: '2009/9/22\n7:00'
-                }]]
-            },
-            data: [
-                0.97,0.96,0.96,0.95,0.95,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0 [...]
-            ]
+    {
+      name: 'Rainfall',
+      type: 'line',
+      yAxisIndex: 1,
+      areaStyle: {},
+      lineStyle: {
+        width: 1
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      markArea: {
+        silent: true,
+        itemStyle: {
+          opacity: 0.3
         },
-        {
-            name: 'Rainfall',
-            type: 'line',
-            yAxisIndex: 1,
-            areaStyle: {},
-            lineStyle: {
-                width: 1
-            },
-            emphasis: {
-                focus: 'series'
+        data: [
+          [
+            {
+              xAxis: '2009/9/10\n7:00'
             },
-            markArea: {
-                silent: true,
-                itemStyle: {
-                    opacity: 0.3
-                },
-                data: [
-                    [{
-                        xAxis: '2009/9/10\n7:00'
-                    }, {
-                        xAxis: '2009/9/20\n7:00'
-                    }]
-                ]
-            },
-            data: [
-                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.005,0.017,0.017,0.017,0.017,0.011,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.021,0.026,0.03,0.036,0.036,0.195,0.221,0.019,0.013,0.017,0.03,0.03,0.03,0.046,0.045,0.038,0.084,0.045,0.045,0.037,0.034,0.035,0.036,0.044,0.052,0.048,0.109,0.033,0.029,0.04,0.042,0.042,0.042,0.073,0.076,0.062,0.066,0.066,0.075,0.096,0.128 [...]
-            ]
-        }
-    ]
+            {
+              xAxis: '2009/9/20\n7:00'
+            }
+          ]
+        ]
+      },
+      // prettier-ignore
+      data: [
+        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.005,0.017,0.017,0.017,0.017,0.011,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.021,0.026,0.03,0.036,0.036,0.195,0.221,0.019,0.013,0.017,0.03,0.03,0.03,0.046,0.045,0.038,0.084,0.045,0.045,0.037,0.034,0.035,0.036,0.044,0.052,0.048,0.109,0.033,0.029,0.04,0.042,0.042,0.042,0.073,0.076,0.062,0.066,0.066,0.075,0.096,0.128,0.121,0 [...]
+      ]
+    }
+  ]
 };
 
-
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/area-simple.ts b/public/examples/ts/area-simple.ts
index 8ab9c88..892fc05 100644
--- a/public/examples/ts/area-simple.ts
+++ b/public/examples/ts/area-simple.ts
@@ -12,69 +12,75 @@ let date = [];
 let data = [Math.random() * 300];
 
 for (let i = 1; i < 20000; i++) {
-    var now = new Date(base += oneDay);
-    date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
-    data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));
+  var now = new Date((base += oneDay));
+  date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
+  data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));
 }
 
 option = {
-    tooltip: {
-        trigger: 'axis',
-        position: function (pt) {
-            return [pt[0], '10%'];
-        }
+  tooltip: {
+    trigger: 'axis',
+    position: function (pt) {
+      return [pt[0], '10%'];
+    }
+  },
+  title: {
+    left: 'center',
+    text: 'Large Area Chart'
+  },
+  toolbox: {
+    feature: {
+      dataZoom: {
+        yAxisIndex: 'none'
+      },
+      restore: {},
+      saveAsImage: {}
+    }
+  },
+  xAxis: {
+    type: 'category',
+    boundaryGap: false,
+    data: date
+  },
+  yAxis: {
+    type: 'value',
+    boundaryGap: [0, '100%']
+  },
+  dataZoom: [
+    {
+      type: 'inside',
+      start: 0,
+      end: 10
     },
-    title: {
-        left: 'center',
-        text: 'Large Area Chart',
-    },
-    toolbox: {
-        feature: {
-            dataZoom: {
-                yAxisIndex: 'none'
-            },
-            restore: {},
-            saveAsImage: {}
-        }
-    },
-    xAxis: {
-        type: 'category',
-        boundaryGap: false,
-        data: date
-    },
-    yAxis: {
-        type: 'value',
-        boundaryGap: [0, '100%']
-    },
-    dataZoom: [{
-        type: 'inside',
-        start: 0,
-        end: 10
-    }, {
-        start: 0,
-        end: 10
-    }],
-    series: [
-        {
-            name: 'Fake Data',
-            type: 'line',
-            symbol: 'none',
-            sampling: 'lttb',
-            itemStyle: {
-                color: 'rgb(255, 70, 131)'
-            },
-            areaStyle: {
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
-                    offset: 0,
-                    color: 'rgb(255, 158, 68)'
-                }, {
-                    offset: 1,
-                    color: 'rgb(255, 70, 131)'
-                }])
-            },
-            data: data
-        }
-    ]
+    {
+      start: 0,
+      end: 10
+    }
+  ],
+  series: [
+    {
+      name: 'Fake Data',
+      type: 'line',
+      symbol: 'none',
+      sampling: 'lttb',
+      itemStyle: {
+        color: 'rgb(255, 70, 131)'
+      },
+      areaStyle: {
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: 'rgb(255, 158, 68)'
+          },
+          {
+            offset: 1,
+            color: 'rgb(255, 70, 131)'
+          }
+        ])
+      },
+      data: data
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/area-stack-gradient.ts b/public/examples/ts/area-stack-gradient.ts
index 8ab69ca..16ac77a 100644
--- a/public/examples/ts/area-stack-gradient.ts
+++ b/public/examples/ts/area-stack-gradient.ts
@@ -6,171 +6,186 @@ difficulty: 2
 */
 
 option = {
-    color: ['#80FFA5', '#00DDFF', '#37A2FF', '#FF0087', '#FFBF00'],
-    title: {
-        text: 'Gradient Stacked Area Chart'
+  color: ['#80FFA5', '#00DDFF', '#37A2FF', '#FF0087', '#FFBF00'],
+  title: {
+    text: 'Gradient Stacked Area Chart'
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'cross',
+      label: {
+        backgroundColor: '#6a7985'
+      }
+    }
+  },
+  legend: {
+    data: ['Line 1', 'Line 2', 'Line 3', 'Line 4', 'Line 5']
+  },
+  toolbox: {
+    feature: {
+      saveAsImage: {}
+    }
+  },
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '3%',
+    containLabel: true
+  },
+  xAxis: [
+    {
+      type: 'category',
+      boundaryGap: false,
+      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+    }
+  ],
+  yAxis: [
+    {
+      type: 'value'
+    }
+  ],
+  series: [
+    {
+      name: 'Line 1',
+      type: 'line',
+      stack: 'Total',
+      smooth: true,
+      lineStyle: {
+        width: 0
+      },
+      showSymbol: false,
+      areaStyle: {
+        opacity: 0.8,
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: 'rgba(128, 255, 165)'
+          },
+          {
+            offset: 1,
+            color: 'rgba(1, 191, 236)'
+          }
+        ])
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [140, 232, 101, 264, 90, 340, 250]
     },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'cross',
-            label: {
-                backgroundColor: '#6a7985'
-            }
-        }
+    {
+      name: 'Line 2',
+      type: 'line',
+      stack: 'Total',
+      smooth: true,
+      lineStyle: {
+        width: 0
+      },
+      showSymbol: false,
+      areaStyle: {
+        opacity: 0.8,
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: 'rgba(0, 221, 255)'
+          },
+          {
+            offset: 1,
+            color: 'rgba(77, 119, 255)'
+          }
+        ])
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [120, 282, 111, 234, 220, 340, 310]
     },
-    legend: {
-        data: ['Line 1', 'Line 2', 'Line 3', 'Line 4', 'Line 5']
+    {
+      name: 'Line 3',
+      type: 'line',
+      stack: 'Total',
+      smooth: true,
+      lineStyle: {
+        width: 0
+      },
+      showSymbol: false,
+      areaStyle: {
+        opacity: 0.8,
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: 'rgba(55, 162, 255)'
+          },
+          {
+            offset: 1,
+            color: 'rgba(116, 21, 219)'
+          }
+        ])
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [320, 132, 201, 334, 190, 130, 220]
     },
-    toolbox: {
-        feature: {
-            saveAsImage: {}
-        }
+    {
+      name: 'Line 4',
+      type: 'line',
+      stack: 'Total',
+      smooth: true,
+      lineStyle: {
+        width: 0
+      },
+      showSymbol: false,
+      areaStyle: {
+        opacity: 0.8,
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: 'rgba(255, 0, 135)'
+          },
+          {
+            offset: 1,
+            color: 'rgba(135, 0, 157)'
+          }
+        ])
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [220, 402, 231, 134, 190, 230, 120]
     },
-    grid: {
-        left: '3%',
-        right: '4%',
-        bottom: '3%',
-        containLabel: true
-    },
-    xAxis: [
-        {
-            type: 'category',
-            boundaryGap: false,
-            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-        }
-    ],
-    yAxis: [
-        {
-            type: 'value'
-        }
-    ],
-    series: [
-        {
-            name: 'Line 1',
-            type: 'line',
-            stack: 'Total',
-            smooth: true,
-            lineStyle: {
-                width: 0
-            },
-            showSymbol: false,
-            areaStyle: {
-                opacity: 0.8,
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
-                    offset: 0,
-                    color: 'rgba(128, 255, 165)'
-                }, {
-                    offset: 1,
-                    color: 'rgba(1, 191, 236)'
-                }])
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [140, 232, 101, 264, 90, 340, 250]
-        },
-        {
-            name: 'Line 2',
-            type: 'line',
-            stack: 'Total',
-            smooth: true,
-            lineStyle: {
-                width: 0
-            },
-            showSymbol: false,
-            areaStyle: {
-                opacity: 0.8,
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
-                    offset: 0,
-                    color: 'rgba(0, 221, 255)'
-                }, {
-                    offset: 1,
-                    color: 'rgba(77, 119, 255)'
-                }])
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [120, 282, 111, 234, 220, 340, 310]
-        },
-        {
-            name: 'Line 3',
-            type: 'line',
-            stack: 'Total',
-            smooth: true,
-            lineStyle: {
-                width: 0
-            },
-            showSymbol: false,
-            areaStyle: {
-                opacity: 0.8,
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
-                    offset: 0,
-                    color: 'rgba(55, 162, 255)'
-                }, {
-                    offset: 1,
-                    color: 'rgba(116, 21, 219)'
-                }])
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [320, 132, 201, 334, 190, 130, 220]
-        },
-        {
-            name: 'Line 4',
-            type: 'line',
-            stack: 'Total',
-            smooth: true,
-            lineStyle: {
-                width: 0
-            },
-            showSymbol: false,
-            areaStyle: {
-                opacity: 0.8,
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
-                    offset: 0,
-                    color: 'rgba(255, 0, 135)'
-                }, {
-                    offset: 1,
-                    color: 'rgba(135, 0, 157)'
-                }])
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [220, 402, 231, 134, 190, 230, 120]
-        },
-        {
-            name: 'Line 5',
-            type: 'line',
-            stack: 'Total',
-            smooth: true,
-            lineStyle: {
-                width: 0
-            },
-            showSymbol: false,
-            label: {
-                show: true,
-                position: 'top'
-            },
-            areaStyle: {
-                opacity: 0.8,
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
-                    offset: 0,
-                    color: 'rgba(255, 191, 0)'
-                }, {
-                    offset: 1,
-                    color: 'rgba(224, 62, 76)'
-                }])
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [220, 302, 181, 234, 210, 290, 150]
-        }
-    ]
+    {
+      name: 'Line 5',
+      type: 'line',
+      stack: 'Total',
+      smooth: true,
+      lineStyle: {
+        width: 0
+      },
+      showSymbol: false,
+      label: {
+        show: true,
+        position: 'top'
+      },
+      areaStyle: {
+        opacity: 0.8,
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: 'rgba(255, 191, 0)'
+          },
+          {
+            offset: 1,
+            color: 'rgba(224, 62, 76)'
+          }
+        ])
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [220, 302, 181, 234, 210, 290, 150]
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/area-stack.ts b/public/examples/ts/area-stack.ts
index 3b0683c..3cb38b2 100644
--- a/public/examples/ts/area-stack.ts
+++ b/public/examples/ts/area-stack.ts
@@ -6,100 +6,100 @@ difficulty: 2
 */
 
 option = {
-    title: {
-        text: 'Stacked Area Chart'
+  title: {
+    text: 'Stacked Area Chart'
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'cross',
+      label: {
+        backgroundColor: '#6a7985'
+      }
+    }
+  },
+  legend: {
+    data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
+  },
+  toolbox: {
+    feature: {
+      saveAsImage: {}
+    }
+  },
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '3%',
+    containLabel: true
+  },
+  xAxis: [
+    {
+      type: 'category',
+      boundaryGap: false,
+      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+    }
+  ],
+  yAxis: [
+    {
+      type: 'value'
+    }
+  ],
+  series: [
+    {
+      name: 'Email',
+      type: 'line',
+      stack: 'Total',
+      areaStyle: {},
+      emphasis: {
+        focus: 'series'
+      },
+      data: [120, 132, 101, 134, 90, 230, 210]
     },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'cross',
-            label: {
-                backgroundColor: '#6a7985'
-            }
-        }
+    {
+      name: 'Union Ads',
+      type: 'line',
+      stack: 'Total',
+      areaStyle: {},
+      emphasis: {
+        focus: 'series'
+      },
+      data: [220, 182, 191, 234, 290, 330, 310]
     },
-    legend: {
-        data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
+    {
+      name: 'Video Ads',
+      type: 'line',
+      stack: 'Total',
+      areaStyle: {},
+      emphasis: {
+        focus: 'series'
+      },
+      data: [150, 232, 201, 154, 190, 330, 410]
     },
-    toolbox: {
-        feature: {
-            saveAsImage: {}
-        }
+    {
+      name: 'Direct',
+      type: 'line',
+      stack: 'Total',
+      areaStyle: {},
+      emphasis: {
+        focus: 'series'
+      },
+      data: [320, 332, 301, 334, 390, 330, 320]
     },
-    grid: {
-        left: '3%',
-        right: '4%',
-        bottom: '3%',
-        containLabel: true
-    },
-    xAxis: [
-        {
-            type: 'category',
-            boundaryGap: false,
-            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-        }
-    ],
-    yAxis: [
-        {
-            type: 'value'
-        }
-    ],
-    series: [
-        {
-            name: 'Email',
-            type: 'line',
-            stack: 'Total',
-            areaStyle: {},
-            emphasis: {
-                focus: 'series'
-            },
-            data: [120, 132, 101, 134, 90, 230, 210]
-        },
-        {
-            name: 'Union Ads',
-            type: 'line',
-            stack: 'Total',
-            areaStyle: {},
-            emphasis: {
-                focus: 'series'
-            },
-            data: [220, 182, 191, 234, 290, 330, 310]
-        },
-        {
-            name: 'Video Ads',
-            type: 'line',
-            stack: 'Total',
-            areaStyle: {},
-            emphasis: {
-                focus: 'series'
-            },
-            data: [150, 232, 201, 154, 190, 330, 410]
-        },
-        {
-            name: 'Direct',
-            type: 'line',
-            stack: 'Total',
-            areaStyle: {},
-            emphasis: {
-                focus: 'series'
-            },
-            data: [320, 332, 301, 334, 390, 330, 320]
-        },
-        {
-            name: 'Search Engine',
-            type: 'line',
-            stack: 'Total',
-            label: {
-                show: true,
-                position: 'top'
-            },
-            areaStyle: {},
-            emphasis: {
-                focus: 'series'
-            },
-            data: [820, 932, 901, 934, 1290, 1330, 1320]
-        }
-    ]
+    {
+      name: 'Search Engine',
+      type: 'line',
+      stack: 'Total',
+      label: {
+        show: true,
+        position: 'top'
+      },
+      areaStyle: {},
+      emphasis: {
+        focus: 'series'
+      },
+      data: [820, 932, 901, 934, 1290, 1330, 1320]
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/area-time-axis.ts b/public/examples/ts/area-time-axis.ts
index 17f2a6e..5d12fd1 100644
--- a/public/examples/ts/area-time-axis.ts
+++ b/public/examples/ts/area-time-axis.ts
@@ -11,59 +11,59 @@ let oneDay = 24 * 3600 * 1000;
 let data = [[base, Math.random() * 300]];
 
 for (let i = 1; i < 20000; i++) {
-    let now = new Date(base += oneDay);
-    data.push([
-        +now,
-        Math.round((Math.random() - 0.5) * 20 + data[i - 1][1])
-    ]);
+  let now = new Date((base += oneDay));
+  data.push([+now, Math.round((Math.random() - 0.5) * 20 + data[i - 1][1])]);
 }
 
 option = {
-    tooltip: {
-        trigger: 'axis',
-        position: function (pt) {
-            return [pt[0], '10%'];
-        }
+  tooltip: {
+    trigger: 'axis',
+    position: function (pt) {
+      return [pt[0], '10%'];
+    }
+  },
+  title: {
+    left: 'center',
+    text: 'Large Ara Chart'
+  },
+  toolbox: {
+    feature: {
+      dataZoom: {
+        yAxisIndex: 'none'
+      },
+      restore: {},
+      saveAsImage: {}
+    }
+  },
+  xAxis: {
+    type: 'time',
+    boundaryGap: false
+  },
+  yAxis: {
+    type: 'value',
+    boundaryGap: [0, '100%']
+  },
+  dataZoom: [
+    {
+      type: 'inside',
+      start: 0,
+      end: 20
     },
-    title: {
-        left: 'center',
-        text: 'Large Ara Chart',
-    },
-    toolbox: {
-        feature: {
-            dataZoom: {
-                yAxisIndex: 'none'
-            },
-            restore: {},
-            saveAsImage: {}
-        }
-    },
-    xAxis: {
-        type: 'time',
-        boundaryGap: false
-    },
-    yAxis: {
-        type: 'value',
-        boundaryGap: [0, '100%']
-    },
-    dataZoom: [{
-        type: 'inside',
-        start: 0,
-        end: 20
-    }, {
-        start: 0,
-        end: 20
-    }],
-    series: [
-        {
-            name: 'Fake Data',
-            type: 'line',
-            smooth: true,
-            symbol: 'none',
-            areaStyle: {},
-            data: data
-        }
-    ]
+    {
+      start: 0,
+      end: 20
+    }
+  ],
+  series: [
+    {
+      name: 'Fake Data',
+      type: 'line',
+      smooth: true,
+      symbol: 'none',
+      areaStyle: {},
+      data: data
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-animation-delay.ts b/public/examples/ts/bar-animation-delay.ts
index 3002c03..50f1f01 100644
--- a/public/examples/ts/bar-animation-delay.ts
+++ b/public/examples/ts/bar-animation-delay.ts
@@ -9,62 +9,64 @@ var xAxisData = [];
 var data1 = [];
 var data2 = [];
 for (var i = 0; i < 100; i++) {
-    xAxisData.push('类目' + i);
-    data1.push((Math.sin(i / 5) * (i / 5 -10) + i / 6) * 5);
-    data2.push((Math.cos(i / 5) * (i / 5 -10) + i / 6) * 5);
+  xAxisData.push('A' + i);
+  data1.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5);
+  data2.push((Math.cos(i / 5) * (i / 5 - 10) + i / 6) * 5);
 }
 
 option = {
-    title: {
-        text: 'Bar Animation Delay'
-    },
-    legend: {
-        data: ['bar', 'bar2']
-    },
-    toolbox: {
-        // y: 'bottom',
-        feature: {
-            magicType: {
-                type: ['stack']
-            },
-            dataView: {},
-            saveAsImage: {
-                pixelRatio: 2
-            }
-        }
-    },
-    tooltip: {},
-    xAxis: {
-        data: xAxisData,
-        splitLine: {
-            show: false
-        }
-    },
-    yAxis: {
+  title: {
+    text: 'Bar Animation Delay'
+  },
+  legend: {
+    data: ['bar', 'bar2']
+  },
+  toolbox: {
+    // y: 'bottom',
+    feature: {
+      magicType: {
+        type: ['stack']
+      },
+      dataView: {},
+      saveAsImage: {
+        pixelRatio: 2
+      }
+    }
+  },
+  tooltip: {},
+  xAxis: {
+    data: xAxisData,
+    splitLine: {
+      show: false
+    }
+  },
+  yAxis: {},
+  series: [
+    {
+      name: 'bar',
+      type: 'bar',
+      data: data1,
+      emphasis: {
+        focus: 'series'
+      },
+      animationDelay: function (idx) {
+        return idx * 10;
+      }
     },
-    series: [{
-        name: 'bar',
-        type: 'bar',
-        data: data1,
-        emphasis: {
-            focus: 'series'
-        },
-        animationDelay: function (idx) {
-            return idx * 10;
-        }
-    }, {
-        name: 'bar2',
-        type: 'bar',
-        data: data2,
-        emphasis: {
-            focus: 'series'
-        },
-        animationDelay: function (idx) {
-            return idx * 10 + 100;
-        }
-    }],
-    animationEasing: 'elasticOut',
-    animationDelayUpdate: function (idx) {
-        return idx * 5;
+    {
+      name: 'bar2',
+      type: 'bar',
+      data: data2,
+      emphasis: {
+        focus: 'series'
+      },
+      animationDelay: function (idx) {
+        return idx * 10 + 100;
+      }
     }
-};
\ No newline at end of file
+  ],
+  animationEasing: 'elasticOut',
+  animationDelayUpdate: function (idx) {
+    return idx * 5;
+  }
+};
diff --git a/public/examples/ts/bar-background.ts b/public/examples/ts/bar-background.ts
index 3c89094..d9a9efb 100644
--- a/public/examples/ts/bar-background.ts
+++ b/public/examples/ts/bar-background.ts
@@ -6,21 +6,23 @@ difficulty: 0
 */
 
 option = {
-    xAxis: {
-        type: 'category',
-        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-    },
-    yAxis: {
-        type: 'value'
-    },
-    series: [{
-        data: [120, 200, 150, 80, 70, 110, 130],
-        type: 'bar',
-        showBackground: true,
-        backgroundStyle: {
-            color: 'rgba(180, 180, 180, 0.2)'
-        }
-    }]
+  xAxis: {
+    type: 'category',
+    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+  },
+  yAxis: {
+    type: 'value'
+  },
+  series: [
+    {
+      data: [120, 200, 150, 80, 70, 110, 130],
+      type: 'bar',
+      showBackground: true,
+      backgroundStyle: {
+        color: 'rgba(180, 180, 180, 0.2)'
+      }
+    }
+  ]
 };
 
-export {}
+export {};
diff --git a/public/examples/ts/bar-brush.ts b/public/examples/ts/bar-brush.ts
index abb4cbd..f09b9dd 100644
--- a/public/examples/ts/bar-brush.ts
+++ b/public/examples/ts/bar-brush.ts
@@ -12,104 +12,103 @@ let data3: number[] = [];
 let data4: number[] = [];
 
 for (let i = 0; i < 10; i++) {
-    xAxisData.push('Class' + i);
-    data1.push(+(Math.random() * 2).toFixed(2));
-    data2.push(+(Math.random() * 5).toFixed(2));
-    data3.push(+(Math.random() + 0.3).toFixed(2));
-    data4.push(+Math.random().toFixed(2));
+  xAxisData.push('Class' + i);
+  data1.push(+(Math.random() * 2).toFixed(2));
+  data2.push(+(Math.random() * 5).toFixed(2));
+  data3.push(+(Math.random() + 0.3).toFixed(2));
+  data4.push(+Math.random().toFixed(2));
 }
 
 var emphasisStyle = {
-    itemStyle: {
-        shadowBlur: 10,
-        shadowColor: 'rgba(0,0,0,0.3)'
-    }
+  itemStyle: {
+    shadowBlur: 10,
+    shadowColor: 'rgba(0,0,0,0.3)'
+  }
 };
 
 option = {
-    legend: {
-        data: ['bar', 'bar2', 'bar3', 'bar4'],
-        left: '10%'
-    },
-    brush: {
-        toolbox: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'],
-        xAxisIndex: 0
-    },
-    toolbox: {
-        feature: {
-            magicType: {
-                type: ['stack']
-            },
-            dataView: {}
-        }
+  legend: {
+    data: ['bar', 'bar2', 'bar3', 'bar4'],
+    left: '10%'
+  },
+  brush: {
+    toolbox: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'],
+    xAxisIndex: 0
+  },
+  toolbox: {
+    feature: {
+      magicType: {
+        type: ['stack']
+      },
+      dataView: {}
+    }
+  },
+  tooltip: {},
+  xAxis: {
+    data: xAxisData,
+    name: 'X Axis',
+    axisLine: { onZero: true },
+    splitLine: { show: false },
+    splitArea: { show: false }
+  },
+  yAxis: {},
+  grid: {
+    bottom: 100
+  },
+  series: [
+    {
+      name: 'bar',
+      type: 'bar',
+      stack: 'one',
+      emphasis: emphasisStyle,
+      data: data1
     },
-    tooltip: {},
-    xAxis: {
-        data: xAxisData,
-        name: 'X Axis',
-        axisLine: {onZero: true},
-        splitLine: {show: false},
-        splitArea: {show: false}
+    {
+      name: 'bar2',
+      type: 'bar',
+      stack: 'one',
+      emphasis: emphasisStyle,
+      data: data2
     },
-    yAxis: {},
-    grid: {
-        bottom: 100
+    {
+      name: 'bar3',
+      type: 'bar',
+      stack: 'two',
+      emphasis: emphasisStyle,
+      data: data3
     },
-    series: [
-        {
-            name: 'bar',
-            type: 'bar',
-            stack: 'one',
-            emphasis: emphasisStyle,
-            data: data1
-        },
-        {
-            name: 'bar2',
-            type: 'bar',
-            stack: 'one',
-            emphasis: emphasisStyle,
-            data: data2
-        },
-        {
-            name: 'bar3',
-            type: 'bar',
-            stack: 'two',
-            emphasis: emphasisStyle,
-            data: data3
-        },
-        {
-            name: 'bar4',
-            type: 'bar',
-            stack: 'two',
-            emphasis: emphasisStyle,
-            data: data4
-        }
-    ]
+    {
+      name: 'bar4',
+      type: 'bar',
+      stack: 'two',
+      emphasis: emphasisStyle,
+      data: data4
+    }
+  ]
 };
 
 myChart.on('brushSelected', function (params: any) {
-    var brushed = [];
-    var brushComponent = params.batch[0];
+  var brushed = [];
+  var brushComponent = params.batch[0];
 
-    for (var sIdx = 0; sIdx < brushComponent.selected.length; sIdx++) {
-        var rawIndices = brushComponent.selected[sIdx].dataIndex;
-        brushed.push('[Series ' + sIdx + '] ' + rawIndices.join(', '));
-    }
+  for (var sIdx = 0; sIdx < brushComponent.selected.length; sIdx++) {
+    var rawIndices = brushComponent.selected[sIdx].dataIndex;
+    brushed.push('[Series ' + sIdx + '] ' + rawIndices.join(', '));
+  }
 
-    myChart.setOption<echarts.EChartsOption>({
-        title: {
-            backgroundColor: '#333',
-            text: 'SELECTED DATA INDICES: \n' + brushed.join('\n'),
-            bottom: 0,
-            right:'10%',
-            width: 100,
-            textStyle: {
-                fontSize: 12,
-                color: '#fff'
-            }
-        }
-    });
+  myChart.setOption<echarts.EChartsOption>({
+    title: {
+      backgroundColor: '#333',
+      text: 'SELECTED DATA INDICES: \n' + brushed.join('\n'),
+      bottom: 0,
+      right: '10%',
+      width: 100,
+      textStyle: {
+        fontSize: 12,
+        color: '#fff'
+      }
+    }
+  });
 });
 
-
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-data-color.ts b/public/examples/ts/bar-data-color.ts
index b5eccae..6f3f224 100644
--- a/public/examples/ts/bar-data-color.ts
+++ b/public/examples/ts/bar-data-color.ts
@@ -6,22 +6,32 @@ difficulty: 1
 */
 
 option = {
-    xAxis: {
-        type: 'category',
-        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-    },
-    yAxis: {
-        type: 'value'
-    },
-    series: [{
-        data: [120, {
-            value: 200,
-            itemStyle: {
-                color: '#a90000'
-            }
-        }, 150, 80, 70, 110, 130],
-        type: 'bar'
-    }]
+  xAxis: {
+    type: 'category',
+    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+  },
+  yAxis: {
+    type: 'value'
+  },
+  series: [
+    {
+      data: [
+        120,
+        {
+          value: 200,
+          itemStyle: {
+            color: '#a90000'
+          }
+        },
+        150,
+        80,
+        70,
+        110,
+        130
+      ],
+      type: 'bar'
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-drilldown.ts b/public/examples/ts/bar-drilldown.ts
index 864766c..d050e33 100644
--- a/public/examples/ts/bar-drilldown.ts
+++ b/public/examples/ts/bar-drilldown.ts
@@ -5,101 +5,110 @@ titleCN: 柱状图下钻动画
 difficulty: 5
 */
 
-
 interface DataItem {
-    value: number
-    groupId: string
+  value: number;
+  groupId: string;
 }
 option = {
-    xAxis: {
-        data: ['Animals', 'Fruits', 'Cars']
-    },
-    yAxis: {},
-    dataGroupId: '',
-    animationDurationUpdate: 500,
-    series: {
-        type: 'bar',
-        id: 'sales',
-        data: [{
-            value: 5,
-            groupId: 'animals'
-        }, {
-            value: 2,
-            groupId: 'fruits'
-        }, {
-            value: 4,
-            groupId: 'cars'
-        }] as DataItem[],
-        universalTransition: {
-            enabled: true,
-            divideShape: 'clone'
-        }
+  xAxis: {
+    data: ['Animals', 'Fruits', 'Cars']
+  },
+  yAxis: {},
+  dataGroupId: '',
+  animationDurationUpdate: 500,
+  series: {
+    type: 'bar',
+    id: 'sales',
+    data: [
+      {
+        value: 5,
+        groupId: 'animals'
+      },
+      {
+        value: 2,
+        groupId: 'fruits'
+      },
+      {
+        value: 4,
+        groupId: 'cars'
+      }
+    ] as DataItem[],
+    universalTransition: {
+      enabled: true,
+      divideShape: 'clone'
     }
+  }
 };
 
-const drilldownData = [{
+const drilldownData = [
+  {
     dataGroupId: 'animals',
     data: [
-        ['Cats', 4],
-        ['Dogs', 2],
-        ['Cows', 1],
-        ['Sheep', 2],
-        ['Pigs', 1]
+      ['Cats', 4],
+      ['Dogs', 2],
+      ['Cows', 1],
+      ['Sheep', 2],
+      ['Pigs', 1]
     ]
-}, {
+  },
+  {
     dataGroupId: 'fruits',
     data: [
-        ['Apples', 4],
-        ['Oranges', 2]
+      ['Apples', 4],
+      ['Oranges', 2]
     ]
-}, {
+  },
+  {
     dataGroupId: 'cars',
     data: [
-        ['Toyota', 4],
-        ['Opel', 2],
-        ['Volkswagen', 2]
+      ['Toyota', 4],
+      ['Opel', 2],
+      ['Volkswagen', 2]
     ]
-}];
+  }
+];
 
 myChart.on('click', function (event) {
-    if (event.data) {
-        var subData = drilldownData.find(function (data) {
-            return data.dataGroupId === (event.data as DataItem).groupId;
-        });
-        if (!subData) {
-            return;
-        }
-        myChart.setOption<echarts.EChartsOption>({
-            xAxis: {
-                data: subData.data.map(function (item) {
-                    return item[0];
-                })
-            },
-            series: {
-                type: 'bar',
-                id: 'sales',
-                dataGroupId: subData.dataGroupId,
-                data: subData.data.map(function (item) {
-                    return item[1];
-                }),
-                universalTransition: {
-                    enabled: true,
-                    divideShape: 'clone'
-                }
-            },
-            graphic: [{
-                type: 'text',
-                left: 50,
-                top: 20,
-                style: {
-                    text: 'Back',
-                    fontSize: 18
-                },
-                onclick: function () {
-                    myChart.setOption<echarts.EChartsOption>(option);
-                }
-            }]
-        });
+  if (event.data) {
+    var subData = drilldownData.find(function (data) {
+      return data.dataGroupId === (event.data as DataItem).groupId;
+    });
+    if (!subData) {
+      return;
     }
+    myChart.setOption<echarts.EChartsOption>({
+      xAxis: {
+        data: subData.data.map(function (item) {
+          return item[0];
+        })
+      },
+      series: {
+        type: 'bar',
+        id: 'sales',
+        dataGroupId: subData.dataGroupId,
+        data: subData.data.map(function (item) {
+          return item[1];
+        }),
+        universalTransition: {
+          enabled: true,
+          divideShape: 'clone'
+        }
+      },
+      graphic: [
+        {
+          type: 'text',
+          left: 50,
+          top: 20,
+          style: {
+            text: 'Back',
+            fontSize: 18
+          },
+          onclick: function () {
+            myChart.setOption<echarts.EChartsOption>(option);
+          }
+        }
+      ]
+    });
+  }
 });
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-gradient.ts b/public/examples/ts/bar-gradient.ts
index a22168d..c620388 100644
--- a/public/examples/ts/bar-gradient.ts
+++ b/public/examples/ts/bar-gradient.ts
@@ -5,90 +5,87 @@ category: bar
 difficulty: 3
 */
 
-var dataAxis = ['点', '击', '柱', '子', '或', '者', '两', '指', '在', '触', '屏', '上', '滑', '动', '能', '够', '自', '动', '缩', '放'];
-var data = [220, 182, 191, 234, 290, 330, 310, 123, 442, 321, 90, 149, 210, 122, 133, 334, 198, 123, 125, 220];
-var yMax = 500;
-var dataShadow = [];
+// prettier-ignore
+let dataAxis = ['点', '击', '柱', '子', '或', '者', '两', '指', '在', '触', '屏', '上', '滑', '动', '能', '够', '自', '动', '缩', '放'];
+// prettier-ignore
+let data = [220, 182, 191, 234, 290, 330, 310, 123, 442, 321, 90, 149, 210, 122, 133, 334, 198, 123, 125, 220];
+let yMax = 500;
+let dataShadow = [];
 
-for (var i = 0; i < data.length; i++) {
-    dataShadow.push(yMax);
+for (let i = 0; i < data.length; i++) {
+  dataShadow.push(yMax);
 }
 
 option = {
-    title: {
-        text: '特性示例:渐变色 阴影 点击缩放',
-        subtext: 'Feature Sample: Gradient Color, Shadow, Click Zoom'
+  title: {
+    text: '特性示例:渐变色 阴影 点击缩放',
+    subtext: 'Feature Sample: Gradient Color, Shadow, Click Zoom'
+  },
+  xAxis: {
+    data: dataAxis,
+    axisLabel: {
+      inside: true,
+      color: '#fff'
     },
-    xAxis: {
-        data: dataAxis,
-        axisLabel: {
-            inside: true,
-            color: '#fff'
-        },
-        axisTick: {
-            show: false
-        },
-        axisLine: {
-            show: false
-        },
-        z: 10
+    axisTick: {
+      show: false
     },
-    yAxis: {
-        axisLine: {
-            show: false
-        },
-        axisTick: {
-            show: false
-        },
-        axisLabel: {
-            color: '#999'
-        }
+    axisLine: {
+      show: false
     },
-    dataZoom: [
-        {
-            type: 'inside'
-        }
-    ],
-    series: [
-        {
-            type: 'bar',
-            showBackground: true,
-            itemStyle: {
-                color: new echarts.graphic.LinearGradient(
-                    0, 0, 0, 1,
-                    [
-                        {offset: 0, color: '#83bff6'},
-                        {offset: 0.5, color: '#188df0'},
-                        {offset: 1, color: '#188df0'}
-                    ]
-                )
-            },
-            emphasis: {
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(
-                        0, 0, 0, 1,
-                        [
-                            {offset: 0, color: '#2378f7'},
-                            {offset: 0.7, color: '#2378f7'},
-                            {offset: 1, color: '#83bff6'}
-                        ]
-                    )
-                }
-            },
-            data: data
+    z: 10
+  },
+  yAxis: {
+    axisLine: {
+      show: false
+    },
+    axisTick: {
+      show: false
+    },
+    axisLabel: {
+      color: '#999'
+    }
+  },
+  dataZoom: [
+    {
+      type: 'inside'
+    }
+  ],
+  series: [
+    {
+      type: 'bar',
+      showBackground: true,
+      itemStyle: {
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          { offset: 0, color: '#83bff6' },
+          { offset: 0.5, color: '#188df0' },
+          { offset: 1, color: '#188df0' }
+        ])
+      },
+      emphasis: {
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#2378f7' },
+            { offset: 0.7, color: '#2378f7' },
+            { offset: 1, color: '#83bff6' }
+          ])
         }
-    ]
+      },
+      data: data
+    }
+  ]
 };
 
 // Enable data zoom when user click bar.
-var zoomSize = 6;
+const zoomSize = 6;
 myChart.on('click', function (params) {
-    console.log(dataAxis[Math.max(params.dataIndex - zoomSize / 2, 0)]);
-    myChart.dispatchAction({
-        type: 'dataZoom',
-        startValue: dataAxis[Math.max(params.dataIndex - zoomSize / 2, 0)],
-        endValue: dataAxis[Math.min(params.dataIndex + zoomSize / 2, data.length - 1)]
-    });
+  console.log(dataAxis[Math.max(params.dataIndex - zoomSize / 2, 0)]);
+  myChart.dispatchAction({
+    type: 'dataZoom',
+    startValue: dataAxis[Math.max(params.dataIndex - zoomSize / 2, 0)],
+    endValue:
+      dataAxis[Math.min(params.dataIndex + zoomSize / 2, data.length - 1)]
+  });
 });
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-histogram.ts b/public/examples/ts/bar-histogram.ts
index 424db37..b4536ec 100644
--- a/public/examples/ts/bar-histogram.ts
+++ b/public/examples/ts/bar-histogram.ts
@@ -9,119 +9,138 @@ difficulty: 0
 echarts.registerTransform(ecStat.transform.histogram);
 
 option = {
-    dataset: [{
-        source: [
-            [8.3, 143],
-            [8.6, 214],
-            [8.8, 251],
-            [10.5, 26],
-            [10.7, 86],
-            [10.8, 93],
-            [11.0, 176],
-            [11.0, 39],
-            [11.1, 221],
-            [11.2, 188],
-            [11.3, 57],
-            [11.4, 91],
-            [11.4, 191],
-            [11.7, 8],
-            [12.0, 196],
-            [12.9, 177],
-            [12.9, 153],
-            [13.3, 201],
-            [13.7, 199],
-            [13.8, 47],
-            [14.0, 81],
-            [14.2, 98],
-            [14.5, 121],
-            [16.0, 37],
-            [16.3, 12],
-            [17.3, 105],
-            [17.5, 168],
-            [17.9, 84],
-            [18.0, 197],
-            [18.0, 155],
-            [20.6, 125]
-        ]
-    }, {
-        transform: {
-            type: 'ecStat:histogram',
-            config: {}
-        }
-    }, {
-        transform: {
-            type: 'ecStat:histogram',
-            // print: true,
-            config: { dimensions: [1] }
-        }
-    }],
-    tooltip: {
+  dataset: [
+    {
+      source: [
+        [8.3, 143],
+        [8.6, 214],
+        [8.8, 251],
+        [10.5, 26],
+        [10.7, 86],
+        [10.8, 93],
+        [11.0, 176],
+        [11.0, 39],
+        [11.1, 221],
+        [11.2, 188],
+        [11.3, 57],
+        [11.4, 91],
+        [11.4, 191],
+        [11.7, 8],
+        [12.0, 196],
+        [12.9, 177],
+        [12.9, 153],
+        [13.3, 201],
+        [13.7, 199],
+        [13.8, 47],
+        [14.0, 81],
+        [14.2, 98],
+        [14.5, 121],
+        [16.0, 37],
+        [16.3, 12],
+        [17.3, 105],
+        [17.5, 168],
+        [17.9, 84],
+        [18.0, 197],
+        [18.0, 155],
+        [20.6, 125]
+      ]
     },
-    grid: [{
-        top: '50%',
-        right: '50%'
-    }, {
-        bottom: '52%',
-        right: '50%',
-    }, {
-        top: '50%',
-        left: '52%'
-    }],
-    xAxis: [{
-        scale: true,
-        gridIndex: 0
-    }, {
-        type: 'category',
-        scale: true,
-        axisTick: { show: false },
-        axisLabel: { show: false },
-        axisLine: { show: false },
-        gridIndex: 1
-    }, {
-        scale: true,
-        gridIndex: 2
-    }],
-    yAxis: [{
-        gridIndex: 0
-    }, {
-        gridIndex: 1
-    }, {
-        type: 'category',
-        axisTick: { show: false },
-        axisLabel: { show: false },
-        axisLine: { show: false },
-        gridIndex: 2
-    }],
-    series: [{
-        name: 'origianl scatter',
-        type: 'scatter',
-        xAxisIndex: 0,
-        yAxisIndex: 0,
-        encode: { tooltip: [0, 1] },
-        datasetIndex: 0
-    }, {
-        name: 'histogram',
-        type: 'bar',
-        xAxisIndex: 1,
-        yAxisIndex: 1,
-        barWidth: '99.3%',
-        label: {
-            show: true,
-            position: 'top'
-        },
-        encode: { x: 0, y: 1, itemName: 4 },
-        datasetIndex: 1
-    }, {
-        name: 'histogram',
-        type: 'bar',
-        xAxisIndex: 2,
-        yAxisIndex: 2,
-        barWidth: '99.3%',
-        label: {
-            show: true,
-            position: 'right'
-        },
-        encode: { x: 1, y: 0, itemName: 4 },
-        datasetIndex: 2
-    }]
+    {
+      transform: {
+        type: 'ecStat:histogram',
+        config: {}
+      }
+    },
+    {
+      transform: {
+        type: 'ecStat:histogram',
+        // print: true,
+        config: { dimensions: [1] }
+      }
+    }
+  ],
+  tooltip: {},
+  grid: [
+    {
+      top: '50%',
+      right: '50%'
+    },
+    {
+      bottom: '52%',
+      right: '50%'
+    },
+    {
+      top: '50%',
+      left: '52%'
+    }
+  ],
+  xAxis: [
+    {
+      scale: true,
+      gridIndex: 0
+    },
+    {
+      type: 'category',
+      scale: true,
+      axisTick: { show: false },
+      axisLabel: { show: false },
+      axisLine: { show: false },
+      gridIndex: 1
+    },
+    {
+      scale: true,
+      gridIndex: 2
+    }
+  ],
+  yAxis: [
+    {
+      gridIndex: 0
+    },
+    {
+      gridIndex: 1
+    },
+    {
+      type: 'category',
+      axisTick: { show: false },
+      axisLabel: { show: false },
+      axisLine: { show: false },
+      gridIndex: 2
+    }
+  ],
+  series: [
+    {
+      name: 'origianl scatter',
+      type: 'scatter',
+      xAxisIndex: 0,
+      yAxisIndex: 0,
+      encode: { tooltip: [0, 1] },
+      datasetIndex: 0
+    },
+    {
+      name: 'histogram',
+      type: 'bar',
+      xAxisIndex: 1,
+      yAxisIndex: 1,
+      barWidth: '99.3%',
+      label: {
+        show: true,
+        position: 'top'
+      },
+      encode: { x: 0, y: 1, itemName: 4 },
+      datasetIndex: 1
+    },
+    {
+      name: 'histogram',
+      type: 'bar',
+      xAxisIndex: 2,
+      yAxisIndex: 2,
+      barWidth: '99.3%',
+      label: {
+        show: true,
+        position: 'right'
+      },
+      encode: { x: 1, y: 0, itemName: 4 },
+      datasetIndex: 2
+    }
+  ]
 };
diff --git a/public/examples/ts/bar-label-rotation.ts b/public/examples/ts/bar-label-rotation.ts
index 9218f49..97bd265 100644
--- a/public/examples/ts/bar-label-rotation.ts
+++ b/public/examples/ts/bar-label-rotation.ts
@@ -6,161 +6,175 @@ difficulty: 3
 */
 
 const posList = [
-    'left', 'right', 'top', 'bottom',
-    'inside',
-    'insideTop', 'insideLeft', 'insideRight', 'insideBottom',
-    'insideTopLeft', 'insideTopRight', 'insideBottomLeft', 'insideBottomRight'
+  'left',
+  'right',
+  'top',
+  'bottom',
+  'inside',
+  'insideTop',
+  'insideLeft',
+  'insideRight',
+  'insideBottom',
+  'insideTopLeft',
+  'insideTopRight',
+  'insideBottomLeft',
+  'insideBottomRight'
 ] as const;
 
 app.configParameters = {
-    rotate: {
-        min: -90,
-        max: 90
-    },
-    align: {
-        options: {
-            left: 'left',
-            center: 'center',
-            right: 'right'
-        }
-    },
-    verticalAlign: {
-        options: {
-            top: 'top',
-            middle: 'middle',
-            bottom: 'bottom'
-        }
-    },
-    position: {
-        options: posList.reduce(function (map, pos) {
-            map[pos] = pos;
-            return map;
-        }, {} as Record<string, string>)
-    },
-    distance: {
-        min: 0,
-        max: 100
+  rotate: {
+    min: -90,
+    max: 90
+  },
+  align: {
+    options: {
+      left: 'left',
+      center: 'center',
+      right: 'right'
+    }
+  },
+  verticalAlign: {
+    options: {
+      top: 'top',
+      middle: 'middle',
+      bottom: 'bottom'
     }
+  },
+  position: {
+    options: posList.reduce(function (map, pos) {
+      map[pos] = pos;
+      return map;
+    }, {} as Record<string, string>)
+  },
+  distance: {
+    min: 0,
+    max: 100
+  }
 };
 
 app.config = {
-    rotate: 90,
-    align: 'left',
-    verticalAlign: 'middle',
-    position: 'insideBottom',
-    distance: 15,
-    onChange: function () {
-        var labelOption = {
-            normal: {
-                rotate: app.config.rotate,
-                align: app.config.align,
-                verticalAlign: app.config.verticalAlign,
-                position: app.config.position,
-                distance: app.config.distance
-            }
-        };
-        myChart.setOption<echarts.EChartsOption>({
-            series: [{
-                label: labelOption
-            }, {
-                label: labelOption
-            }, {
-                label: labelOption
-            }, {
-                label: labelOption
-            }]
-        });
-    }
+  rotate: 90,
+  align: 'left',
+  verticalAlign: 'middle',
+  position: 'insideBottom',
+  distance: 15,
+  onChange: function () {
+    var labelOption = {
+      normal: {
+        rotate: app.config.rotate,
+        align: app.config.align,
+        verticalAlign: app.config.verticalAlign,
+        position: app.config.position,
+        distance: app.config.distance
+      }
+    };
+    myChart.setOption<echarts.EChartsOption>({
+      series: [
+        {
+          label: labelOption
+        },
+        {
+          label: labelOption
+        },
+        {
+          label: labelOption
+        },
+        {
+          label: labelOption
+        }
+      ]
+    });
+  }
 };
 
-type BarLabelOption = NonNullable<echarts.BarSeriesOption['label']>
+type BarLabelOption = NonNullable<echarts.BarSeriesOption['label']>;
 
 const labelOption = {
-    show: true,
-    position: app.config.position as BarLabelOption['position'],
-    distance: app.config.distance as BarLabelOption['distance'],
-    align: app.config.align as BarLabelOption['align'],
-    verticalAlign: app.config.verticalAlign as BarLabelOption['verticalAlign'],
-    rotate: app.config.rotate as BarLabelOption['rotate'],
-    formatter: '{c}  {name|{a}}',
-    fontSize: 16,
-    rich: {
-        name: {}
-    }
+  show: true,
+  position: app.config.position as BarLabelOption['position'],
+  distance: app.config.distance as BarLabelOption['distance'],
+  align: app.config.align as BarLabelOption['align'],
+  verticalAlign: app.config.verticalAlign as BarLabelOption['verticalAlign'],
+  rotate: app.config.rotate as BarLabelOption['rotate'],
+  formatter: '{c}  {name|{a}}',
+  fontSize: 16,
+  rich: {
+    name: {}
+  }
 };
 
 option = {
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
-        }
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  legend: {
+    data: ['Forest', 'Steppe', 'Desert', 'Wetland']
+  },
+  toolbox: {
+    show: true,
+    orient: 'vertical',
+    left: 'right',
+    top: 'center',
+    feature: {
+      mark: { show: true },
+      dataView: { show: true, readOnly: false },
+      magicType: { show: true, type: ['line', 'bar', 'stack'] },
+      restore: { show: true },
+      saveAsImage: { show: true }
+    }
+  },
+  xAxis: [
+    {
+      type: 'category',
+      axisTick: { show: false },
+      data: ['2012', '2013', '2014', '2015', '2016']
+    }
+  ],
+  yAxis: [
+    {
+      type: 'value'
+    }
+  ],
+  series: [
+    {
+      name: 'Forest',
+      type: 'bar',
+      barGap: 0,
+      label: labelOption,
+      emphasis: {
+        focus: 'series'
+      },
+      data: [320, 332, 301, 334, 390]
     },
-    legend: {
-        data: ['Forest', 'Steppe', 'Desert', 'Wetland']
+    {
+      name: 'Steppe',
+      type: 'bar',
+      label: labelOption,
+      emphasis: {
+        focus: 'series'
+      },
+      data: [220, 182, 191, 234, 290]
     },
-    toolbox: {
-        show: true,
-        orient: 'vertical',
-        left: 'right',
-        top: 'center',
-        feature: {
-            mark: {show: true},
-            dataView: {show: true, readOnly: false},
-            magicType: {show: true, type: ['line', 'bar', 'stack']},
-            restore: {show: true},
-            saveAsImage: {show: true}
-        }
+    {
+      name: 'Desert',
+      type: 'bar',
+      label: labelOption,
+      emphasis: {
+        focus: 'series'
+      },
+      data: [150, 232, 201, 154, 190]
     },
-    xAxis: [
-        {
-            type: 'category',
-            axisTick: {show: false},
-            data: ['2012', '2013', '2014', '2015', '2016']
-        }
-    ],
-    yAxis: [
-        {
-            type: 'value'
-        }
-    ],
-    series: [
-        {
-            name: 'Forest',
-            type: 'bar',
-            barGap: 0,
-            label: labelOption,
-            emphasis: {
-                focus: 'series'
-            },
-            data: [320, 332, 301, 334, 390]
-        },
-        {
-            name: 'Steppe',
-            type: 'bar',
-            label: labelOption,
-            emphasis: {
-                focus: 'series'
-            },
-            data: [220, 182, 191, 234, 290]
-        },
-        {
-            name: 'Desert',
-            type: 'bar',
-            label: labelOption,
-            emphasis: {
-                focus: 'series'
-            },
-            data: [150, 232, 201, 154, 190]
-        },
-        {
-            name: 'Wetland',
-            type: 'bar',
-            label: labelOption,
-            emphasis: {
-                focus: 'series'
-            },
-            data: [98, 77, 101, 99, 40]
-        }
-    ]
-};
\ No newline at end of file
+    {
+      name: 'Wetland',
+      type: 'bar',
+      label: labelOption,
+      emphasis: {
+        focus: 'series'
+      },
+      data: [98, 77, 101, 99, 40]
+    }
+  ]
+};
diff --git a/public/examples/ts/bar-large.ts b/public/examples/ts/bar-large.ts
index 03be19a..0a05fe3 100644
--- a/public/examples/ts/bar-large.ts
+++ b/public/examples/ts/bar-large.ts
@@ -5,91 +5,95 @@ titleCN: 大数据量柱图
 difficulty: 5
 */
 
-
 const dataCount = 5e5;
 const data = generateData(dataCount);
 
 option = {
-    title: {
-        text: echarts.format.addCommas(dataCount) + ' Data',
-        left: 10
-    },
-    toolbox: {
-        feature: {
-            dataZoom: {
-                yAxisIndex: false
-            },
-            saveAsImage: {
-                pixelRatio: 2
-            }
-        }
-    },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
-        }
-    },
-    grid: {
-        bottom: 90
-    },
-    dataZoom: [{
-        type: 'inside'
-    }, {
-        type: 'slider'
-    }],
-    xAxis: {
-        data: data.categoryData,
-        silent: false,
-        splitLine: {
-            show: false
-        },
-        splitArea: {
-            show: false
-        }
+  title: {
+    text: echarts.format.addCommas(dataCount) + ' Data',
+    left: 10
+  },
+  toolbox: {
+    feature: {
+      dataZoom: {
+        yAxisIndex: false
+      },
+      saveAsImage: {
+        pixelRatio: 2
+      }
+    }
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  grid: {
+    bottom: 90
+  },
+  dataZoom: [
+    {
+      type: 'inside'
     },
-    yAxis: {
-        splitArea: {
-            show: false
-        }
+    {
+      type: 'slider'
+    }
+  ],
+  xAxis: {
+    data: data.categoryData,
+    silent: false,
+    splitLine: {
+      show: false
     },
-    series: [{
-        type: 'bar',
-        data: data.valueData,
-        // Set `large` for large data amount
-        large: true
-    }]
+    splitArea: {
+      show: false
+    }
+  },
+  yAxis: {
+    splitArea: {
+      show: false
+    }
+  },
+  series: [
+    {
+      type: 'bar',
+      data: data.valueData,
+      // Set `large` for large data amount
+      large: true
+    }
+  ]
 };
 
 function generateData(count: number) {
-    let baseValue = Math.random() * 1000;
-    let time = +new Date(2011, 0, 1);
-    let smallBaseValue: number;
+  let baseValue = Math.random() * 1000;
+  let time = +new Date(2011, 0, 1);
+  let smallBaseValue: number;
 
-    function next(idx: number) {
-        smallBaseValue = idx % 30 === 0
-            ? Math.random() * 700
-            : (smallBaseValue + Math.random() * 500 - 250);
-        baseValue += Math.random() * 20 - 10;
-        return Math.max(
-            0,
-            Math.round(baseValue + smallBaseValue) + 3000
-        );
-    }
+  function next(idx: number) {
+    smallBaseValue =
+      idx % 30 === 0
+        ? Math.random() * 700
+        : smallBaseValue + Math.random() * 500 - 250;
+    baseValue += Math.random() * 20 - 10;
+    return Math.max(0, Math.round(baseValue + smallBaseValue) + 3000);
+  }
 
-    const categoryData = [];
-    const valueData = [];
+  const categoryData = [];
+  const valueData = [];
 
-    for (let i = 0; i < count; i++) {
-        categoryData.push(echarts.format.formatTime('yyyy-MM-dd\nhh:mm:ss', time, false));
-        valueData.push(next(i).toFixed(2));
-        time += 1000;
-    }
+  for (let i = 0; i < count; i++) {
+    categoryData.push(
+      echarts.format.formatTime('yyyy-MM-dd\nhh:mm:ss', time, false)
+    );
+    valueData.push(next(i).toFixed(2));
+    time += 1000;
+  }
 
-    return {
-        categoryData: categoryData,
-        valueData: valueData
-    };
+  return {
+    categoryData: categoryData,
+    valueData: valueData
+  };
 }
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-negative.ts b/public/examples/ts/bar-negative.ts
index a1c5aa2..57c3dde 100644
--- a/public/examples/ts/bar-negative.ts
+++ b/public/examples/ts/bar-negative.ts
@@ -6,74 +6,75 @@ difficulty: 4
 */
 
 option = {
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {            // 坐标轴指示器,坐标轴触发有效
-            type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
-        }
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      // 坐标轴指示器,坐标轴触发有效
+      type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
+    }
+  },
+  legend: {
+    data: ['利润', '支出', '收入']
+  },
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '3%',
+    containLabel: true
+  },
+  xAxis: [
+    {
+      type: 'value'
+    }
+  ],
+  yAxis: [
+    {
+      type: 'category',
+      axisTick: {
+        show: false
+      },
+      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+    }
+  ],
+  series: [
+    {
+      name: '利润',
+      type: 'bar',
+      label: {
+        show: true,
+        position: 'inside'
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [200, 170, 240, 244, 200, 220, 210]
     },
-    legend: {
-        data: ['利润', '支出', '收入']
+    {
+      name: '收入',
+      type: 'bar',
+      stack: 'Total',
+      label: {
+        show: true
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [320, 302, 341, 374, 390, 450, 420]
     },
-    grid: {
-        left: '3%',
-        right: '4%',
-        bottom: '3%',
-        containLabel: true
-    },
-    xAxis: [
-        {
-            type: 'value'
-        }
-    ],
-    yAxis: [
-        {
-            type: 'category',
-            axisTick: {
-                show: false
-            },
-            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-        }
-    ],
-    series: [
-        {
-            name: '利润',
-            type: 'bar',
-            label: {
-                show: true,
-                position: 'inside'
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [200, 170, 240, 244, 200, 220, 210]
-        },
-        {
-            name: '收入',
-            type: 'bar',
-            stack: 'Total',
-            label: {
-                show: true
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [320, 302, 341, 374, 390, 450, 420]
-        },
-        {
-            name: '支出',
-            type: 'bar',
-            stack: 'Total',
-            label: {
-                show: true,
-                position: 'left'
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [-120, -132, -101, -134, -190, -230, -210]
-        }
-    ]
+    {
+      name: '支出',
+      type: 'bar',
+      stack: 'Total',
+      label: {
+        show: true,
+        position: 'left'
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [-120, -132, -101, -134, -190, -230, -210]
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-negative2.ts b/public/examples/ts/bar-negative2.ts
index 2d4884d..faf21e0 100644
--- a/public/examples/ts/bar-negative2.ts
+++ b/public/examples/ts/bar-negative2.ts
@@ -6,62 +6,74 @@ difficulty: 2
 */
 
 const labelRight = {
-    position: 'right'
+  position: 'right'
 } as const;
 
 option = {
-    title: {
-        text: 'Bar Chart with Negative Value'
-    },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
-        }
-    },
-    grid: {
-        top: 80,
-        bottom: 30
-    },
-    xAxis: {
-        type: 'value',
-        position: 'top',
-        splitLine: {
-            lineStyle: {
-                type: 'dashed'
-            }
-        }
-    },
-    yAxis: {
-        type: 'category',
-        axisLine: {show: false},
-        axisLabel: {show: false},
-        axisTick: {show: false},
-        splitLine: {show: false},
-        data: ['ten', 'nine', 'eight', 'seven', 'six', 'five', 'four', 'three', 'two', 'one']
-    },
-    series: [
-        {
-            name: 'Cost',
-            type: 'bar',
-            stack: 'Total',
-            label: {
-                show: true,
-                formatter: '{b}'
-            },
-            data: [
-                {value: -0.07, label: labelRight},
-                {value: -0.09, label: labelRight},
-                0.2, 0.44,
-                {value: -0.23, label: labelRight},
-                0.08,
-                {value: -0.17, label: labelRight},
-                0.47,
-                {value: -0.36, label: labelRight},
-                0.18
-            ]
-        }
+  title: {
+    text: 'Bar Chart with Negative Value'
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  grid: {
+    top: 80,
+    bottom: 30
+  },
+  xAxis: {
+    type: 'value',
+    position: 'top',
+    splitLine: {
+      lineStyle: {
+        type: 'dashed'
+      }
+    }
+  },
+  yAxis: {
+    type: 'category',
+    axisLine: { show: false },
+    axisLabel: { show: false },
+    axisTick: { show: false },
+    splitLine: { show: false },
+    data: [
+      'ten',
+      'nine',
+      'eight',
+      'seven',
+      'six',
+      'five',
+      'four',
+      'three',
+      'two',
+      'one'
     ]
+  },
+  series: [
+    {
+      name: 'Cost',
+      type: 'bar',
+      stack: 'Total',
+      label: {
+        show: true,
+        formatter: '{b}'
+      },
+      data: [
+        { value: -0.07, label: labelRight },
+        { value: -0.09, label: labelRight },
+        0.2,
+        0.44,
+        { value: -0.23, label: labelRight },
+        0.08,
+        { value: -0.17, label: labelRight },
+        0.47,
+        { value: -0.36, label: labelRight },
+        0.18
+      ]
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-polar-label-radial.ts b/public/examples/ts/bar-polar-label-radial.ts
index 9ab4b01..c42a96e 100644
--- a/public/examples/ts/bar-polar-label-radial.ts
+++ b/public/examples/ts/bar-polar-label-radial.ts
@@ -6,33 +6,35 @@ difficulty: 2
 */
 
 option = {
-    title: [{
-        text: 'Radial Polar Bar Label Position (middle)'
-    }],
-    polar: {
-        radius: [30, '80%']
-    },
-    radiusAxis: {
-        max: 4
-    },
-    angleAxis: {
-        type: 'category',
-        data: ['a', 'b', 'c', 'd'],
-        startAngle: 75
-    },
-    tooltip: {},
-    series: {
-        type: 'bar',
-        data: [2, 1.2, 2.4, 3.6],
-        coordinateSystem: 'polar',
-        label: {
-            show: true,
-            position: 'middle', // or 'start', 'insideStart', 'end', 'insideEnd'
-            formatter: '{b}: {c}',
-        }
-    },
-    backgroundColor: '#fff',
-    animation: false
+  title: [
+    {
+      text: 'Radial Polar Bar Label Position (middle)'
+    }
+  ],
+  polar: {
+    radius: [30, '80%']
+  },
+  radiusAxis: {
+    max: 4
+  },
+  angleAxis: {
+    type: 'category',
+    data: ['a', 'b', 'c', 'd'],
+    startAngle: 75
+  },
+  tooltip: {},
+  series: {
+    type: 'bar',
+    data: [2, 1.2, 2.4, 3.6],
+    coordinateSystem: 'polar',
+    label: {
+      show: true,
+      position: 'middle', // or 'start', 'insideStart', 'end', 'insideEnd'
+      formatter: '{b}: {c}'
+    }
+  },
+  backgroundColor: '#fff',
+  animation: false
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-polar-label-tangential.ts b/public/examples/ts/bar-polar-label-tangential.ts
index 9fcd728..aa69c37 100644
--- a/public/examples/ts/bar-polar-label-tangential.ts
+++ b/public/examples/ts/bar-polar-label-tangential.ts
@@ -5,33 +5,35 @@ category: bar
 difficulty: 2
 */
 option = {
-    title: [{
-        text: 'Tangential Polar Bar Label Position (middle)'
-    }],
-    polar: {
-        radius: [30, '80%']
-    },
-    angleAxis: {
-        max: 4,
-        startAngle: 75
-    },
-    radiusAxis: {
-        type: 'category',
-        data: ['a', 'b', 'c', 'd']
-    },
-    tooltip: {},
-    series: {
-        type: 'bar',
-        data: [2, 1.2, 2.4, 3.6],
-        coordinateSystem: 'polar',
-        label: {
-            show: true,
-            position: 'middle', // or 'start', 'insideStart', 'end', 'insideEnd'
-            formatter: '{b}: {c}',
-        }
-    },
-    backgroundColor: '#fff',
-    animation: false
+  title: [
+    {
+      text: 'Tangential Polar Bar Label Position (middle)'
+    }
+  ],
+  polar: {
+    radius: [30, '80%']
+  },
+  angleAxis: {
+    max: 4,
+    startAngle: 75
+  },
+  radiusAxis: {
+    type: 'category',
+    data: ['a', 'b', 'c', 'd']
+  },
+  tooltip: {},
+  series: {
+    type: 'bar',
+    data: [2, 1.2, 2.4, 3.6],
+    coordinateSystem: 'polar',
+    label: {
+      show: true,
+      position: 'middle', // or 'start', 'insideStart', 'end', 'insideEnd'
+      formatter: '{b}: {c}'
+    }
+  },
+  backgroundColor: '#fff',
+  animation: false
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-polar-real-estate.ts b/public/examples/ts/bar-polar-real-estate.ts
index 42d60b2..87ea60d 100644
--- a/public/examples/ts/bar-polar-real-estate.ts
+++ b/public/examples/ts/bar-polar-real-estate.ts
@@ -6,99 +6,111 @@ shotWidth: 800
 */
 
 const data = [
-    [5000, 10000, 6785.71],
-    [4000, 10000, 6825],
-    [3000, 6500, 4463.33],
-    [2500, 5600, 3793.83],
-    [2000, 4000, 3060],
-    [2000, 4000, 3222.33],
-    [2500, 4000, 3133.33],
-    [1800, 4000, 3100],
-    [2000, 3500, 2750],
-    [2000, 3000, 2500],
-    [1800, 3000, 2433.33],
-    [2000, 2700, 2375],
-    [1500, 2800, 2150],
-    [1500, 2300, 2100],
-    [1600, 3500, 2057.14],
-    [1500, 2600, 2037.5],
-    [1500, 2417.54, 1905.85],
-    [1500, 2000, 1775],
-    [1500, 1800, 1650]
+  [5000, 10000, 6785.71],
+  [4000, 10000, 6825],
+  [3000, 6500, 4463.33],
+  [2500, 5600, 3793.83],
+  [2000, 4000, 3060],
+  [2000, 4000, 3222.33],
+  [2500, 4000, 3133.33],
+  [1800, 4000, 3100],
+  [2000, 3500, 2750],
+  [2000, 3000, 2500],
+  [1800, 3000, 2433.33],
+  [2000, 2700, 2375],
+  [1500, 2800, 2150],
+  [1500, 2300, 2100],
+  [1600, 3500, 2057.14],
+  [1500, 2600, 2037.5],
+  [1500, 2417.54, 1905.85],
+  [1500, 2000, 1775],
+  [1500, 1800, 1650]
 ];
+// prettier-ignore
 const cities = ['北京', '上海', '深圳', '广州', '苏州', '杭州', '南京', '福州', '青岛', '济南', '长春', '大连', '温州', '郑州', '武汉', '成都', '东莞', '沈阳', '烟台'];
 const barHeight = 50;
 
 option = {
-    title: {
-        text: 'How expensive is it to rent an apartment in China?',
-        subtext: 'Data from https://www.numbeo.com'
+  title: {
+    text: 'How expensive is it to rent an apartment in China?',
+    subtext: 'Data from https://www.numbeo.com'
+  },
+  legend: {
+    show: true,
+    top: 'bottom',
+    data: ['Range', 'Average']
+  },
+  grid: {
+    top: 100
+  },
+  angleAxis: {
+    type: 'category',
+    data: cities
+  },
+  tooltip: {
+    show: true,
+    formatter: function (params: any) {
+      const id = params.dataIndex;
+      return (
+        cities[id] +
+        '<br>Lowest:' +
+        data[id][0] +
+        '<br>Highest:' +
+        data[id][1] +
+        '<br>Average:' +
+        data[id][2]
+      );
+    }
+  },
+  radiusAxis: {},
+  polar: {},
+  series: [
+    {
+      type: 'bar',
+      itemStyle: {
+        color: 'transparent'
+      },
+      data: data.map(function (d) {
+        return d[0];
+      }),
+      coordinateSystem: 'polar',
+      stack: 'Min Max',
+      silent: true
     },
-    legend: {
-        show: true,
-        top: 'bottom',
-        data: ['Range', 'Average']
+    {
+      type: 'bar',
+      data: data.map(function (d) {
+        return d[1] - d[0];
+      }),
+      coordinateSystem: 'polar',
+      name: 'Range',
+      stack: 'Min Max'
     },
-    grid: {
-        top: 100
+    {
+      type: 'bar',
+      itemStyle: {
+        color: 'transparent'
+      },
+      data: data.map(function (d) {
+        return d[2] - barHeight;
+      }),
+      coordinateSystem: 'polar',
+      stack: 'Average',
+      silent: true,
+      z: 10
     },
-    angleAxis: {
-        type: 'category',
-        data: cities
-    },
-    tooltip: {
-        show: true,
-        formatter: function (params: any) {
-            const id = params.dataIndex;
-            return cities[id] + '<br>Lowest:' + data[id][0] + '<br>Highest:' + data[id][1] + '<br>Average:' + data[id][2];
-        }
-    },
-    radiusAxis: {
-    },
-    polar: {
-    },
-    series: [{
-        type: 'bar',
-        itemStyle: {
-            color: 'transparent'
-        },
-        data: data.map(function (d) {
-            return d[0];
-        }),
-        coordinateSystem: 'polar',
-        stack: 'Min Max',
-        silent: true
-    }, {
-        type: 'bar',
-        data: data.map(function (d) {
-            return d[1] - d[0];
-        }),
-        coordinateSystem: 'polar',
-        name: 'Range',
-        stack: 'Min Max'
-    }, {
-        type: 'bar',
-        itemStyle: {
-            color: 'transparent'
-        },
-        data: data.map(function (d) {
-            return d[2] - barHeight;
-        }),
-        coordinateSystem: 'polar',
-        stack: 'Average',
-        silent: true,
-        z: 10
-    }, {
-        type: 'bar',
-        data: data.map(function (d) {
-            return barHeight * 2;
-        }),
-        coordinateSystem: 'polar',
-        name: 'Average',
-        stack: 'Average',
-        barGap: '-100%',
-        z: 10
-    }]
+    {
+      type: 'bar',
+      data: data.map(function (d) {
+        return barHeight * 2;
+      }),
+      coordinateSystem: 'polar',
+      name: 'Average',
+      stack: 'Average',
+      barGap: '-100%',
+      z: 10
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-polar-stack-radial.ts b/public/examples/ts/bar-polar-stack-radial.ts
index 34a01e4..08519cf 100644
--- a/public/examples/ts/bar-polar-stack-radial.ts
+++ b/public/examples/ts/bar-polar-stack-radial.ts
@@ -6,46 +6,48 @@ difficulty: 7
 */
 
 option = {
-    angleAxis: {
-        type: 'category',
-        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+  angleAxis: {
+    type: 'category',
+    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+  },
+  radiusAxis: {},
+  polar: {},
+  series: [
+    {
+      type: 'bar',
+      data: [1, 2, 3, 4, 3, 5, 1],
+      coordinateSystem: 'polar',
+      name: 'A',
+      stack: 'a',
+      emphasis: {
+        focus: 'series'
+      }
     },
-    radiusAxis: {
+    {
+      type: 'bar',
+      data: [2, 4, 6, 1, 3, 2, 1],
+      coordinateSystem: 'polar',
+      name: 'B',
+      stack: 'a',
+      emphasis: {
+        focus: 'series'
+      }
     },
-    polar: {
-    },
-    series: [{
-        type: 'bar',
-        data: [1, 2, 3, 4, 3, 5, 1],
-        coordinateSystem: 'polar',
-        name: 'A',
-        stack: 'a',
-        emphasis: {
-            focus: 'series'
-        }
-    }, {
-        type: 'bar',
-        data: [2, 4, 6, 1, 3, 2, 1],
-        coordinateSystem: 'polar',
-        name: 'B',
-        stack: 'a',
-        emphasis: {
-            focus: 'series'
-        }
-    }, {
-        type: 'bar',
-        data: [1, 2, 3, 4, 1, 2, 5],
-        coordinateSystem: 'polar',
-        name: 'C',
-        stack: 'a',
-        emphasis: {
-            focus: 'series'
-        }
-    }],
-    legend: {
-        show: true,
-        data: ['A', 'B', 'C']
+    {
+      type: 'bar',
+      data: [1, 2, 3, 4, 1, 2, 5],
+      coordinateSystem: 'polar',
+      name: 'C',
+      stack: 'a',
+      emphasis: {
+        focus: 'series'
+      }
     }
+  ],
+  legend: {
+    show: true,
+    data: ['A', 'B', 'C']
+  }
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-polar-stack.ts b/public/examples/ts/bar-polar-stack.ts
index b81466b..14f4bc4 100644
--- a/public/examples/ts/bar-polar-stack.ts
+++ b/public/examples/ts/bar-polar-stack.ts
@@ -6,47 +6,49 @@ difficulty: 7
 */
 
 option = {
-    angleAxis: {
+  angleAxis: {},
+  radiusAxis: {
+    type: 'category',
+    data: ['Mon', 'Tue', 'Wed', 'Thu'],
+    z: 10
+  },
+  polar: {},
+  series: [
+    {
+      type: 'bar',
+      data: [1, 2, 3, 4],
+      coordinateSystem: 'polar',
+      name: 'A',
+      stack: 'a',
+      emphasis: {
+        focus: 'series'
+      }
     },
-    radiusAxis: {
-        type: 'category',
-        data: ['Mon', 'Tue', 'Wed', 'Thu'],
-        z: 10
+    {
+      type: 'bar',
+      data: [2, 4, 6, 8],
+      coordinateSystem: 'polar',
+      name: 'B',
+      stack: 'a',
+      emphasis: {
+        focus: 'series'
+      }
     },
-    polar: {
-    },
-    series: [{
-        type: 'bar',
-        data: [1, 2, 3, 4],
-        coordinateSystem: 'polar',
-        name: 'A',
-        stack: 'a',
-        emphasis: {
-            focus: 'series'
-        }
-    }, {
-        type: 'bar',
-        data: [2, 4, 6, 8],
-        coordinateSystem: 'polar',
-        name: 'B',
-        stack: 'a',
-        emphasis: {
-            focus: 'series'
-        }
-    }, {
-        type: 'bar',
-        data: [1, 2, 3, 4],
-        coordinateSystem: 'polar',
-        name: 'C',
-        stack: 'a',
-        emphasis: {
-            focus: 'series'
-        }
-    }],
-    legend: {
-        show: true,
-        data: ['A', 'B', 'C']
+    {
+      type: 'bar',
+      data: [1, 2, 3, 4],
+      coordinateSystem: 'polar',
+      name: 'C',
+      stack: 'a',
+      emphasis: {
+        focus: 'series'
+      }
     }
+  ],
+  legend: {
+    show: true,
+    data: ['A', 'B', 'C']
+  }
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-race-country.ts b/public/examples/ts/bar-race-country.ts
index ee402de..15d623d 100644
--- a/public/examples/ts/bar-race-country.ts
+++ b/public/examples/ts/bar-race-country.ts
@@ -7,136 +7,161 @@ videoStart: 1000
 videoEnd: 6000
 */
 
-
 const updateFrequency = 2000;
 const dimension = 0;
 
-const countryColors: Record<string, string> = {"Australia":"#00008b","Canada":"#f00","China":"#ffde00","Cuba":"#002a8f","Finland":"#003580","France":"#ed2939","Germany":"#000","Iceland":"#003897","India":"#f93","Japan":"#bc002d","North Korea":"#024fa2","South Korea":"#000","New Zealand":"#00247d","Norway":"#ef2b2d","Poland":"#dc143c","Russia":"#d52b1e","Turkey":"#e30a17","United Kingdom":"#00247d","United States":"#b22234"};
+const countryColors: Record<string, string> = {
+  Australia: '#00008b',
+  Canada: '#f00',
+  China: '#ffde00',
+  Cuba: '#002a8f',
+  Finland: '#003580',
+  France: '#ed2939',
+  Germany: '#000',
+  Iceland: '#003897',
+  India: '#f93',
+  Japan: '#bc002d',
+  'North Korea': '#024fa2',
+  'South Korea': '#000',
+  'New Zealand': '#00247d',
+  Norway: '#ef2b2d',
+  Poland: '#dc143c',
+  Russia: '#d52b1e',
+  Turkey: '#e30a17',
+  'United Kingdom': '#00247d',
+  'United States': '#b22234'
+};
 
 $.when(
-    $.getJSON('https://cdn.jsdelivr.net/npm/emoji-flags@1.3.0/data.json'),
-    $.getJSON(ROOT_PATH + '/data/asset/data/life-expectancy-table.json')
+  $.getJSON('https://cdn.jsdelivr.net/npm/emoji-flags@1.3.0/data.json'),
+  $.getJSON(ROOT_PATH + '/data/asset/data/life-expectancy-table.json')
 ).done(function (res0, res1) {
-    const flags = res0[0];
-    const data = res1[0];
-    const years: string[] = [];
-    for (var i = 0; i < data.length; ++i) {
-        if (years.length === 0 || years[years.length - 1] !== data[i][4]) {
-            years.push(data[i][4]);
-        }
+  const flags = res0[0];
+  const data = res1[0];
+  const years: string[] = [];
+  for (let i = 0; i < data.length; ++i) {
+    if (years.length === 0 || years[years.length - 1] !== data[i][4]) {
+      years.push(data[i][4]);
     }
+  }
 
-    function getFlag(countryName: string) {
-        if (!countryName) {
-            return '';
-        }
-        return (flags.find(function (item) {
-            return item.name === countryName;
-        }) || {}).emoji;
+  function getFlag(countryName: string) {
+    if (!countryName) {
+      return '';
     }
-    var startIndex = 10;
-    var startYear = years[startIndex];
+    return (
+      flags.find(function (item) {
+        return item.name === countryName;
+      }) || {}
+    ).emoji;
+  }
+  let startIndex = 10;
+  let startYear = years[startIndex];
 
-    option = {
-        grid: {
-            top: 10,
-            bottom: 30,
-            left: 150,
-            right: 80
-        },
-        xAxis: {
-            max: 'dataMax',
-            axisLabel: {
-                formatter: function (n: number) {
-                    return Math.round(n) + '';
-                }
-            }
+  option = {
+    grid: {
+      top: 10,
+      bottom: 30,
+      left: 150,
+      right: 80
+    },
+    xAxis: {
+      max: 'dataMax',
+      axisLabel: {
+        formatter: function (n: number) {
+          return Math.round(n) + '';
+        }
+      }
+    },
+    dataset: {
+      source: data.slice(1).filter(function (d) {
+        return d[4] === startYear;
+      })
+    },
+    yAxis: {
+      type: 'category',
+      inverse: true,
+      max: 10,
+      axisLabel: {
+        show: true,
+        fontSize: 14,
+        formatter: function (value: string) {
+          return value + '{flag|' + getFlag(value) + '}';
         },
-        dataset: {
-            source: data.slice(1).filter(function (d) {
-                return d[4] === startYear;
-            })
+        rich: {
+          flag: {
+            fontSize: 25,
+            padding: 5
+          }
+        }
+      },
+      animationDuration: 300,
+      animationDurationUpdate: 300
+    },
+    series: [
+      {
+        realtimeSort: true,
+        seriesLayoutBy: 'column',
+        type: 'bar',
+        itemStyle: {
+          color: function (param: any) {
+            return countryColors[param.value[3]] || '#5470c6';
+          }
         },
-        yAxis: {
-            type: 'category',
-            inverse: true,
-            max: 10,
-            axisLabel: {
-                show: true,
-                fontSize: 14,
-                formatter: function (value: string) {
-                    return value + '{flag|' + getFlag(value) + '}';
-                },
-                rich: {
-                    flag: {
-                        fontSize: 25,
-                        padding: 5
-                    }
-                }
-            },
-            animationDuration: 300,
-            animationDurationUpdate: 300
+        encode: {
+          x: dimension,
+          y: 3
         },
-        series: [{
-            realtimeSort: true,
-            seriesLayoutBy: 'column',
-            type: 'bar',
-            itemStyle: {
-                color: function (param: any) {
-                    return countryColors[param.value[3]] || '#5470c6';
-                }
-            },
-            encode: {
-                x: dimension,
-                y: 3
-            },
-            label: {
-                show: true,
-                precision: 1,
-                position: 'right',
-                valueAnimation: true,
-                fontFamily: 'monospace'
-            }
-        }],
-        // Disable init animation.
-        animationDuration: 0,
-        animationDurationUpdate: updateFrequency,
-        animationEasing: 'linear',
-        animationEasingUpdate: 'linear',
-        graphic: {
-            elements: [{
-                type: 'text',
-                right: 160,
-                bottom: 60,
-                style: {
-                    text: startYear,
-                    font: 'bolder 80px monospace',
-                    fill: 'rgba(100, 100, 100, 0.25)'
-                },
-                z: 100
-            }]
+        label: {
+          show: true,
+          precision: 1,
+          position: 'right',
+          valueAnimation: true,
+          fontFamily: 'monospace'
         }
-    };
+      }
+    ],
+    // Disable init animation.
+    animationDuration: 0,
+    animationDurationUpdate: updateFrequency,
+    animationEasing: 'linear',
+    animationEasingUpdate: 'linear',
+    graphic: {
+      elements: [
+        {
+          type: 'text',
+          right: 160,
+          bottom: 60,
+          style: {
+            text: startYear,
+            font: 'bolder 80px monospace',
+            fill: 'rgba(100, 100, 100, 0.25)'
+          },
+          z: 100
+        }
+      ]
+    }
+  };
 
-    // console.log(option);
-    myChart.setOption<echarts.EChartsOption>(option);
+  // console.log(option);
+  myChart.setOption<echarts.EChartsOption>(option);
 
-    for (var i = startIndex; i < years.length - 1; ++i) {
-        (function (i) {
-            setTimeout(function () {
-                updateYear(years[i + 1]);
-            }, (i - startIndex) * updateFrequency);
-        })(i);
-    }
+  for (let i = startIndex; i < years.length - 1; ++i) {
+    (function (i) {
+      setTimeout(function () {
+        updateYear(years[i + 1]);
+      }, (i - startIndex) * updateFrequency);
+    })(i);
+  }
 
-    function updateYear(year: string) {
-        var source = data.slice(1).filter(function (d) {
-            return d[4] === year;
-        });
-        option.series[0].data = source;
-        option.graphic.elements[0].style.text = year;
-        myChart.setOption<echarts.EChartsOption>(option);
-    }
-})
+  function updateYear(year: string) {
+    let source = data.slice(1).filter(function (d) {
+      return d[4] === year;
+    });
+    option.series[0].data = source;
+    option.graphic.elements[0].style.text = year;
+    myChart.setOption<echarts.EChartsOption>(option);
+  }
+});
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-race.ts b/public/examples/ts/bar-race.ts
index bc4de3d..a9ff049 100644
--- a/public/examples/ts/bar-race.ts
+++ b/public/examples/ts/bar-race.ts
@@ -9,63 +9,66 @@ videoEnd: 6000
 
 const data: number[] = [];
 for (let i = 0; i < 5; ++i) {
-    data.push(Math.round(Math.random() * 200));
+  data.push(Math.round(Math.random() * 200));
 }
 
 option = {
-    xAxis: {
-        max: 'dataMax',
-    },
-    yAxis: {
-        type: 'category',
-        data: ['A', 'B', 'C', 'D', 'E'],
-        inverse: true,
-        animationDuration: 300,
-        animationDurationUpdate: 300,
-        max: 2 // only the largest 3 bars will be displayed
-    },
-    series: [{
-        realtimeSort: true,
-        name: 'X',
-        type: 'bar',
-        data: data,
-        label: {
-            show: true,
-            position: 'right',
-            valueAnimation: true
-        }
-    }],
-    legend: {
-        show: true
-    },
-    animationDuration: 0,
-    animationDurationUpdate: 3000,
-    animationEasing: 'linear',
-    animationEasingUpdate: 'linear'
+  xAxis: {
+    max: 'dataMax'
+  },
+  yAxis: {
+    type: 'category',
+    data: ['A', 'B', 'C', 'D', 'E'],
+    inverse: true,
+    animationDuration: 300,
+    animationDurationUpdate: 300,
+    max: 2 // only the largest 3 bars will be displayed
+  },
+  series: [
+    {
+      realtimeSort: true,
+      name: 'X',
+      type: 'bar',
+      data: data,
+      label: {
+        show: true,
+        position: 'right',
+        valueAnimation: true
+      }
+    }
+  ],
+  legend: {
+    show: true
+  },
+  animationDuration: 0,
+  animationDurationUpdate: 3000,
+  animationEasing: 'linear',
+  animationEasingUpdate: 'linear'
 };
 
-function run () {
-    for (var i = 0; i < data.length; ++i) {
-        if (Math.random() > 0.9) {
-            data[i] += Math.round(Math.random() * 2000);
-        }
-        else {
-            data[i] += Math.round(Math.random() * 200);
-        }
+function run() {
+  for (var i = 0; i < data.length; ++i) {
+    if (Math.random() > 0.9) {
+      data[i] += Math.round(Math.random() * 2000);
+    } else {
+      data[i] += Math.round(Math.random() * 200);
     }
-    myChart.setOption<echarts.EChartsOption>({
-        series: [{
-            type: 'bar',
-            data
-        }]
-    });
+  }
+  myChart.setOption<echarts.EChartsOption>({
+    series: [
+      {
+        type: 'bar',
+        data
+      }
+    ]
+  });
 }
 
-setTimeout(function() {
-    run();
+setTimeout(function () {
+  run();
 }, 0);
 setInterval(function () {
-    run();
+  run();
 }, 3000);
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-rich-text.ts b/public/examples/ts/bar-rich-text.ts
index a4545d3..76fc0e7 100644
--- a/public/examples/ts/bar-rich-text.ts
+++ b/public/examples/ts/bar-rich-text.ts
@@ -5,149 +5,148 @@ titleCN: 天气统计(富文本)
 difficulty: 6
 */
 
-
 const weatherIcons = {
-    'Sunny': ROOT_PATH + '/data/asset/img/weather/sunny_128.png',
-    'Cloudy': ROOT_PATH + '/data/asset/img/weather/cloudy_128.png',
-    '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',
+  Showers: ROOT_PATH + '/data/asset/img/weather/showers_128.png'
 } as const;
 
 const seriesLabel = {
-    show: true
+  show: true
 } as const;
 
 option = {
-    title: {
-        text: 'Weather Statistics'
-    },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
-        }
-    },
-    legend: {
-        data: ['City Alpha', 'City Beta', 'City Gamma']
-    },
-    grid: {
-        left: 100
-    },
-    toolbox: {
-        show: true,
-        feature: {
-            saveAsImage: {}
-        }
-    },
-    xAxis: {
-        type: 'value',
-        name: 'Days',
-        axisLabel: {
-            formatter: '{value}'
+  title: {
+    text: 'Weather Statistics'
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  legend: {
+    data: ['City Alpha', 'City Beta', 'City Gamma']
+  },
+  grid: {
+    left: 100
+  },
+  toolbox: {
+    show: true,
+    feature: {
+      saveAsImage: {}
+    }
+  },
+  xAxis: {
+    type: 'value',
+    name: 'Days',
+    axisLabel: {
+      formatter: '{value}'
+    }
+  },
+  yAxis: {
+    type: 'category',
+    inverse: true,
+    data: ['Sunny', 'Cloudy', 'Showers'],
+    axisLabel: {
+      formatter: function (value) {
+        return '{' + value + '| }\n{value|' + value + '}';
+      },
+      margin: 20,
+      rich: {
+        value: {
+          lineHeight: 30,
+          align: 'center'
+        },
+        Sunny: {
+          height: 40,
+          align: 'center',
+          backgroundColor: {
+            image: weatherIcons.Sunny
+          }
+        },
+        Cloudy: {
+          height: 40,
+          align: 'center',
+          backgroundColor: {
+            image: weatherIcons.Cloudy
+          }
+        },
+        Showers: {
+          height: 40,
+          align: 'center',
+          backgroundColor: {
+            image: weatherIcons.Showers
+          }
         }
-    },
-    yAxis: {
-        type: 'category',
-        inverse: true,
-        data: ['Sunny', 'Cloudy', 'Showers'],
-        axisLabel: {
-            formatter: function (value) {
-                return '{' + value + '| }\n{value|' + value + '}';
+      }
+    }
+  },
+  series: [
+    {
+      name: 'City Alpha',
+      type: 'bar',
+      data: [165, 170, 30],
+      label: seriesLabel,
+      markPoint: {
+        symbolSize: 1,
+        symbolOffset: [0, '50%'],
+        label: {
+          formatter: '{a|{a}\n}{b|{b} }{c|{c}}',
+          backgroundColor: 'rgb(242,242,242)',
+          borderColor: '#aaa',
+          borderWidth: 1,
+          borderRadius: 4,
+          padding: [4, 10],
+          lineHeight: 26,
+          // shadowBlur: 5,
+          // shadowColor: '#000',
+          // shadowOffsetX: 0,
+          // shadowOffsetY: 1,
+          position: 'right',
+          distance: 20,
+          rich: {
+            a: {
+              align: 'center',
+              color: '#fff',
+              fontSize: 18,
+              textShadowBlur: 2,
+              textShadowColor: '#000',
+              textShadowOffsetX: 0,
+              textShadowOffsetY: 1,
+              textBorderColor: '#333',
+              textBorderWidth: 2
             },
-            margin: 20,
-            rich: {
-                value: {
-                    lineHeight: 30,
-                    align: 'center'
-                },
-                Sunny: {
-                    height: 40,
-                    align: 'center',
-                    backgroundColor: {
-                        image: weatherIcons.Sunny
-                    }
-                },
-                Cloudy: {
-                    height: 40,
-                    align: 'center',
-                    backgroundColor: {
-                        image: weatherIcons.Cloudy
-                    }
-                },
-                Showers: {
-                    height: 40,
-                    align: 'center',
-                    backgroundColor: {
-                        image: weatherIcons.Showers
-                    }
-                }
-            }
-        }
-    },
-    series: [
-        {
-            name: 'City Alpha',
-            type: 'bar',
-            data: [165, 170, 30],
-            label: seriesLabel,
-            markPoint: {
-                symbolSize: 1,
-                symbolOffset: [0, '50%'],
-                label: {
-                    formatter: '{a|{a}\n}{b|{b} }{c|{c}}',
-                    backgroundColor: 'rgb(242,242,242)',
-                    borderColor: '#aaa',
-                    borderWidth: 1,
-                    borderRadius: 4,
-                    padding: [4, 10],
-                    lineHeight: 26,
-                    // shadowBlur: 5,
-                    // shadowColor: '#000',
-                    // shadowOffsetX: 0,
-                    // shadowOffsetY: 1,
-                    position: 'right',
-                    distance: 20,
-                    rich: {
-                        a: {
-                            align: 'center',
-                            color: '#fff',
-                            fontSize: 18,
-                            textShadowBlur: 2,
-                            textShadowColor: '#000',
-                            textShadowOffsetX: 0,
-                            textShadowOffsetY: 1,
-                            textBorderColor: '#333',
-                            textBorderWidth: 2
-                        },
-                        b: {
-                            color: '#333'
-                        },
-                        c: {
-                            color: '#ff8811',
-                            textBorderColor: '#000',
-                            textBorderWidth: 1,
-                            fontSize: 22
-                        }
-                    }
-                },
-                data: [
-                    {type: 'max', name: 'max days: '},
-                    {type: 'min', name: 'min days: '}
-                ]
+            b: {
+              color: '#333'
+            },
+            c: {
+              color: '#ff8811',
+              textBorderColor: '#000',
+              textBorderWidth: 1,
+              fontSize: 22
             }
+          }
         },
-        {
-            name: 'City Beta',
-            type: 'bar',
-            label: seriesLabel,
-            data: [150, 105, 110]
-        },
-        {
-            name: 'City Gamma',
-            type: 'bar',
-            label: seriesLabel,
-            data: [220, 82, 63]
-        }
-    ]
+        data: [
+          { type: 'max', name: 'max days: ' },
+          { type: 'min', name: 'min days: ' }
+        ]
+      }
+    },
+    {
+      name: 'City Beta',
+      type: 'bar',
+      label: seriesLabel,
+      data: [150, 105, 110]
+    },
+    {
+      name: 'City Gamma',
+      type: 'bar',
+      label: seriesLabel,
+      data: [220, 82, 63]
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-simple.ts b/public/examples/ts/bar-simple.ts
index f1221bb..85dd6a5 100644
--- a/public/examples/ts/bar-simple.ts
+++ b/public/examples/ts/bar-simple.ts
@@ -6,17 +6,19 @@ difficulty: 0
 */
 
 option = {
-    xAxis: {
-        type: 'category',
-        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-    },
-    yAxis: {
-        type: 'value'
-    },
-    series: [{
-        data: [120, 200, 150, 80, 70, 110, 130],
-        type: 'bar'
-    }]
+  xAxis: {
+    type: 'category',
+    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+  },
+  yAxis: {
+    type: 'value'
+  },
+  series: [
+    {
+      data: [120, 200, 150, 80, 70, 110, 130],
+      type: 'bar'
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-stack.ts b/public/examples/ts/bar-stack.ts
index eeb8721..f93d9ca 100644
--- a/public/examples/ts/bar-stack.ts
+++ b/public/examples/ts/bar-stack.ts
@@ -6,122 +6,118 @@ difficulty: 3
 */
 
 option = {
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
-        }
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  legend: {},
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '3%',
+    containLabel: true
+  },
+  xAxis: [
+    {
+      type: 'category',
+      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+    }
+  ],
+  yAxis: [
+    {
+      type: 'value'
+    }
+  ],
+  series: [
+    {
+      name: 'Direct',
+      type: 'bar',
+      emphasis: {
+        focus: 'series'
+      },
+      data: [320, 332, 301, 334, 390, 330, 320]
     },
-    legend: {
-        data: ['Direct', 'Email', 'Union Ads', 'Video Ads', 'Search Engine', '百度', '谷歌', '必应', '其他']
+    {
+      name: 'Email',
+      type: 'bar',
+      stack: 'Ad',
+      emphasis: {
+        focus: 'series'
+      },
+      data: [120, 132, 101, 134, 90, 230, 210]
     },
-    grid: {
-        left: '3%',
-        right: '4%',
-        bottom: '3%',
-        containLabel: true
+    {
+      name: 'Union Ads',
+      type: 'bar',
+      stack: 'Ad',
+      emphasis: {
+        focus: 'series'
+      },
+      data: [220, 182, 191, 234, 290, 330, 310]
     },
-    xAxis: [
-        {
-            type: 'category',
-            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-        }
-    ],
-    yAxis: [
-        {
-            type: 'value'
-        }
-    ],
-    series: [
-        {
-            name: 'Direct',
-            type: 'bar',
-            emphasis: {
-                focus: 'series'
-            },
-            data: [320, 332, 301, 334, 390, 330, 320]
-        },
-        {
-            name: 'Email',
-            type: 'bar',
-            stack: 'Ad',
-            emphasis: {
-                focus: 'series'
-            },
-            data: [120, 132, 101, 134, 90, 230, 210]
-        },
-        {
-            name: 'Union Ads',
-            type: 'bar',
-            stack: 'Ad',
-            emphasis: {
-                focus: 'series'
-            },
-            data: [220, 182, 191, 234, 290, 330, 310]
-        },
-        {
-            name: 'Video Ads',
-            type: 'bar',
-            stack: 'Ad',
-            emphasis: {
-                focus: 'series'
-            },
-            data: [150, 232, 201, 154, 190, 330, 410]
-        },
-        {
-            name: 'Search Engine',
-            type: 'bar',
-            data: [862, 1018, 964, 1026, 1679, 1600, 1570],
-            emphasis: {
-                focus: 'series'
-            },
-            markLine: {
-                lineStyle: {
-                    type: 'dashed'
-                },
-                data: [
-                    [{type: 'min'}, {type: 'max'}]
-                ]
-            }
-        },
-        {
-            name: 'Baidu',
-            type: 'bar',
-            barWidth: 5,
-            stack: 'Search Engine',
-            emphasis: {
-                focus: 'series'
-            },
-            data: [620, 732, 701, 734, 1090, 1130, 1120]
-        },
-        {
-            name: 'Google',
-            type: 'bar',
-            stack: 'Search Engine',
-            emphasis: {
-                focus: 'series'
-            },
-            data: [120, 132, 101, 134, 290, 230, 220]
-        },
-        {
-            name: 'Bing',
-            type: 'bar',
-            stack: 'Search Engine',
-            emphasis: {
-                focus: 'series'
-            },
-            data: [60, 72, 71, 74, 190, 130, 110]
+    {
+      name: 'Video Ads',
+      type: 'bar',
+      stack: 'Ad',
+      emphasis: {
+        focus: 'series'
+      },
+      data: [150, 232, 201, 154, 190, 330, 410]
+    },
+    {
+      name: 'Search Engine',
+      type: 'bar',
+      data: [862, 1018, 964, 1026, 1679, 1600, 1570],
+      emphasis: {
+        focus: 'series'
+      },
+      markLine: {
+        lineStyle: {
+          type: 'dashed'
         },
-        {
-            name: 'Others',
-            type: 'bar',
-            stack: 'Search Engine',
-            emphasis: {
-                focus: 'series'
-            },
-            data: [62, 82, 91, 84, 109, 110, 120]
-        }
-    ]
+        data: [[{ type: 'min' }, { type: 'max' }]]
+      }
+    },
+    {
+      name: 'Baidu',
+      type: 'bar',
+      barWidth: 5,
+      stack: 'Search Engine',
+      emphasis: {
+        focus: 'series'
+      },
+      data: [620, 732, 701, 734, 1090, 1130, 1120]
+    },
+    {
+      name: 'Google',
+      type: 'bar',
+      stack: 'Search Engine',
+      emphasis: {
+        focus: 'series'
+      },
+      data: [120, 132, 101, 134, 290, 230, 220]
+    },
+    {
+      name: 'Bing',
+      type: 'bar',
+      stack: 'Search Engine',
+      emphasis: {
+        focus: 'series'
+      },
+      data: [60, 72, 71, 74, 190, 130, 110]
+    },
+    {
+      name: 'Others',
+      type: 'bar',
+      stack: 'Search Engine',
+      emphasis: {
+        focus: 'series'
+      },
+      data: [62, 82, 91, 84, 109, 110, 120]
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-tick-align.ts b/public/examples/ts/bar-tick-align.ts
index 2c96c16..43ca58c 100644
--- a/public/examples/ts/bar-tick-align.ts
+++ b/public/examples/ts/bar-tick-align.ts
@@ -6,38 +6,38 @@ difficulty: 0
 */
 
 option = {
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
-        }
-    },
-    grid: {
-        left: '3%',
-        right: '4%',
-        bottom: '3%',
-        containLabel: true
-    },
-    xAxis: [
-        {
-            type: 'category',
-            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
-            axisTick: {
-                alignWithLabel: true
-            }
-        }
-    ],
-    yAxis: [
-        {
-            type: 'value'
-        }
-    ],
-    series: [
-        {
-            name: 'Direct',
-            type: 'bar',
-            barWidth: '60%',
-            data: [10, 52, 200, 334, 390, 330, 220]
-        }
-    ]
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '3%',
+    containLabel: true
+  },
+  xAxis: [
+    {
+      type: 'category',
+      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
+      axisTick: {
+        alignWithLabel: true
+      }
+    }
+  ],
+  yAxis: [
+    {
+      type: 'value'
+    }
+  ],
+  series: [
+    {
+      name: 'Direct',
+      type: 'bar',
+      barWidth: '60%',
+      data: [10, 52, 200, 334, 390, 330, 220]
+    }
+  ]
 };
diff --git a/public/examples/ts/bar-waterfall.ts b/public/examples/ts/bar-waterfall.ts
index ba0daef..e45c676 100644
--- a/public/examples/ts/bar-waterfall.ts
+++ b/public/examples/ts/bar-waterfall.ts
@@ -6,62 +6,62 @@ difficulty: 1
 */
 
 option = {
-    title: {
-        text: 'Waterfall Chart',
-        subtext: 'Living Expenses in Shenzhen'
+  title: {
+    text: 'Waterfall Chart',
+    subtext: 'Living Expenses in Shenzhen'
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'shadow'
     },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
-        },
-        formatter: function (params) {
-            var tar = params[1];
-            return tar.name + '<br/>' + tar.seriesName + ' : ' + tar.value;
+    formatter: function (params: any) {
+      var tar = params[1];
+      return tar.name + '<br/>' + tar.seriesName + ' : ' + tar.value;
+    }
+  },
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '3%',
+    containLabel: true
+  },
+  xAxis: {
+    type: 'category',
+    splitLine: { show: false },
+    data: ['Total', 'Rent', 'Utilities', 'Transportation', 'Meals', 'Other']
+  },
+  yAxis: {
+    type: 'value'
+  },
+  series: [
+    {
+      name: 'Placeholder',
+      type: 'bar',
+      stack: 'Total',
+      itemStyle: {
+        borderColor: 'transparent',
+        color: 'transparent'
+      },
+      emphasis: {
+        itemStyle: {
+          borderColor: 'transparent',
+          color: 'transparent'
         }
+      },
+      data: [0, 1700, 1400, 1200, 300, 0]
     },
-    grid: {
-        left: '3%',
-        right: '4%',
-        bottom: '3%',
-        containLabel: true
-    },
-    xAxis: {
-        type: 'category',
-        splitLine: {show: false},
-        data: ['Total', 'Rent', 'Utilities', 'Transportation', 'Meals', 'Other']
-    },
-    yAxis: {
-        type: 'value'
-    },
-    series: [
-        {
-            name: 'Placeholder',
-            type: 'bar',
-            stack: 'Total',
-            itemStyle: {
-                borderColor: 'transparent',
-                color: 'transparent'
-            },
-            emphasis: {
-                itemStyle: {
-                    borderColor: 'transparent',
-                    color: 'transparent'
-                }
-            },
-            data: [0, 1700, 1400, 1200, 300, 0]
-        },
-        {
-            name: 'Life Cost',
-            type: 'bar',
-            stack: 'Total',
-            label: {
-                show: true,
-                position: 'inside'
-            },
-            data: [2900, 1200, 300, 200, 900, 300]
-        }
-    ]
+    {
+      name: 'Life Cost',
+      type: 'bar',
+      stack: 'Total',
+      label: {
+        show: true,
+        position: 'inside'
+      },
+      data: [2900, 1200, 300, 200, 900, 300]
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-waterfall2.ts b/public/examples/ts/bar-waterfall2.ts
index ea1465e..ff61a99 100644
--- a/public/examples/ts/bar-waterfall2.ts
+++ b/public/examples/ts/bar-waterfall2.ts
@@ -6,86 +6,85 @@ difficulty: 3
 */
 
 option = {
-    title: {
-        text: 'Accumulated Waterfall Chart'
+  title: {
+    text: 'Accumulated Waterfall Chart'
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'shadow'
     },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
-        },
-        formatter: function (params) {
-            let tar;
-            if (params[1].value !== '-') {
-                tar = params[1];
-            }
-            else {
-                tar = params[0];
-            }
-            return tar.name + '<br/>' + tar.seriesName + ' : ' + tar.value;
+    formatter: function (params: any) {
+      let tar;
+      if (params[1].value !== '-') {
+        tar = params[1];
+      } else {
+        tar = params[0];
+      }
+      return tar.name + '<br/>' + tar.seriesName + ' : ' + tar.value;
+    }
+  },
+  legend: {
+    data: ['支出', '收入']
+  },
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '3%',
+    containLabel: true
+  },
+  xAxis: {
+    type: 'category',
+    splitLine: { show: false },
+    data: (function () {
+      var list = [];
+      for (var i = 1; i <= 11; i++) {
+        list.push('11月' + i + '日');
+      }
+      return list;
+    })()
+  },
+  yAxis: {
+    type: 'value'
+  },
+  series: [
+    {
+      name: '辅助',
+      type: 'bar',
+      stack: 'Total',
+      itemStyle: {
+        borderColor: 'transparent',
+        color: 'transparent'
+      },
+      emphasis: {
+        itemStyle: {
+          borderColor: 'transparent',
+          color: 'transparent'
         }
+      },
+      data: [0, 900, 1245, 1530, 1376, 1376, 1511, 1689, 1856, 1495, 1292]
     },
-    legend: {
-        data: ['支出', '收入']
+    {
+      name: '收入',
+      type: 'bar',
+      stack: 'Total',
+      label: {
+        show: true,
+        position: 'top'
+      },
+      data: [900, 345, 393, '-', '-', 135, 178, 286, '-', '-', '-']
     },
-    grid: {
-        left: '3%',
-        right: '4%',
-        bottom: '3%',
-        containLabel: true
-    },
-    xAxis: {
-        type: 'category',
-        splitLine: {show: false},
-        data: function () {
-            var list = [];
-            for (var i = 1; i <= 11; i++) {
-                list.push('11月' + i + '日');
-            }
-            return list;
-        }()
-    },
-    yAxis: {
-        type: 'value'
-    },
-    series: [
-        {
-            name: '辅助',
-            type: 'bar',
-            stack: 'Total',
-            itemStyle: {
-                borderColor: 'transparent',
-                color: 'transparent'
-            },
-            emphasis: {
-                itemStyle: {
-                    borderColor: 'transparent',
-                    color: 'transparent'
-                }
-            },
-            data: [0, 900, 1245, 1530, 1376, 1376, 1511, 1689, 1856, 1495, 1292]
-        },
-        {
-            name: '收入',
-            type: 'bar',
-            stack: 'Total',
-            label: {
-                show: true,
-                position: 'top'
-            },
-            data: [900, 345, 393, '-', '-', 135, 178, 286, '-', '-', '-']
-        },
-        {
-            name: '支出',
-            type: 'bar',
-            stack: 'Total',
-            label: {
-                show: true,
-                position: 'bottom'
-            },
-            data: ['-', '-', '-', 108, 154, '-', '-', '-', 119, 361, 203]
-        }
-    ]
+    {
+      name: '支出',
+      type: 'bar',
+      stack: 'Total',
+      label: {
+        show: true,
+        position: 'bottom'
+      },
+      data: ['-', '-', '-', 108, 154, '-', '-', '-', 119, 361, 203]
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-y-category-stack.ts b/public/examples/ts/bar-y-category-stack.ts
index fa2c1b3..3d85803 100644
--- a/public/examples/ts/bar-y-category-stack.ts
+++ b/public/examples/ts/bar-y-category-stack.ts
@@ -5,90 +5,89 @@ category: bar
 difficulty: 3
 */
 option = {
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {            // Use axis to trigger tooltip
-            type: 'shadow'        // 'shadow' as default; can also be 'line' or 'shadow'
-        }
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      // Use axis to trigger tooltip
+      type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
+    }
+  },
+  legend: {},
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '3%',
+    containLabel: true
+  },
+  xAxis: {
+    type: 'value'
+  },
+  yAxis: {
+    type: 'category',
+    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+  },
+  series: [
+    {
+      name: 'Direct',
+      type: 'bar',
+      stack: 'total',
+      label: {
+        show: true
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [320, 302, 301, 334, 390, 330, 320]
     },
-    legend: {
-        data: ['Direct', 'Mail Ad', 'Affiliate Ad', 'Video Ad', 'Search Engine']
+    {
+      name: 'Mail Ad',
+      type: 'bar',
+      stack: 'total',
+      label: {
+        show: true
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [120, 132, 101, 134, 90, 230, 210]
     },
-    grid: {
-        left: '3%',
-        right: '4%',
-        bottom: '3%',
-        containLabel: true
+    {
+      name: 'Affiliate Ad',
+      type: 'bar',
+      stack: 'total',
+      label: {
+        show: true
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [220, 182, 191, 234, 290, 330, 310]
     },
-    xAxis: {
-        type: 'value'
+    {
+      name: 'Video Ad',
+      type: 'bar',
+      stack: 'total',
+      label: {
+        show: true
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [150, 212, 201, 154, 190, 330, 410]
     },
-    yAxis: {
-        type: 'category',
-        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-    },
-    series: [
-        {
-            name: 'Direct',
-            type: 'bar',
-            stack: 'total',
-            label: {
-                show: true
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [320, 302, 301, 334, 390, 330, 320]
-        },
-        {
-            name: 'Mail Ad',
-            type: 'bar',
-            stack: 'total',
-            label: {
-                show: true
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [120, 132, 101, 134, 90, 230, 210]
-        },
-        {
-            name: 'Affiliate Ad',
-            type: 'bar',
-            stack: 'total',
-            label: {
-                show: true
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [220, 182, 191, 234, 290, 330, 310]
-        },
-        {
-            name: 'Video Ad',
-            type: 'bar',
-            stack: 'total',
-            label: {
-                show: true
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [150, 212, 201, 154, 190, 330, 410]
-        },
-        {
-            name: 'Search Engine',
-            type: 'bar',
-            stack: 'total',
-            label: {
-                show: true
-            },
-            emphasis: {
-                focus: 'series'
-            },
-            data: [820, 832, 901, 934, 1290, 1330, 1320]
-        }
-    ]
+    {
+      name: 'Search Engine',
+      type: 'bar',
+      stack: 'total',
+      label: {
+        show: true
+      },
+      emphasis: {
+        focus: 'series'
+      },
+      data: [820, 832, 901, 934, 1290, 1330, 1320]
+    }
+  ]
 };
 
-export {};
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar-y-category.ts b/public/examples/ts/bar-y-category.ts
index 36d8272..dd81014 100644
--- a/public/examples/ts/bar-y-category.ts
+++ b/public/examples/ts/bar-y-category.ts
@@ -6,45 +6,42 @@ difficulty: 2
 */
 
 option = {
-    title: {
-        text: 'World Population'
+  title: {
+    text: 'World Population'
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  legend: {},
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '3%',
+    containLabel: true
+  },
+  xAxis: {
+    type: 'value',
+    boundaryGap: [0, 0.01]
+  },
+  yAxis: {
+    type: 'category',
+    data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World']
+  },
+  series: [
+    {
+      name: '2011',
+      type: 'bar',
+      data: [18203, 23489, 29034, 104970, 131744, 630230]
     },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
-        }
-    },
-    legend: {
-        data: ['2011', '2012']
-    },
-    grid: {
-        left: '3%',
-        right: '4%',
-        bottom: '3%',
-        containLabel: true
-    },
-    xAxis: {
-        type: 'value',
-        boundaryGap: [0, 0.01]
-    },
-    yAxis: {
-        type: 'category',
-        data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World']
-    },
-    series: [
-        {
-            name: '2011',
-            type: 'bar',
-            data: [18203, 23489, 29034, 104970, 131744, 630230]
-        },
-        {
-            name: '2012',
-            type: 'bar',
-            data: [19325, 23438, 31000, 121594, 134141, 681807]
-        }
-    ]
+    {
+      name: '2012',
+      type: 'bar',
+      data: [19325, 23438, 31000, 121594, 134141, 681807]
+    }
+  ]
 };
 
-
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bar1.ts b/public/examples/ts/bar1.ts
index e37585b..6ff1d14 100644
--- a/public/examples/ts/bar1.ts
+++ b/public/examples/ts/bar1.ts
@@ -6,71 +6,72 @@ difficulty: 4
 */
 
 option = {
-    title: {
-        text: 'Rainfall and Evaporation',
-        subtext: 'Fake Data'
+  title: {
+    text: 'Rainfall vs Evaporation',
+    subtext: 'Fake Data'
+  },
+  tooltip: {
+    trigger: 'axis'
+  },
+  legend: {
+    data: ['Rainfall', 'Evaporation']
+  },
+  toolbox: {
+    show: true,
+    feature: {
+      dataView: { show: true, readOnly: false },
+      magicType: { show: true, type: ['line', 'bar'] },
+      restore: { show: true },
+      saveAsImage: { show: true }
+    }
+  },
+  calculable: true,
+  xAxis: [
+    {
+      type: 'category',
+      // prettier-ignore
+      data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+    }
+  ],
+  yAxis: [
+    {
+      type: 'value'
+    }
+  ],
+  series: [
+    {
+      name: 'Rainfall',
+      type: 'bar',
+      data: [
+        2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
+      ],
+      markPoint: {
+        data: [
+          { type: 'max', name: 'Max' },
+          { type: 'min', name: 'Min' }
+        ]
+      },
+      markLine: {
+        data: [{ type: 'average', name: 'Avg' }]
+      }
     },
-    tooltip: {
-        trigger: 'axis'
-    },
-    legend: {
-        data: ['Rainfall', 'Evaporation']
-    },
-    toolbox: {
-        show: true,
-        feature: {
-            dataView: {show: true, readOnly: false},
-            magicType: {show: true, type: ['line', 'bar']},
-            restore: {show: true},
-            saveAsImage: {show: true}
-        }
-    },
-    calculable: true,
-    xAxis: [
-        {
-            type: 'category',
-            data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-        }
-    ],
-    yAxis: [
-        {
-            type: 'value'
-        }
-    ],
-    series: [
-        {
-            name: 'Rainfall',
-            type: 'bar',
-            data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],
-            markPoint: {
-                data: [
-                    {type: 'max', name: 'Max'},
-                    {type: 'min', name: 'Min'}
-                ]
-            },
-            markLine: {
-                data: [
-                    {type: 'average', name: 'Avg'}
-                ]
-            }
-        },
-        {
-            name: 'Evaporation',
-            type: 'bar',
-            data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
-            markPoint: {
-                data: [
-                    {name: '年最高', value: 182.2, xAxis: 7, yAxis: 183},
-                    {name: '年最低', value: 2.3, xAxis: 11, yAxis: 3}
-                ]
-            },
-            markLine: {
-                data: [
-                    {type: 'average', name: 'Avg'}
-                ]
-            }
-        }
-    ]
+    {
+      name: 'Evaporation',
+      type: 'bar',
+      data: [
+        2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3
+      ],
+      markPoint: {
+        data: [
+          { name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 },
+          { name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 }
+        ]
+      },
+      markLine: {
+        data: [{ type: 'average', name: 'Avg' }]
+      }
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/boxplot-light-velocity.ts b/public/examples/ts/boxplot-light-velocity.ts
index 5e6f8b9..3d73509 100644
--- a/public/examples/ts/boxplot-light-velocity.ts
+++ b/public/examples/ts/boxplot-light-velocity.ts
@@ -5,82 +5,87 @@ titleCN: 基础盒须图
 */
 
 option = {
-    title: [
-        {
-            text: 'Michelson-Morley Experiment',
-            left: 'center'
-        },
-        {
-            text: 'upper: Q3 + 1.5 * IQR \nlower: Q1 - 1.5 * IQR',
-            borderColor: '#999',
-            borderWidth: 1,
-            textStyle: {
-                fontWeight: 'normal',
-                fontSize: 14,
-                lineHeight: 20
-            },
-            left: '10%',
-            top: '90%'
-        }
-    ],
-    dataset: [{
-        source: [
-            [850, 740, 900, 1070, 930, 850, 950, 980, 980, 880, 1000, 980, 930, 650, 760, 810, 1000, 1000, 960, 960],
-            [960, 940, 960, 940, 880, 800, 850, 880, 900, 840, 830, 790, 810, 880, 880, 830, 800, 790, 760, 800],
-            [880, 880, 880, 860, 720, 720, 620, 860, 970, 950, 880, 910, 850, 870, 840, 840, 850, 840, 840, 840],
-            [890, 810, 810, 820, 800, 770, 760, 740, 750, 760, 910, 920, 890, 860, 880, 720, 840, 850, 850, 780],
-            [890, 840, 780, 810, 760, 810, 790, 810, 820, 850, 870, 870, 810, 740, 810, 940, 950, 800, 810, 870]
-        ]
-    }, {
-        transform: {
-            type: 'boxplot',
-            config: { itemNameFormatter: 'expr {value}' }
-        }
-    }, {
-        fromDatasetIndex: 1,
-        fromTransformResult: 1
-    }],
-    tooltip: {
-        trigger: 'item',
-        axisPointer: {
-            type: 'shadow'
-        }
+  title: [
+    {
+      text: 'Michelson-Morley Experiment',
+      left: 'center'
     },
-    grid: {
-        left: '10%',
-        right: '10%',
-        bottom: '15%'
+    {
+      text: 'upper: Q3 + 1.5 * IQR \nlower: Q1 - 1.5 * IQR',
+      borderColor: '#999',
+      borderWidth: 1,
+      textStyle: {
+        fontWeight: 'normal',
+        fontSize: 14,
+        lineHeight: 20
+      },
+      left: '10%',
+      top: '90%'
+    }
+  ],
+  dataset: [
+    {
+      // prettier-ignore
+      source: [
+        [850, 740, 900, 1070, 930, 850, 950, 980, 980, 880, 1000, 980, 930, 650, 760, 810, 1000, 1000, 960, 960],
+        [960, 940, 960, 940, 880, 800, 850, 880, 900, 840, 830, 790, 810, 880, 880, 830, 800, 790, 760, 800],
+        [880, 880, 880, 860, 720, 720, 620, 860, 970, 950, 880, 910, 850, 870, 840, 840, 850, 840, 840, 840],
+        [890, 810, 810, 820, 800, 770, 760, 740, 750, 760, 910, 920, 890, 860, 880, 720, 840, 850, 850, 780],
+        [890, 840, 780, 810, 760, 810, 790, 810, 820, 850, 870, 870, 810, 740, 810, 940, 950, 800, 810, 870]
+      ]
     },
-    xAxis: {
-        type: 'category',
-        boundaryGap: true,
-        nameGap: 30,
-        splitArea: {
-            show: false
-        },
-        splitLine: {
-            show: false
-        }
+    {
+      transform: {
+        type: 'boxplot',
+        config: { itemNameFormatter: 'expr {value}' }
+      }
     },
-    yAxis: {
-        type: 'value',
-        name: 'km/s minus 299,000',
-        splitArea: {
-            show: true
-        }
+    {
+      fromDatasetIndex: 1,
+      fromTransformResult: 1
+    }
+  ],
+  tooltip: {
+    trigger: 'item',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  grid: {
+    left: '10%',
+    right: '10%',
+    bottom: '15%'
+  },
+  xAxis: {
+    type: 'category',
+    boundaryGap: true,
+    nameGap: 30,
+    splitArea: {
+      show: false
     },
-    series: [
-        {
-            name: 'boxplot',
-            type: 'boxplot',
-            datasetIndex: 1
-        },
-        {
-            name: 'outlier',
-            type: 'scatter',
-            datasetIndex: 2
-        }
-    ]
+    splitLine: {
+      show: false
+    }
+  },
+  yAxis: {
+    type: 'value',
+    name: 'km/s minus 299,000',
+    splitArea: {
+      show: true
+    }
+  },
+  series: [
+    {
+      name: 'boxplot',
+      type: 'boxplot',
+      datasetIndex: 1
+    },
+    {
+      name: 'outlier',
+      type: 'scatter',
+      datasetIndex: 2
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/boxplot-light-velocity2.ts b/public/examples/ts/boxplot-light-velocity2.ts
index 14452ec..91e44af 100644
--- a/public/examples/ts/boxplot-light-velocity2.ts
+++ b/public/examples/ts/boxplot-light-velocity2.ts
@@ -5,85 +5,90 @@ titleCN: 垂直方向盒须图
 */
 
 option = {
-    title: [
-        {
-            text: 'Michelson-Morley Experiment',
-            left: 'center'
-        },
-        {
-            text: 'upper: Q3 + 1.5 * IRQ \nlower: Q1 - 1.5 * IRQ',
-            borderColor: '#999',
-            borderWidth: 1,
-            textStyle: {
-                fontSize: 14
-            },
-            left: '10%',
-            top: '90%'
-        }
-    ],
-    dataset: [{
-        source: [
-            [850, 740, 900, 1070, 930, 850, 950, 980, 980, 880, 1000, 980, 930, 650, 760, 810, 1000, 1000, 960, 960],
-            [960, 940, 960, 940, 880, 800, 850, 880, 900, 840, 830, 790, 810, 880, 880, 830, 800, 790, 760, 800],
-            [880, 880, 880, 860, 720, 720, 620, 860, 970, 950, 880, 910, 850, 870, 840, 840, 850, 840, 840, 840],
-            [890, 810, 810, 820, 800, 770, 760, 740, 750, 760, 910, 920, 890, 860, 880, 720, 840, 850, 850, 780],
-            [890, 840, 780, 810, 760, 810, 790, 810, 820, 850, 870, 870, 810, 740, 810, 940, 950, 800, 810, 870]
-        ]
-    }, {
-        transform: {
-            type: 'boxplot',
-            config: {
-                itemNameFormatter: function (params: any) {
-                    return 'expr ' + params.value;
-                }
-            }
-        }
-    }, {
-        fromDatasetIndex: 1,
-        fromTransformResult: 1
-    }],
-    tooltip: {
-        trigger: 'item',
-        axisPointer: {
-            type: 'shadow'
-        }
+  title: [
+    {
+      text: 'Michelson-Morley Experiment',
+      left: 'center'
     },
-    grid: {
-        left: '10%',
-        right: '10%',
-        bottom: '15%'
+    {
+      text: 'upper: Q3 + 1.5 * IRQ \nlower: Q1 - 1.5 * IRQ',
+      borderColor: '#999',
+      borderWidth: 1,
+      textStyle: {
+        fontSize: 14
+      },
+      left: '10%',
+      top: '90%'
+    }
+  ],
+  dataset: [
+    {
+      // prettier-ignore
+      source: [
+        [850, 740, 900, 1070, 930, 850, 950, 980, 980, 880, 1000, 980, 930, 650, 760, 810, 1000, 1000, 960, 960],
+        [960, 940, 960, 940, 880, 800, 850, 880, 900, 840, 830, 790, 810, 880, 880, 830, 800, 790, 760, 800],
+        [880, 880, 880, 860, 720, 720, 620, 860, 970, 950, 880, 910, 850, 870, 840, 840, 850, 840, 840, 840],
+        [890, 810, 810, 820, 800, 770, 760, 740, 750, 760, 910, 920, 890, 860, 880, 720, 840, 850, 850, 780],
+        [890, 840, 780, 810, 760, 810, 790, 810, 820, 850, 870, 870, 810, 740, 810, 940, 950, 800, 810, 870]
+      ]
     },
-    yAxis: {
-        type: 'category',
-        boundaryGap: true,
-        nameGap: 30,
-        splitArea: {
-            show: false
-        },
-        splitLine: {
-            show: false
+    {
+      transform: {
+        type: 'boxplot',
+        config: {
+          itemNameFormatter: function (params: any) {
+            return 'expr ' + params.value;
+          }
         }
+      }
     },
-    xAxis: {
-        type: 'value',
-        name: 'km/s minus 299,000',
-        splitArea: {
-            show: true
-        }
+    {
+      fromDatasetIndex: 1,
+      fromTransformResult: 1
+    }
+  ],
+  tooltip: {
+    trigger: 'item',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  grid: {
+    left: '10%',
+    right: '10%',
+    bottom: '15%'
+  },
+  yAxis: {
+    type: 'category',
+    boundaryGap: true,
+    nameGap: 30,
+    splitArea: {
+      show: false
     },
-    series: [
-        {
-            name: 'boxplot',
-            type: 'boxplot',
-            datasetIndex: 1
-        },
-        {
-            name: 'outlier',
-            type: 'scatter',
-            encode: { x: 1, y: 0 },
-            datasetIndex: 2
-        }
-    ]
+    splitLine: {
+      show: false
+    }
+  },
+  xAxis: {
+    type: 'value',
+    name: 'km/s minus 299,000',
+    splitArea: {
+      show: true
+    }
+  },
+  series: [
+    {
+      name: 'boxplot',
+      type: 'boxplot',
+      datasetIndex: 1
+    },
+    {
+      name: 'outlier',
+      type: 'scatter',
+      encode: { x: 1, y: 0 },
+      datasetIndex: 2
+    }
+  ]
 };
 
-export {};
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/boxplot-multi.ts b/public/examples/ts/boxplot-multi.ts
index f877282..9c7e31c 100644
--- a/public/examples/ts/boxplot-multi.ts
+++ b/public/examples/ts/boxplot-multi.ts
@@ -4,105 +4,117 @@ category: boxplot
 titleCN: 多系列盒须图
 */
 
-
 // Generate data.
 function makeData() {
-    let data = [];
-    for (let i = 0; i < 18; i++) {
-        let cate = [];
-        for (let j = 0; j < 100; j++) {
-            cate.push(Math.random() * 200);
-        }
-        data.push(cate);
+  let data = [];
+  for (let i = 0; i < 18; i++) {
+    let cate = [];
+    for (let j = 0; j < 100; j++) {
+      cate.push(Math.random() * 200);
     }
-    return data;
+    data.push(cate);
+  }
+  return data;
 }
 const data0 = makeData();
 const data1 = makeData();
 const data2 = makeData();
 
-
 option = {
-    title: {
-        text: 'Multiple Categories',
-        left: 'center'
+  title: {
+    text: 'Multiple Categories',
+    left: 'center'
+  },
+  dataset: [
+    {
+      source: data0
     },
-    dataset: [{
-        source: data0
-    }, {
-        source: data1
-    }, {
-        source: data2
-    }, {
-        fromDatasetIndex: 0,
-        transform: { type: 'boxplot' }
-    }, {
-        fromDatasetIndex: 1,
-        transform: { type: 'boxplot' }
-    }, {
-        fromDatasetIndex: 2,
-        transform: { type: 'boxplot' }
-    }],
-    legend: {
-        top: '10%'
+    {
+      source: data1
     },
-    tooltip: {
-        trigger: 'item',
-        axisPointer: {
-            type: 'shadow'
-        }
+    {
+      source: data2
     },
-    grid: {
-        left: '10%',
-        top: '20%',
-        right: '10%',
-        bottom: '15%'
+    {
+      fromDatasetIndex: 0,
+      transform: { type: 'boxplot' }
     },
-    xAxis: {
-        type: 'category',
-        boundaryGap: true,
-        nameGap: 30,
-        splitArea: {
-            show: true
-        },
-        splitLine: {
-            show: false
-        }
+    {
+      fromDatasetIndex: 1,
+      transform: { type: 'boxplot' }
     },
-    yAxis: {
-        type: 'value',
-        name: 'Value',
-        min: -400,
-        max: 600,
-        splitArea: {
-            show: false
-        }
+    {
+      fromDatasetIndex: 2,
+      transform: { type: 'boxplot' }
+    }
+  ],
+  legend: {
+    top: '10%'
+  },
+  tooltip: {
+    trigger: 'item',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  grid: {
+    left: '10%',
+    top: '20%',
+    right: '10%',
+    bottom: '15%'
+  },
+  xAxis: {
+    type: 'category',
+    boundaryGap: true,
+    nameGap: 30,
+    splitArea: {
+      show: true
     },
-    dataZoom: [{
-        type: 'inside',
-        start: 0,
-        end: 20
-    }, {
-        show: true,
-        type: 'slider',
-        top: '90%',
-        xAxisIndex: [0],
-        start: 0,
-        end: 20
-    }],
-    series: [{
-        name: 'category0',
-        type: 'boxplot',
-        datasetIndex: 3
-    }, {
-        name: 'category1',
-        type: 'boxplot',
-        datasetIndex: 4
-    }, {
-        name: 'category2',
-        type: 'boxplot',
-        datasetIndex: 5
-    }]
+    splitLine: {
+      show: false
+    }
+  },
+  yAxis: {
+    type: 'value',
+    name: 'Value',
+    min: -400,
+    max: 600,
+    splitArea: {
+      show: false
+    }
+  },
+  dataZoom: [
+    {
+      type: 'inside',
+      start: 0,
+      end: 20
+    },
+    {
+      show: true,
+      type: 'slider',
+      top: '90%',
+      xAxisIndex: [0],
+      start: 0,
+      end: 20
+    }
+  ],
+  series: [
+    {
+      name: 'category0',
+      type: 'boxplot',
+      datasetIndex: 3
+    },
+    {
+      name: 'category1',
+      type: 'boxplot',
+      datasetIndex: 4
+    },
+    {
+      name: 'category2',
+      type: 'boxplot',
+      datasetIndex: 5
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/bubble-gradient.ts b/public/examples/ts/bubble-gradient.ts
index 42ec11d..fe3294f 100644
--- a/public/examples/ts/bubble-gradient.ts
+++ b/public/examples/ts/bubble-gradient.ts
@@ -6,106 +6,158 @@ difficulty: 6
 */
 
 const data = [
-    [[28604,77,17096869,'Australia',1990],[31163,77.4,27662440,'Canada',1990],[1516,68,1154605773,'China',1990],[13670,74.7,10582082,'Cuba',1990],[28599,75,4986705,'Finland',1990],[29476,77.1,56943299,'France',1990],[31476,75.4,78958237,'Germany',1990],[28666,78.1,254830,'Iceland',1990],[1777,57.7,870601776,'India',1990],[29550,79.1,122249285,'Japan',1990],[2076,67.9,20194354,'North Korea',1990],[12087,72,42972254,'South Korea',1990],[24021,75.4,3397534,'New Zealand',1990],[43296,76.8,42 [...]
-    [[44056,81.8,23968973,'Australia',2015],[43294,81.7,35939927,'Canada',2015],[13334,76.9,1376048943,'China',2015],[21291,78.5,11389562,'Cuba',2015],[38923,80.8,5503457,'Finland',2015],[37599,81.9,64395345,'France',2015],[44053,81.1,80688545,'Germany',2015],[42182,82.8,329425,'Iceland',2015],[5903,66.8,1311050527,'India',2015],[36162,83.5,126573481,'Japan',2015],[1390,71.4,25155317,'North Korea',2015],[34644,80.7,50293439,'South Korea',2015],[34186,80.6,4528526,'New Zealand',2015],[643 [...]
+  [
+    [28604, 77, 17096869, 'Australia', 1990],
+    [31163, 77.4, 27662440, 'Canada', 1990],
+    [1516, 68, 1154605773, 'China', 1990],
+    [13670, 74.7, 10582082, 'Cuba', 1990],
+    [28599, 75, 4986705, 'Finland', 1990],
+    [29476, 77.1, 56943299, 'France', 1990],
+    [31476, 75.4, 78958237, 'Germany', 1990],
+    [28666, 78.1, 254830, 'Iceland', 1990],
+    [1777, 57.7, 870601776, 'India', 1990],
+    [29550, 79.1, 122249285, 'Japan', 1990],
+    [2076, 67.9, 20194354, 'North Korea', 1990],
+    [12087, 72, 42972254, 'South Korea', 1990],
+    [24021, 75.4, 3397534, 'New Zealand', 1990],
+    [43296, 76.8, 4240375, 'Norway', 1990],
+    [10088, 70.8, 38195258, 'Poland', 1990],
+    [19349, 69.6, 147568552, 'Russia', 1990],
+    [10670, 67.3, 53994605, 'Turkey', 1990],
+    [26424, 75.7, 57110117, 'United Kingdom', 1990],
+    [37062, 75.4, 252847810, 'United States', 1990]
+  ],
+  [
+    [44056, 81.8, 23968973, 'Australia', 2015],
+    [43294, 81.7, 35939927, 'Canada', 2015],
+    [13334, 76.9, 1376048943, 'China', 2015],
+    [21291, 78.5, 11389562, 'Cuba', 2015],
+    [38923, 80.8, 5503457, 'Finland', 2015],
+    [37599, 81.9, 64395345, 'France', 2015],
+    [44053, 81.1, 80688545, 'Germany', 2015],
+    [42182, 82.8, 329425, 'Iceland', 2015],
+    [5903, 66.8, 1311050527, 'India', 2015],
+    [36162, 83.5, 126573481, 'Japan', 2015],
+    [1390, 71.4, 25155317, 'North Korea', 2015],
+    [34644, 80.7, 50293439, 'South Korea', 2015],
+    [34186, 80.6, 4528526, 'New Zealand', 2015],
+    [64304, 81.6, 5210967, 'Norway', 2015],
+    [24787, 77.3, 38611794, 'Poland', 2015],
+    [23038, 73.13, 143456918, 'Russia', 2015],
+    [19360, 76.5, 78665830, 'Turkey', 2015],
+    [38225, 81.4, 64715810, 'United Kingdom', 2015],
+    [53354, 79.1, 321773631, 'United States', 2015]
+  ]
 ];
 
 option = {
-    backgroundColor: new echarts.graphic.RadialGradient(0.3, 0.3, 0.8, [{
-        offset: 0,
-        color: '#f7f8fa'
-    }, {
-        offset: 1,
-        color: '#cdd0d5'
-    }]),
-    title: {
-        text: 'Life Expectancy and GDP by Country' ,
-        left: '5%',
-        top: '3%'
+  backgroundColor: new echarts.graphic.RadialGradient(0.3, 0.3, 0.8, [
+    {
+      offset: 0,
+      color: '#f7f8fa'
     },
-    legend: {
-        right: '10%',
-        top: '3%',
-        data: ['1990', '2015']
+    {
+      offset: 1,
+      color: '#cdd0d5'
+    }
+  ]),
+  title: {
+    text: 'Life Expectancy and GDP by Country',
+    left: '5%',
+    top: '3%'
+  },
+  legend: {
+    right: '10%',
+    top: '3%',
+    data: ['1990', '2015']
+  },
+  grid: {
+    left: '8%',
+    top: '10%'
+  },
+  xAxis: {
+    splitLine: {
+      lineStyle: {
+        type: 'dashed'
+      }
+    }
+  },
+  yAxis: {
+    splitLine: {
+      lineStyle: {
+        type: 'dashed'
+      }
     },
-    grid: {
-        left: '8%',
-        top: '10%'
-    },
-    xAxis: {
-        splitLine: {
-            lineStyle: {
-                type: 'dashed'
-            }
+    scale: true
+  },
+  series: [
+    {
+      name: '1990',
+      data: data[0],
+      type: 'scatter',
+      symbolSize: function (data) {
+        return Math.sqrt(data[2]) / 5e2;
+      },
+      emphasis: {
+        focus: 'series',
+        label: {
+          show: true,
+          formatter: function (param: any) {
+            return param.data[3];
+          },
+          position: 'top'
         }
+      },
+      itemStyle: {
+        shadowBlur: 10,
+        shadowColor: 'rgba(120, 36, 50, 0.5)',
+        shadowOffsetY: 5,
+        color: new echarts.graphic.RadialGradient(0.4, 0.3, 1, [
+          {
+            offset: 0,
+            color: 'rgb(251, 118, 123)'
+          },
+          {
+            offset: 1,
+            color: 'rgb(204, 46, 72)'
+          }
+        ])
+      }
     },
-    yAxis: {
-        splitLine: {
-            lineStyle: {
-                type: 'dashed'
-            }
-        },
-        scale: true
-    },
-    series: [{
-        name: '1990',
-        data: data[0],
-        type: 'scatter',
-        symbolSize: function (data) {
-            return Math.sqrt(data[2]) / 5e2;
-        },
-        emphasis: {
-            focus: 'series',
-            label: {
-                show: true,
-                formatter: function (param) {
-                    return param.data[3];
-                },
-                position: 'top'
-            }
-        },
-        itemStyle: {
-            shadowBlur: 10,
-            shadowColor: 'rgba(120, 36, 50, 0.5)',
-            shadowOffsetY: 5,
-            color: new echarts.graphic.RadialGradient(0.4, 0.3, 1, [{
-                offset: 0,
-                color: 'rgb(251, 118, 123)'
-            }, {
-                offset: 1,
-                color: 'rgb(204, 46, 72)'
-            }])
-        }
-    }, {
-        name: '2015',
-        data: data[1],
-        type: 'scatter',
-        symbolSize: function (data) {
-            return Math.sqrt(data[2]) / 5e2;
-        },
-        emphasis: {
-            focus: 'series',
-            label: {
-                show: true,
-                formatter: function (param) {
-                    return param.data[3];
-                },
-                position: 'top'
-            }
-        },
-        itemStyle: {
-            shadowBlur: 10,
-            shadowColor: 'rgba(25, 100, 150, 0.5)',
-            shadowOffsetY: 5,
-            color: new echarts.graphic.RadialGradient(0.4, 0.3, 1, [{
-                offset: 0,
-                color: 'rgb(129, 227, 238)'
-            }, {
-                offset: 1,
-                color: 'rgb(25, 183, 207)'
-            }])
+    {
+      name: '2015',
+      data: data[1],
+      type: 'scatter',
+      symbolSize: function (data) {
+        return Math.sqrt(data[2]) / 5e2;
+      },
+      emphasis: {
+        focus: 'series',
+        label: {
+          show: true,
+          formatter: function (param) {
+            return param.data[3];
+          },
+          position: 'top'
         }
-    }]
+      },
+      itemStyle: {
+        shadowBlur: 10,
+        shadowColor: 'rgba(25, 100, 150, 0.5)',
+        shadowOffsetY: 5,
+        color: new echarts.graphic.RadialGradient(0.4, 0.3, 1, [
+          {
+            offset: 0,
+            color: 'rgb(129, 227, 238)'
+          },
+          {
+            offset: 1,
+            color: 'rgb(25, 183, 207)'
+          }
+        ])
+      }
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/calendar-charts.ts b/public/examples/ts/calendar-charts.ts
index 5418331..508ac34 100644
--- a/public/examples/ts/calendar-charts.ts
+++ b/public/examples/ts/calendar-charts.ts
@@ -7,189 +7,177 @@ difficulty: 11
 */
 
 function getVirtulData(year: string) {
-    year = year || '2017';
-    let date = +echarts.number.parseDate(year + '-01-01');
-    let end = +echarts.number.parseDate((+year + 1) + '-01-01');
-    let dayTime = 3600 * 24 * 1000;
-    let data = [];
-    for (let time = date; time < end; time += dayTime) {
-        data.push([
-            echarts.format.formatTime('yyyy-MM-dd', time),
-            Math.floor(Math.random() * 1000)
-        ]);
-    }
-    console.log(data[data.length - 1]);
-    return data;
+  year = year || '2017';
+  let date = +echarts.number.parseDate(year + '-01-01');
+  let end = +echarts.number.parseDate(+year + 1 + '-01-01');
+  let dayTime = 3600 * 24 * 1000;
+  let data = [];
+  for (let time = date; time < end; time += dayTime) {
+    data.push([
+      echarts.format.formatTime('yyyy-MM-dd', time),
+      Math.floor(Math.random() * 1000)
+    ]);
+  }
+  console.log(data[data.length - 1]);
+  return data;
 }
 
-
-
 const graphData = [
-    [
-       '2017-02-01',
-        260
-    ],
-    [
-        '2017-02-04',
-        200
-    ],
-    [
-        '2017-02-09',
-        279
-    ],
-    [
-        '2017-02-13',
-        847
-    ],
-    [
-        '2017-02-18',
-        241
-    ],
-    [
-        '2017-02-23',
-        411
-    ],
-    [
-        '2017-02-27',
-        985
-    ]
+  ['2017-02-01', 260],
+  ['2017-02-04', 200],
+  ['2017-02-09', 279],
+  ['2017-02-13', 847],
+  ['2017-02-18', 241],
+  ['2017-02-23', 411],
+  ['2017-02-27', 985]
 ];
 
 const links = graphData.map(function (item, idx) {
-    return {
-        source: idx,
-        target: idx + 1
-    };
+  return {
+    source: idx,
+    target: idx + 1
+  };
 });
 links.pop();
 
 option = {
-    tooltip: {
-        position: 'top'
-    },
+  tooltip: {
+    position: 'top'
+  },
 
-    visualMap: [{
-        min: 0,
-        max: 1000,
-        calculable: true,
-        seriesIndex: [2, 3, 4],
-        orient: 'horizontal',
-        left: '55%',
-        bottom: 20
-    }, {
-        min: 0,
-        max: 1000,
+  visualMap: [
+    {
+      min: 0,
+      max: 1000,
+      calculable: true,
+      seriesIndex: [2, 3, 4],
+      orient: 'horizontal',
+      left: '55%',
+      bottom: 20
+    },
+    {
+      min: 0,
+      max: 1000,
+      inRange: {
+        color: ['grey'],
+        opacity: [0, 0.3]
+      },
+      controller: {
         inRange: {
-            color: ['grey'],
-            opacity: [0, 0.3]
+          opacity: [0.3, 0.6]
         },
-        controller: {
-            inRange: {
-                opacity: [0.3, 0.6]
-            },
-            outOfRange: {
-                color: '#ccc'
-            }
-        },
-        seriesIndex: [1],
-        orient: 'horizontal',
-        left: '10%',
-        bottom: 20
-    }],
+        outOfRange: {
+          color: '#ccc'
+        }
+      },
+      seriesIndex: [1],
+      orient: 'horizontal',
+      left: '10%',
+      bottom: 20
+    }
+  ],
 
-    calendar: [{
-        orient: 'vertical',
-        yearLabel: {
-            margin: 40
-        },
-        monthLabel: {
-            nameMap: 'cn',
-            margin: 20
-        },
-        dayLabel: {
-            firstDay: 1,
-            nameMap: 'cn'
-        },
-        cellSize: 40,
-        range: '2017-02'
+  calendar: [
+    {
+      orient: 'vertical',
+      yearLabel: {
+        margin: 40
+      },
+      monthLabel: {
+        nameMap: 'cn',
+        margin: 20
+      },
+      dayLabel: {
+        firstDay: 1,
+        nameMap: 'cn'
+      },
+      cellSize: 40,
+      range: '2017-02'
     },
     {
-        orient: 'vertical',
-        yearLabel: {
-            margin: 40
-        },
-        monthLabel: {
-            margin: 20
-        },
-        cellSize: 40,
-        left: 460,
-        range: '2017-01'
+      orient: 'vertical',
+      yearLabel: {
+        margin: 40
+      },
+      monthLabel: {
+        margin: 20
+      },
+      cellSize: 40,
+      left: 460,
+      range: '2017-01'
     },
     {
-        orient: 'vertical',
-        yearLabel: {
-            margin: 40
-        },
-        monthLabel: {
-            margin: 20
-        },
-        cellSize: 40,
-        top: 350,
-        range: '2017-03'
+      orient: 'vertical',
+      yearLabel: {
+        margin: 40
+      },
+      monthLabel: {
+        margin: 20
+      },
+      cellSize: 40,
+      top: 350,
+      range: '2017-03'
     },
     {
-        orient: 'vertical',
-        yearLabel: {
-            margin: 40
-        },
-        dayLabel: {
-            firstDay: 1,
-            nameMap: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
-        },
-        monthLabel: {
-            nameMap: 'cn',
-            margin: 20
-        },
-        cellSize: 40,
-        top: 350,
-        left: 460,
-        range: '2017-04'
-    }],
+      orient: 'vertical',
+      yearLabel: {
+        margin: 40
+      },
+      dayLabel: {
+        firstDay: 1,
+        nameMap: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
+      },
+      monthLabel: {
+        nameMap: 'cn',
+        margin: 20
+      },
+      cellSize: 40,
+      top: 350,
+      left: 460,
+      range: '2017-04'
+    }
+  ],
 
-    series: [{
-        type: 'graph',
-        edgeSymbol: ['none', 'arrow'],
-        coordinateSystem: 'calendar',
-        links: links,
-        symbolSize: 10,
-        calendarIndex: 0,
-        data: graphData
-    }, {
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        data: getVirtulData('2017')
-    }, {
-        type: 'effectScatter',
-        coordinateSystem: 'calendar',
-        calendarIndex: 1,
-        symbolSize: function (val) {
-            return val[1] / 40;
-        },
-        data: getVirtulData('2017')
-    }, {
-        type: 'scatter',
-        coordinateSystem: 'calendar',
-        calendarIndex: 2,
-        symbolSize: function (val) {
-            return val[1] / 60;
-        },
-        data: getVirtulData('2017')
-    }, {
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        calendarIndex: 3,
-        data: getVirtulData('2017')
-    }]
+  series: [
+    {
+      type: 'graph',
+      edgeSymbol: ['none', 'arrow'],
+      coordinateSystem: 'calendar',
+      links: links,
+      symbolSize: 10,
+      calendarIndex: 0,
+      data: graphData
+    },
+    {
+      type: 'heatmap',
+      coordinateSystem: 'calendar',
+      data: getVirtulData('2017')
+    },
+    {
+      type: 'effectScatter',
+      coordinateSystem: 'calendar',
+      calendarIndex: 1,
+      symbolSize: function (val) {
+        return val[1] / 40;
+      },
+      data: getVirtulData('2017')
+    },
+    {
+      type: 'scatter',
+      coordinateSystem: 'calendar',
+      calendarIndex: 2,
+      symbolSize: function (val) {
+        return val[1] / 60;
+      },
+      data: getVirtulData('2017')
+    },
+    {
+      type: 'heatmap',
+      coordinateSystem: 'calendar',
+      calendarIndex: 3,
+      data: getVirtulData('2017')
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/calendar-effectscatter.ts b/public/examples/ts/calendar-effectscatter.ts
index 131d57c..32f4b5c 100644
--- a/public/examples/ts/calendar-effectscatter.ts
+++ b/public/examples/ts/calendar-effectscatter.ts
@@ -6,158 +6,165 @@ difficulty:3
 */
 
 function getVirtulData(year: string) {
-    year = year || '2017';
-    let date = +echarts.number.parseDate(year + '-01-01');
-    let end = +echarts.number.parseDate((+year + 1) + '-01-01');
-    let dayTime = 3600 * 24 * 1000;
-    let data: [string, number][] = [];
-    for (let time = date; time < end; time += dayTime) {
-        data.push([
-            echarts.format.formatTime('yyyy-MM-dd', time),
-            Math.floor(Math.random() * 10000)
-        ]);
-    }
-    return data;
+  year = year || '2017';
+  let date = +echarts.number.parseDate(year + '-01-01');
+  let end = +echarts.number.parseDate(+year + 1 + '-01-01');
+  let dayTime = 3600 * 24 * 1000;
+  let data: [string, number][] = [];
+  for (let time = date; time < end; time += dayTime) {
+    data.push([
+      echarts.format.formatTime('yyyy-MM-dd', time),
+      Math.floor(Math.random() * 10000)
+    ]);
+  }
+  return data;
 }
 
 const data = getVirtulData('2016');
 
 option = {
-    backgroundColor: '#404a59',
+  backgroundColor: '#404a59',
 
-    title: {
-        top: 30,
-        text: 'Daily Step Count in 2016',
-        subtext: 'Fake Data',
-        left: 'center',
-        textStyle: {
-            color: '#fff'
+  title: {
+    top: 30,
+    text: 'Daily Step Count in 2016',
+    subtext: 'Fake Data',
+    left: 'center',
+    textStyle: {
+      color: '#fff'
+    }
+  },
+  tooltip: {
+    trigger: 'item'
+  },
+  legend: {
+    top: '30',
+    left: '100',
+    data: ['Steps', 'Top 12'],
+    textStyle: {
+      color: '#fff'
+    }
+  },
+  calendar: [
+    {
+      top: 100,
+      left: 'center',
+      range: ['2016-01-01', '2016-06-30'],
+      splitLine: {
+        show: true,
+        lineStyle: {
+          color: '#000',
+          width: 4,
+          type: 'solid'
         }
+      },
+      yearLabel: {
+        formatter: '{start}  1st',
+        color: '#fff'
+      },
+      itemStyle: {
+        color: '#323c48',
+        borderWidth: 1,
+        borderColor: '#111'
+      }
     },
-    tooltip: {
-        trigger: 'item'
-    },
-    legend: {
-        top: '30',
-        left: '100',
-        data: ['Steps', 'Top 12'],
-        textStyle: {
-            color: '#fff'
+    {
+      top: 340,
+      left: 'center',
+      range: ['2016-07-01', '2016-12-31'],
+      splitLine: {
+        show: true,
+        lineStyle: {
+          color: '#000',
+          width: 4,
+          type: 'solid'
         }
+      },
+      yearLabel: {
+        formatter: '{start}  2nd',
+        color: '#fff'
+      },
+      itemStyle: {
+        color: '#323c48',
+        borderWidth: 1,
+        borderColor: '#111'
+      }
+    }
+  ],
+  series: [
+    {
+      name: 'Steps',
+      type: 'scatter',
+      coordinateSystem: 'calendar',
+      data: data,
+      symbolSize: function (val) {
+        return val[1] / 500;
+      },
+      itemStyle: {
+        color: '#ddb926'
+      }
     },
-    calendar: [{
-        top: 100,
-        left: 'center',
-        range: ['2016-01-01', '2016-06-30'],
-        splitLine: {
-            show: true,
-            lineStyle: {
-                color: '#000',
-                width: 4,
-                type: 'solid'
-            }
-        },
-        yearLabel: {
-            formatter: '{start}  1st',
-            color: '#fff'
-        },
-        itemStyle: {
-            color: '#323c48',
-            borderWidth: 1,
-            borderColor: '#111'
-        }
-    }, {
-        top: 340,
-        left: 'center',
-        range: ['2016-07-01', '2016-12-31'],
-        splitLine: {
-            show: true,
-            lineStyle: {
-                color: '#000',
-                width: 4,
-                type: 'solid'
-            }
-        },
-        yearLabel: {
-            formatter: '{start}  2nd',
-            color: '#fff'
-        },
-        itemStyle: {
-            color: '#323c48',
-            borderWidth: 1,
-            borderColor: '#111'
-        }
-    }],
-    series: [
-        {
-            name: 'Steps',
-            type: 'scatter',
-            coordinateSystem: 'calendar',
-            data: data,
-            symbolSize: function (val) {
-                return val[1] / 500;
-            },
-            itemStyle: {
-                color: '#ddb926'
-            }
-        },
-        {
-            name: 'Steps',
-            type: 'scatter',
-            coordinateSystem: 'calendar',
-            calendarIndex: 1,
-            data: data,
-            symbolSize: function (val) {
-                return val[1] / 500;
-            },
-            itemStyle: {
-                color: '#ddb926'
-            }
-        },
-        {
-            name: 'Top 12',
-            type: 'effectScatter',
-            coordinateSystem: 'calendar',
-            calendarIndex: 1,
-            data: data.sort(function (a, b) {
-                return b[1] - a[1];
-            }).slice(0, 12),
-            symbolSize: function (val) {
-                return val[1] / 500;
-            },
-            showEffectOn: 'render',
-            rippleEffect: {
-                brushType: 'stroke'
-            },
-            itemStyle: {
-                color: '#f4e925',
-                shadowBlur: 10,
-                shadowColor: '#333'
-            },
-            zlevel: 1
-        },
-        {
-            name: 'Top 12',
-            type: 'effectScatter',
-            coordinateSystem: 'calendar',
-            data: data.sort(function (a, b) {
-                return b[1] - a[1];
-            }).slice(0, 12),
-            symbolSize: function (val) {
-                return val[1] / 500;
-            },
-            showEffectOn: 'render',
-            rippleEffect: {
-                brushType: 'stroke'
-            },
-            itemStyle: {
-                color: '#f4e925',
-                shadowBlur: 10,
-                shadowColor: '#333'
-            },
-            zlevel: 1
-        }
-    ]
+    {
+      name: 'Steps',
+      type: 'scatter',
+      coordinateSystem: 'calendar',
+      calendarIndex: 1,
+      data: data,
+      symbolSize: function (val) {
+        return val[1] / 500;
+      },
+      itemStyle: {
+        color: '#ddb926'
+      }
+    },
+    {
+      name: 'Top 12',
+      type: 'effectScatter',
+      coordinateSystem: 'calendar',
+      calendarIndex: 1,
+      data: data
+        .sort(function (a, b) {
+          return b[1] - a[1];
+        })
+        .slice(0, 12),
+      symbolSize: function (val) {
+        return val[1] / 500;
+      },
+      showEffectOn: 'render',
+      rippleEffect: {
+        brushType: 'stroke'
+      },
+      itemStyle: {
+        color: '#f4e925',
+        shadowBlur: 10,
+        shadowColor: '#333'
+      },
+      zlevel: 1
+    },
+    {
+      name: 'Top 12',
+      type: 'effectScatter',
+      coordinateSystem: 'calendar',
+      data: data
+        .sort(function (a, b) {
+          return b[1] - a[1];
+        })
+        .slice(0, 12),
+      symbolSize: function (val) {
+        return val[1] / 500;
+      },
+      showEffectOn: 'render',
+      rippleEffect: {
+        brushType: 'stroke'
+      },
+      itemStyle: {
+        color: '#f4e925',
+        shadowBlur: 10,
+        shadowColor: '#333'
+      },
+      zlevel: 1
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/calendar-graph.ts b/public/examples/ts/calendar-graph.ts
index 63c6251..152222d 100644
--- a/public/examples/ts/calendar-graph.ts
+++ b/public/examples/ts/calendar-graph.ts
@@ -6,121 +6,102 @@ difficulty: 4
 */
 
 const graphData: [string, number][] = [
-    [
-       '2017-02-01',
-        260
-    ],
-    [
-        '2017-02-04',
-        200
-    ],
-    [
-        '2017-02-09',
-        279
-    ],
-    [
-        '2017-02-13',
-        847
-    ],
-    [
-        '2017-02-18',
-        241
-    ],
-    [
-        '2017-02-23',
-        411
-    ],
-    [
-        '2017-03-14',
-        985
-    ]
+  ['2017-02-01', 260],
+  ['2017-02-04', 200],
+  ['2017-02-09', 279],
+  ['2017-02-13', 847],
+  ['2017-02-18', 241],
+  ['2017-02-23', 411],
+  ['2017-03-14', 985]
 ];
 
 const links = graphData.map(function (item, idx) {
-    return {
-        source: idx,
-        target: idx + 1
-    };
+  return {
+    source: idx,
+    target: idx + 1
+  };
 });
 links.pop();
 
 function getVirtulData(year: string) {
-    year = year || '2017';
-    var date = +echarts.number.parseDate(year + '-01-01');
-    var end = +echarts.number.parseDate((+year + 1) + '-01-01');
-    var dayTime = 3600 * 24 * 1000;
-    var data = [];
-    for (var time = date; time < end; time += dayTime) {
-        data.push([
-            echarts.format.formatTime('yyyy-MM-dd', time),
-            Math.floor(Math.random() * 1000)
-        ]);
-    }
-    return data;
+  year = year || '2017';
+  var date = +echarts.number.parseDate(year + '-01-01');
+  var end = +echarts.number.parseDate(+year + 1 + '-01-01');
+  var dayTime = 3600 * 24 * 1000;
+  var data = [];
+  for (var time = date; time < end; time += dayTime) {
+    data.push([
+      echarts.format.formatTime('yyyy-MM-dd', time),
+      Math.floor(Math.random() * 1000)
+    ]);
+  }
+  return data;
 }
 
-
 option = {
-    tooltip: {},
-    calendar: {
-        top: 'middle',
-        left: 'center',
-        orient: 'vertical',
-        cellSize: 40,
-        yearLabel: {
-            margin: 50,
-            fontSize: 30
-        },
-        dayLabel: {
-            firstDay: 1,
-            nameMap: 'cn'
-        },
-        monthLabel: {
-            nameMap: 'cn',
-            margin: 15,
-            fontSize: 20,
-            color: '#999'
-        },
-        range: ['2017-02', '2017-03-31']
+  tooltip: {},
+  calendar: {
+    top: 'middle',
+    left: 'center',
+    orient: 'vertical',
+    cellSize: 40,
+    yearLabel: {
+      margin: 50,
+      fontSize: 30
+    },
+    dayLabel: {
+      firstDay: 1,
+      nameMap: 'cn'
     },
-    visualMap: {
-        min: 0,
-        max: 1000,
-        type: 'piecewise',
-        left: 'center',
-        bottom: 20,
-        inRange: {
-            color: ['#5291FF', '#C7DBFF']
-        },
-        seriesIndex: [1],
-        orient: 'horizontal'
+    monthLabel: {
+      nameMap: 'cn',
+      margin: 15,
+      fontSize: 20,
+      color: '#999'
     },
-    series: [{
-        type: 'graph',
-        edgeSymbol: ['none', 'arrow'],
-        coordinateSystem: 'calendar',
-        links: links,
-        symbolSize: 15,
-        calendarIndex: 0,
-        itemStyle: {
-            color: 'yellow',
-            shadowBlur: 9,
-            shadowOffsetX: 1.5,
-            shadowOffsetY: 3,
-            shadowColor: '#555'
-        },
-        lineStyle: {
-            color: '#D10E00',
-            width: 1,
-            opacity: 1
-        },
-        data: graphData,
-        z: 20
-    }, {
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        data: getVirtulData('2017')
-    }]
+    range: ['2017-02', '2017-03-31']
+  },
+  visualMap: {
+    min: 0,
+    max: 1000,
+    type: 'piecewise',
+    left: 'center',
+    bottom: 20,
+    inRange: {
+      color: ['#5291FF', '#C7DBFF']
+    },
+    seriesIndex: [1],
+    orient: 'horizontal'
+  },
+  series: [
+    {
+      type: 'graph',
+      edgeSymbol: ['none', 'arrow'],
+      coordinateSystem: 'calendar',
+      links: links,
+      symbolSize: 15,
+      calendarIndex: 0,
+      itemStyle: {
+        color: 'yellow',
+        shadowBlur: 9,
+        shadowOffsetX: 1.5,
+        shadowOffsetY: 3,
+        shadowColor: '#555'
+      },
+      lineStyle: {
+        color: '#D10E00',
+        width: 1,
+        opacity: 1
+      },
+      data: graphData,
+      z: 20
+    },
+    {
+      type: 'heatmap',
+      coordinateSystem: 'calendar',
+      data: getVirtulData('2017')
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/calendar-heatmap.ts b/public/examples/ts/calendar-heatmap.ts
index 389c667..c4ee50f 100644
--- a/public/examples/ts/calendar-heatmap.ts
+++ b/public/examples/ts/calendar-heatmap.ts
@@ -6,51 +6,51 @@ difficulty: 1
 */
 
 function getVirtulData(year: string) {
-    year = year || '2017';
-    var date = +echarts.number.parseDate(year + '-01-01');
-    var end = +echarts.number.parseDate((+year + 1) + '-01-01');
-    var dayTime = 3600 * 24 * 1000;
-    var data: [string, number][] = [];
-    for (var time = date; time < end; time += dayTime) {
-        data.push([
-            echarts.format.formatTime('yyyy-MM-dd', time),
-            Math.floor(Math.random() * 10000)
-        ]);
-    }
-    return data;
+  year = year || '2017';
+  var date = +echarts.number.parseDate(year + '-01-01');
+  var end = +echarts.number.parseDate(+year + 1 + '-01-01');
+  var dayTime = 3600 * 24 * 1000;
+  var data: [string, number][] = [];
+  for (var time = date; time < end; time += dayTime) {
+    data.push([
+      echarts.format.formatTime('yyyy-MM-dd', time),
+      Math.floor(Math.random() * 10000)
+    ]);
+  }
+  return data;
 }
 
 option = {
-    title: {
-        top: 30,
-        left: 'center',
-        text: 'Daily Step Count'
+  title: {
+    top: 30,
+    left: 'center',
+    text: 'Daily Step Count'
+  },
+  tooltip: {},
+  visualMap: {
+    min: 0,
+    max: 10000,
+    type: 'piecewise',
+    orient: 'horizontal',
+    left: 'center',
+    top: 65
+  },
+  calendar: {
+    top: 120,
+    left: 30,
+    right: 30,
+    cellSize: ['auto', 13],
+    range: '2016',
+    itemStyle: {
+      borderWidth: 0.5
     },
-    tooltip: {},
-    visualMap: {
-        min: 0,
-        max: 10000,
-        type: 'piecewise',
-        orient: 'horizontal',
-        left: 'center',
-        top: 65
-    },
-    calendar: {
-        top: 120,
-        left: 30,
-        right: 30,
-        cellSize: ['auto', 13],
-        range: '2016',
-        itemStyle: {
-            borderWidth: 0.5
-        },
-        yearLabel: {show: false}
-    },
-    series: {
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        data: getVirtulData('2016')
-    }
+    yearLabel: { show: false }
+  },
+  series: {
+    type: 'heatmap',
+    coordinateSystem: 'calendar',
+    data: getVirtulData('2016')
+  }
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/calendar-horizontal.ts b/public/examples/ts/calendar-horizontal.ts
index c764b97..c0c8f13 100644
--- a/public/examples/ts/calendar-horizontal.ts
+++ b/public/examples/ts/calendar-horizontal.ts
@@ -7,66 +7,69 @@ difficulty: 2
 */
 
 function getVirtulData(year: string) {
-    year = year || '2017';
-    let date = +echarts.number.parseDate(year + '-01-01');
-    let end = +echarts.number.parseDate((+year + 1) + '-01-01');
-    let dayTime = 3600 * 24 * 1000;
-    let data: [string, number][] = [];
-    for (let time = date; time < end; time += dayTime) {
-        data.push([
-            echarts.format.formatTime('yyyy-MM-dd', time),
-            Math.floor(Math.random() * 1000)
-        ]);
-    }
-    return data;
+  year = year || '2017';
+  let date = +echarts.number.parseDate(year + '-01-01');
+  let end = +echarts.number.parseDate(+year + 1 + '-01-01');
+  let dayTime = 3600 * 24 * 1000;
+  let data: [string, number][] = [];
+  for (let time = date; time < end; time += dayTime) {
+    data.push([
+      echarts.format.formatTime('yyyy-MM-dd', time),
+      Math.floor(Math.random() * 1000)
+    ]);
+  }
+  return data;
 }
 
-
-
 option = {
-    tooltip: {
-        position: 'top'
+  tooltip: {
+    position: 'top'
+  },
+  visualMap: {
+    min: 0,
+    max: 1000,
+    calculable: true,
+    orient: 'horizontal',
+    left: 'center',
+    top: 'top'
+  },
+
+  calendar: [
+    {
+      range: '2017',
+      cellSize: ['auto', 20]
     },
-    visualMap: {
-        min: 0,
-        max: 1000,
-        calculable: true,
-        orient: 'horizontal',
-        left: 'center',
-        top: 'top'
+    {
+      top: 260,
+      range: '2016',
+      cellSize: ['auto', 20]
     },
+    {
+      top: 450,
+      range: '2015',
+      cellSize: ['auto', 20],
+      right: 5
+    }
+  ],
 
-    calendar: [{
-        range: '2017',
-        cellSize: ['auto', 20]
+  series: [
+    {
+      type: 'heatmap',
+      coordinateSystem: 'calendar',
+      calendarIndex: 0,
+      data: getVirtulData('2017')
     },
     {
-        top: 260,
-        range: '2016',
-        cellSize: ['auto', 20]
+      type: 'heatmap',
+      coordinateSystem: 'calendar',
+      calendarIndex: 1,
+      data: getVirtulData('2016')
     },
     {
-        top: 450,
-        range: '2015',
-        cellSize: ['auto', 20],
-        right: 5
-    }],
-
-    series: [{
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        calendarIndex: 0,
-        data: getVirtulData(2017)
-    }, {
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        calendarIndex: 1,
-        data: getVirtulData(2016)
-    }, {
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        calendarIndex: 2,
-        data: getVirtulData(2015)
-    }]
-
+      type: 'heatmap',
+      coordinateSystem: 'calendar',
+      calendarIndex: 2,
+      data: getVirtulData('2015')
+    }
+  ]
 };
diff --git a/public/examples/ts/calendar-lunar.ts b/public/examples/ts/calendar-lunar.ts
index ea41f54..7db582a 100644
--- a/public/examples/ts/calendar-lunar.ts
+++ b/public/examples/ts/calendar-lunar.ts
@@ -6,465 +6,462 @@ difficulty: 4
 */
 
 const dateList = [
-    ['2017-1-1', '初四'],
-    ['2017-1-2', '初五'],
-    ['2017-1-3', '初六'],
-    ['2017-1-4', '初七'],
-    ['2017-1-5', '初八', '小寒'],
-    ['2017-1-6', '初九'],
-    ['2017-1-7', '初十'],
-    ['2017-1-8', '十一'],
-    ['2017-1-9', '十二'],
-    ['2017-1-10', '十三'],
-    ['2017-1-11', '十四'],
-    ['2017-1-12', '十五'],
-    ['2017-1-13', '十六'],
-    ['2017-1-14', '十七'],
-    ['2017-1-15', '十八'],
-    ['2017-1-16', '十九'],
-    ['2017-1-17', '二十'],
-    ['2017-1-18', '廿一'],
-    ['2017-1-19', '廿二'],
-    ['2017-1-20', '廿三', '大寒'],
-    ['2017-1-21', '廿四'],
-    ['2017-1-22', '廿五'],
-    ['2017-1-23', '廿六'],
-    ['2017-1-24', '廿七'],
-    ['2017-1-25', '廿八'],
-    ['2017-1-26', '廿九'],
-    ['2017-1-27', '三十'],
-    ['2017-1-28', '正月'],
-    ['2017-1-29', '初二'],
-    ['2017-1-30', '初三'],
-    ['2017-1-31', '初四'],
-    ['2017-2-1', '初五'],
-    ['2017-2-2', '初六'],
-    ['2017-2-3', '初七', '立春'],
-    ['2017-2-4', '初八'],
-    ['2017-2-5', '初九'],
-    ['2017-2-6', '初十'],
-    ['2017-2-7', '十一'],
-    ['2017-2-8', '十二'],
-    ['2017-2-9', '十三'],
-    ['2017-2-10', '十四'],
-    ['2017-2-11', '十五'],
-    ['2017-2-12', '十六'],
-    ['2017-2-13', '十七'],
-    ['2017-2-14', '十八'],
-    ['2017-2-15', '十九'],
-    ['2017-2-16', '二十'],
-    ['2017-2-17', '廿一'],
-    ['2017-2-18', '廿二', '雨水'],
-    ['2017-2-19', '廿三'],
-    ['2017-2-20', '廿四'],
-    ['2017-2-21', '廿五'],
-    ['2017-2-22', '廿六'],
-    ['2017-2-23', '廿七'],
-    ['2017-2-24', '廿八'],
-    ['2017-2-25', '廿九'],
-    ['2017-2-26', '二月'],
-    ['2017-2-27', '初二'],
-    ['2017-2-28', '初三'],
-    ['2017-3-1', '初四'],
-    ['2017-3-2', '初五'],
-    ['2017-3-3', '初六'],
-    ['2017-3-4', '初七'],
-    ['2017-3-5', '初八', '驚蟄'],
-    ['2017-3-6', '初九'],
-    ['2017-3-7', '初十'],
-    ['2017-3-8', '十一'],
-    ['2017-3-9', '十二'],
-    ['2017-3-10', '十三'],
-    ['2017-3-11', '十四'],
-    ['2017-3-12', '十五'],
-    ['2017-3-13', '十六'],
-    ['2017-3-14', '十七'],
-    ['2017-3-15', '十八'],
-    ['2017-3-16', '十九'],
-    ['2017-3-17', '二十'],
-    ['2017-3-18', '廿一'],
-    ['2017-3-19', '廿二'],
-    ['2017-3-20', '廿三', '春分'],
-    ['2017-3-21', '廿四'],
-    ['2017-3-22', '廿五'],
-    ['2017-3-23', '廿六'],
-    ['2017-3-24', '廿七'],
-    ['2017-3-25', '廿八'],
-    ['2017-3-26', '廿九'],
-    ['2017-3-27', '三十'],
-    ['2017-3-28', '三月'],
-    ['2017-3-29', '初二'],
-    ['2017-3-30', '初三'],
-    ['2017-3-31', '初四'],
-    ['2017-4-1', '初五'],
-    ['2017-4-2', '初六'],
-    ['2017-4-3', '初七'],
-    ['2017-4-4', '初八', '清明'],
-    ['2017-4-5', '初九'],
-    ['2017-4-6', '初十'],
-    ['2017-4-7', '十一'],
-    ['2017-4-8', '十二'],
-    ['2017-4-9', '十三'],
-    ['2017-4-10', '十四'],
-    ['2017-4-11', '十五'],
-    ['2017-4-12', '十六'],
-    ['2017-4-13', '十七'],
-    ['2017-4-14', '十八'],
-    ['2017-4-15', '十九'],
-    ['2017-4-16', '二十'],
-    ['2017-4-17', '廿一'],
-    ['2017-4-18', '廿二'],
-    ['2017-4-19', '廿三'],
-    ['2017-4-20', '廿四', '穀雨'],
-    ['2017-4-21', '廿五'],
-    ['2017-4-22', '廿六'],
-    ['2017-4-23', '廿七'],
-    ['2017-4-24', '廿八'],
-    ['2017-4-25', '廿九'],
-    ['2017-4-26', '四月'],
-    ['2017-4-27', '初二'],
-    ['2017-4-28', '初三'],
-    ['2017-4-29', '初四'],
-    ['2017-4-30', '初五'],
-    ['2017-5-1', '初六'],
-    ['2017-5-2', '初七'],
-    ['2017-5-3', '初八'],
-    ['2017-5-4', '初九'],
-    ['2017-5-5', '初十', '立夏'],
-    ['2017-5-6', '十一'],
-    ['2017-5-7', '十二'],
-    ['2017-5-8', '十三'],
-    ['2017-5-9', '十四'],
-    ['2017-5-10', '十五'],
-    ['2017-5-11', '十六'],
-    ['2017-5-12', '十七'],
-    ['2017-5-13', '十八'],
-    ['2017-5-14', '十九'],
-    ['2017-5-15', '二十'],
-    ['2017-5-16', '廿一'],
-    ['2017-5-17', '廿二'],
-    ['2017-5-18', '廿三'],
-    ['2017-5-19', '廿四'],
-    ['2017-5-20', '廿五'],
-    ['2017-5-21', '廿六', '小滿'],
-    ['2017-5-22', '廿七'],
-    ['2017-5-23', '廿八'],
-    ['2017-5-24', '廿九'],
-    ['2017-5-25', '三十'],
-    ['2017-5-26', '五月'],
-    ['2017-5-27', '初二'],
-    ['2017-5-28', '初三'],
-    ['2017-5-29', '初四'],
-    ['2017-5-30', '初五'],
-    ['2017-5-31', '初六'],
-    ['2017-6-1', '初七'],
-    ['2017-6-2', '初八'],
-    ['2017-6-3', '初九'],
-    ['2017-6-4', '初十'],
-    ['2017-6-5', '十一', '芒種'],
-    ['2017-6-6', '十二'],
-    ['2017-6-7', '十三'],
-    ['2017-6-8', '十四'],
-    ['2017-6-9', '十五'],
-    ['2017-6-10', '十六'],
-    ['2017-6-11', '十七'],
-    ['2017-6-12', '十八'],
-    ['2017-6-13', '十九'],
-    ['2017-6-14', '二十'],
-    ['2017-6-15', '廿一'],
-    ['2017-6-16', '廿二'],
-    ['2017-6-17', '廿三'],
-    ['2017-6-18', '廿四'],
-    ['2017-6-19', '廿五'],
-    ['2017-6-20', '廿六'],
-    ['2017-6-21', '廿七', '夏至'],
-    ['2017-6-22', '廿八'],
-    ['2017-6-23', '廿九'],
-    ['2017-6-24', '六月'],
-    ['2017-6-25', '初二'],
-    ['2017-6-26', '初三'],
-    ['2017-6-27', '初四'],
-    ['2017-6-28', '初五'],
-    ['2017-6-29', '初六'],
-    ['2017-6-30', '初七'],
-    ['2017-7-1', '初八'],
-    ['2017-7-2', '初九'],
-    ['2017-7-3', '初十'],
-    ['2017-7-4', '十一'],
-    ['2017-7-5', '十二'],
-    ['2017-7-6', '十三'],
-    ['2017-7-7', '十四', '小暑'],
-    ['2017-7-8', '十五'],
-    ['2017-7-9', '十六'],
-    ['2017-7-10', '十七'],
-    ['2017-7-11', '十八'],
-    ['2017-7-12', '十九'],
-    ['2017-7-13', '二十'],
-    ['2017-7-14', '廿一'],
-    ['2017-7-15', '廿二'],
-    ['2017-7-16', '廿三'],
-    ['2017-7-17', '廿四'],
-    ['2017-7-18', '廿五'],
-    ['2017-7-19', '廿六'],
-    ['2017-7-20', '廿七'],
-    ['2017-7-21', '廿八'],
-    ['2017-7-22', '廿九', '大暑'],
-    ['2017-7-23', '閏六',],
-    ['2017-7-24', '初二'],
-    ['2017-7-25', '初三'],
-    ['2017-7-26', '初四'],
-    ['2017-7-27', '初五'],
-    ['2017-7-28', '初六'],
-    ['2017-7-29', '初七'],
-    ['2017-7-30', '初八'],
-    ['2017-7-31', '初九'],
-    ['2017-8-1', '初十'],
-    ['2017-8-2', '十一'],
-    ['2017-8-3', '十二'],
-    ['2017-8-4', '十三'],
-    ['2017-8-5', '十四'],
-    ['2017-8-6', '十五'],
-    ['2017-8-7', '十六', '立秋'],
-    ['2017-8-8', '十七'],
-    ['2017-8-9', '十八'],
-    ['2017-8-10', '十九'],
-    ['2017-8-11', '二十'],
-    ['2017-8-12', '廿一'],
-    ['2017-8-13', '廿二'],
-    ['2017-8-14', '廿三'],
-    ['2017-8-15', '廿四'],
-    ['2017-8-16', '廿五'],
-    ['2017-8-17', '廿六'],
-    ['2017-8-18', '廿七'],
-    ['2017-8-19', '廿八'],
-    ['2017-8-20', '廿九'],
-    ['2017-8-21', '三十'],
-    ['2017-8-22', '七月'],
-    ['2017-8-23', '初二', '處暑'],
-    ['2017-8-24', '初三'],
-    ['2017-8-25', '初四'],
-    ['2017-8-26', '初五'],
-    ['2017-8-27', '初六'],
-    ['2017-8-28', '初七'],
-    ['2017-8-29', '初八'],
-    ['2017-8-30', '初九'],
-    ['2017-8-31', '初十'],
-    ['2017-9-1', '十一'],
-    ['2017-9-2', '十二'],
-    ['2017-9-3', '十三'],
-    ['2017-9-4', '十四'],
-    ['2017-9-5', '十五'],
-    ['2017-9-6', '十六'],
-    ['2017-9-7', '十七', '白露'],
-    ['2017-9-8', '十八'],
-    ['2017-9-9', '十九'],
-    ['2017-9-10', '二十'],
-    ['2017-9-11', '廿一'],
-    ['2017-9-12', '廿二'],
-    ['2017-9-13', '廿三'],
-    ['2017-9-14', '廿四'],
-    ['2017-9-15', '廿五'],
-    ['2017-9-16', '廿六'],
-    ['2017-9-17', '廿七'],
-    ['2017-9-18', '廿八'],
-    ['2017-9-19', '廿九'],
-    ['2017-9-20', '八月'],
-    ['2017-9-21', '初二'],
-    ['2017-9-22', '初三'],
-    ['2017-9-23', '初四', '秋分'],
-    ['2017-9-24', '初五'],
-    ['2017-9-25', '初六'],
-    ['2017-9-26', '初七'],
-    ['2017-9-27', '初八'],
-    ['2017-9-28', '初九'],
-    ['2017-9-29', '初十'],
-    ['2017-9-30', '十一'],
-    ['2017-10-1', '十二'],
-    ['2017-10-2', '十三'],
-    ['2017-10-3', '十四'],
-    ['2017-10-4', '十五'],
-    ['2017-10-5', '十六'],
-    ['2017-10-6', '十七'],
-    ['2017-10-7', '十八'],
-    ['2017-10-8', '十九', '寒露'],
-    ['2017-10-9', '二十'],
-    ['2017-10-10', '廿一'],
-    ['2017-10-11', '廿二'],
-    ['2017-10-12', '廿三'],
-    ['2017-10-13', '廿四'],
-    ['2017-10-14', '廿五'],
-    ['2017-10-15', '廿六'],
-    ['2017-10-16', '廿七'],
-    ['2017-10-17', '廿八'],
-    ['2017-10-18', '廿九'],
-    ['2017-10-19', '三十'],
-    ['2017-10-20', '九月'],
-    ['2017-10-21', '初二'],
-    ['2017-10-22', '初三'],
-    ['2017-10-23', '初四', '霜降'],
-    ['2017-10-24', '初五'],
-    ['2017-10-25', '初六'],
-    ['2017-10-26', '初七'],
-    ['2017-10-27', '初八'],
-    ['2017-10-28', '初九'],
-    ['2017-10-29', '初十'],
-    ['2017-10-30', '十一'],
-    ['2017-10-31', '十二'],
-    ['2017-11-1', '十三'],
-    ['2017-11-2', '十四'],
-    ['2017-11-3', '十五'],
-    ['2017-11-4', '十六'],
-    ['2017-11-5', '十七'],
-    ['2017-11-6', '十八'],
-    ['2017-11-7', '十九', '立冬'],
-    ['2017-11-8', '二十'],
-    ['2017-11-9', '廿一'],
-    ['2017-11-10', '廿二'],
-    ['2017-11-11', '廿三'],
-    ['2017-11-12', '廿四'],
-    ['2017-11-13', '廿五'],
-    ['2017-11-14', '廿六'],
-    ['2017-11-15', '廿七'],
-    ['2017-11-16', '廿八'],
-    ['2017-11-17', '廿九'],
-    ['2017-11-18', '十月'],
-    ['2017-11-19', '初二'],
-    ['2017-11-20', '初三'],
-    ['2017-11-21', '初四'],
-    ['2017-11-22', '初五', '小雪'],
-    ['2017-11-23', '初六'],
-    ['2017-11-24', '初七'],
-    ['2017-11-25', '初八'],
-    ['2017-11-26', '初九'],
-    ['2017-11-27', '初十'],
-    ['2017-11-28', '十一'],
-    ['2017-11-29', '十二'],
-    ['2017-11-30', '十三'],
-    ['2017-12-1', '十四'],
-    ['2017-12-2', '十五'],
-    ['2017-12-3', '十六'],
-    ['2017-12-4', '十七'],
-    ['2017-12-5', '十八'],
-    ['2017-12-6', '十九'],
-    ['2017-12-7', '二十', '大雪'],
-    ['2017-12-8', '廿一'],
-    ['2017-12-9', '廿二'],
-    ['2017-12-10', '廿三'],
-    ['2017-12-11', '廿四'],
-    ['2017-12-12', '廿五'],
-    ['2017-12-13', '廿六'],
-    ['2017-12-14', '廿七'],
-    ['2017-12-15', '廿八'],
-    ['2017-12-16', '廿九'],
-    ['2017-12-17', '三十'],
-    ['2017-12-18', '十一月'],
-    ['2017-12-19', '初二'],
-    ['2017-12-20', '初三'],
-    ['2017-12-21', '初四'],
-    ['2017-12-22', '初五', '冬至'],
-    ['2017-12-23', '初六'],
-    ['2017-12-24', '初七'],
-    ['2017-12-25', '初八'],
-    ['2017-12-26', '初九'],
-    ['2017-12-27', '初十'],
-    ['2017-12-28', '十一'],
-    ['2017-12-29', '十二'],
-    ['2017-12-30', '十三'],
-    ['2017-12-31', '十四']
+  ['2017-1-1', '初四'],
+  ['2017-1-2', '初五'],
+  ['2017-1-3', '初六'],
+  ['2017-1-4', '初七'],
+  ['2017-1-5', '初八', '小寒'],
+  ['2017-1-6', '初九'],
+  ['2017-1-7', '初十'],
+  ['2017-1-8', '十一'],
+  ['2017-1-9', '十二'],
+  ['2017-1-10', '十三'],
+  ['2017-1-11', '十四'],
+  ['2017-1-12', '十五'],
+  ['2017-1-13', '十六'],
+  ['2017-1-14', '十七'],
+  ['2017-1-15', '十八'],
+  ['2017-1-16', '十九'],
+  ['2017-1-17', '二十'],
+  ['2017-1-18', '廿一'],
+  ['2017-1-19', '廿二'],
+  ['2017-1-20', '廿三', '大寒'],
+  ['2017-1-21', '廿四'],
+  ['2017-1-22', '廿五'],
+  ['2017-1-23', '廿六'],
+  ['2017-1-24', '廿七'],
+  ['2017-1-25', '廿八'],
+  ['2017-1-26', '廿九'],
+  ['2017-1-27', '三十'],
+  ['2017-1-28', '正月'],
+  ['2017-1-29', '初二'],
+  ['2017-1-30', '初三'],
+  ['2017-1-31', '初四'],
+  ['2017-2-1', '初五'],
+  ['2017-2-2', '初六'],
+  ['2017-2-3', '初七', '立春'],
+  ['2017-2-4', '初八'],
+  ['2017-2-5', '初九'],
+  ['2017-2-6', '初十'],
+  ['2017-2-7', '十一'],
+  ['2017-2-8', '十二'],
+  ['2017-2-9', '十三'],
+  ['2017-2-10', '十四'],
+  ['2017-2-11', '十五'],
+  ['2017-2-12', '十六'],
+  ['2017-2-13', '十七'],
+  ['2017-2-14', '十八'],
+  ['2017-2-15', '十九'],
+  ['2017-2-16', '二十'],
+  ['2017-2-17', '廿一'],
+  ['2017-2-18', '廿二', '雨水'],
+  ['2017-2-19', '廿三'],
+  ['2017-2-20', '廿四'],
+  ['2017-2-21', '廿五'],
+  ['2017-2-22', '廿六'],
+  ['2017-2-23', '廿七'],
+  ['2017-2-24', '廿八'],
+  ['2017-2-25', '廿九'],
+  ['2017-2-26', '二月'],
+  ['2017-2-27', '初二'],
+  ['2017-2-28', '初三'],
+  ['2017-3-1', '初四'],
+  ['2017-3-2', '初五'],
+  ['2017-3-3', '初六'],
+  ['2017-3-4', '初七'],
+  ['2017-3-5', '初八', '驚蟄'],
+  ['2017-3-6', '初九'],
+  ['2017-3-7', '初十'],
+  ['2017-3-8', '十一'],
+  ['2017-3-9', '十二'],
+  ['2017-3-10', '十三'],
+  ['2017-3-11', '十四'],
+  ['2017-3-12', '十五'],
+  ['2017-3-13', '十六'],
+  ['2017-3-14', '十七'],
+  ['2017-3-15', '十八'],
+  ['2017-3-16', '十九'],
+  ['2017-3-17', '二十'],
+  ['2017-3-18', '廿一'],
+  ['2017-3-19', '廿二'],
+  ['2017-3-20', '廿三', '春分'],
+  ['2017-3-21', '廿四'],
+  ['2017-3-22', '廿五'],
+  ['2017-3-23', '廿六'],
+  ['2017-3-24', '廿七'],
+  ['2017-3-25', '廿八'],
+  ['2017-3-26', '廿九'],
+  ['2017-3-27', '三十'],
+  ['2017-3-28', '三月'],
+  ['2017-3-29', '初二'],
+  ['2017-3-30', '初三'],
+  ['2017-3-31', '初四'],
+  ['2017-4-1', '初五'],
+  ['2017-4-2', '初六'],
+  ['2017-4-3', '初七'],
+  ['2017-4-4', '初八', '清明'],
+  ['2017-4-5', '初九'],
+  ['2017-4-6', '初十'],
+  ['2017-4-7', '十一'],
+  ['2017-4-8', '十二'],
+  ['2017-4-9', '十三'],
+  ['2017-4-10', '十四'],
+  ['2017-4-11', '十五'],
+  ['2017-4-12', '十六'],
+  ['2017-4-13', '十七'],
+  ['2017-4-14', '十八'],
+  ['2017-4-15', '十九'],
+  ['2017-4-16', '二十'],
+  ['2017-4-17', '廿一'],
+  ['2017-4-18', '廿二'],
+  ['2017-4-19', '廿三'],
+  ['2017-4-20', '廿四', '穀雨'],
+  ['2017-4-21', '廿五'],
+  ['2017-4-22', '廿六'],
+  ['2017-4-23', '廿七'],
+  ['2017-4-24', '廿八'],
+  ['2017-4-25', '廿九'],
+  ['2017-4-26', '四月'],
+  ['2017-4-27', '初二'],
+  ['2017-4-28', '初三'],
+  ['2017-4-29', '初四'],
+  ['2017-4-30', '初五'],
+  ['2017-5-1', '初六'],
+  ['2017-5-2', '初七'],
+  ['2017-5-3', '初八'],
+  ['2017-5-4', '初九'],
+  ['2017-5-5', '初十', '立夏'],
+  ['2017-5-6', '十一'],
+  ['2017-5-7', '十二'],
+  ['2017-5-8', '十三'],
+  ['2017-5-9', '十四'],
+  ['2017-5-10', '十五'],
+  ['2017-5-11', '十六'],
+  ['2017-5-12', '十七'],
+  ['2017-5-13', '十八'],
+  ['2017-5-14', '十九'],
+  ['2017-5-15', '二十'],
+  ['2017-5-16', '廿一'],
+  ['2017-5-17', '廿二'],
+  ['2017-5-18', '廿三'],
+  ['2017-5-19', '廿四'],
+  ['2017-5-20', '廿五'],
+  ['2017-5-21', '廿六', '小滿'],
+  ['2017-5-22', '廿七'],
+  ['2017-5-23', '廿八'],
+  ['2017-5-24', '廿九'],
+  ['2017-5-25', '三十'],
+  ['2017-5-26', '五月'],
+  ['2017-5-27', '初二'],
+  ['2017-5-28', '初三'],
+  ['2017-5-29', '初四'],
+  ['2017-5-30', '初五'],
+  ['2017-5-31', '初六'],
+  ['2017-6-1', '初七'],
+  ['2017-6-2', '初八'],
+  ['2017-6-3', '初九'],
+  ['2017-6-4', '初十'],
+  ['2017-6-5', '十一', '芒種'],
+  ['2017-6-6', '十二'],
+  ['2017-6-7', '十三'],
+  ['2017-6-8', '十四'],
+  ['2017-6-9', '十五'],
+  ['2017-6-10', '十六'],
+  ['2017-6-11', '十七'],
+  ['2017-6-12', '十八'],
+  ['2017-6-13', '十九'],
+  ['2017-6-14', '二十'],
+  ['2017-6-15', '廿一'],
+  ['2017-6-16', '廿二'],
+  ['2017-6-17', '廿三'],
+  ['2017-6-18', '廿四'],
+  ['2017-6-19', '廿五'],
+  ['2017-6-20', '廿六'],
+  ['2017-6-21', '廿七', '夏至'],
+  ['2017-6-22', '廿八'],
+  ['2017-6-23', '廿九'],
+  ['2017-6-24', '六月'],
+  ['2017-6-25', '初二'],
+  ['2017-6-26', '初三'],
+  ['2017-6-27', '初四'],
+  ['2017-6-28', '初五'],
+  ['2017-6-29', '初六'],
+  ['2017-6-30', '初七'],
+  ['2017-7-1', '初八'],
+  ['2017-7-2', '初九'],
+  ['2017-7-3', '初十'],
+  ['2017-7-4', '十一'],
+  ['2017-7-5', '十二'],
+  ['2017-7-6', '十三'],
+  ['2017-7-7', '十四', '小暑'],
+  ['2017-7-8', '十五'],
+  ['2017-7-9', '十六'],
+  ['2017-7-10', '十七'],
+  ['2017-7-11', '十八'],
+  ['2017-7-12', '十九'],
+  ['2017-7-13', '二十'],
+  ['2017-7-14', '廿一'],
+  ['2017-7-15', '廿二'],
+  ['2017-7-16', '廿三'],
+  ['2017-7-17', '廿四'],
+  ['2017-7-18', '廿五'],
+  ['2017-7-19', '廿六'],
+  ['2017-7-20', '廿七'],
+  ['2017-7-21', '廿八'],
+  ['2017-7-22', '廿九', '大暑'],
+  ['2017-7-23', '閏六'],
+  ['2017-7-24', '初二'],
+  ['2017-7-25', '初三'],
+  ['2017-7-26', '初四'],
+  ['2017-7-27', '初五'],
+  ['2017-7-28', '初六'],
+  ['2017-7-29', '初七'],
+  ['2017-7-30', '初八'],
+  ['2017-7-31', '初九'],
+  ['2017-8-1', '初十'],
+  ['2017-8-2', '十一'],
+  ['2017-8-3', '十二'],
+  ['2017-8-4', '十三'],
+  ['2017-8-5', '十四'],
+  ['2017-8-6', '十五'],
+  ['2017-8-7', '十六', '立秋'],
+  ['2017-8-8', '十七'],
+  ['2017-8-9', '十八'],
+  ['2017-8-10', '十九'],
+  ['2017-8-11', '二十'],
+  ['2017-8-12', '廿一'],
+  ['2017-8-13', '廿二'],
+  ['2017-8-14', '廿三'],
+  ['2017-8-15', '廿四'],
+  ['2017-8-16', '廿五'],
+  ['2017-8-17', '廿六'],
+  ['2017-8-18', '廿七'],
+  ['2017-8-19', '廿八'],
+  ['2017-8-20', '廿九'],
+  ['2017-8-21', '三十'],
+  ['2017-8-22', '七月'],
+  ['2017-8-23', '初二', '處暑'],
+  ['2017-8-24', '初三'],
+  ['2017-8-25', '初四'],
+  ['2017-8-26', '初五'],
+  ['2017-8-27', '初六'],
+  ['2017-8-28', '初七'],
+  ['2017-8-29', '初八'],
+  ['2017-8-30', '初九'],
+  ['2017-8-31', '初十'],
+  ['2017-9-1', '十一'],
+  ['2017-9-2', '十二'],
+  ['2017-9-3', '十三'],
+  ['2017-9-4', '十四'],
+  ['2017-9-5', '十五'],
+  ['2017-9-6', '十六'],
+  ['2017-9-7', '十七', '白露'],
+  ['2017-9-8', '十八'],
+  ['2017-9-9', '十九'],
+  ['2017-9-10', '二十'],
+  ['2017-9-11', '廿一'],
+  ['2017-9-12', '廿二'],
+  ['2017-9-13', '廿三'],
+  ['2017-9-14', '廿四'],
+  ['2017-9-15', '廿五'],
+  ['2017-9-16', '廿六'],
+  ['2017-9-17', '廿七'],
+  ['2017-9-18', '廿八'],
+  ['2017-9-19', '廿九'],
+  ['2017-9-20', '八月'],
+  ['2017-9-21', '初二'],
+  ['2017-9-22', '初三'],
+  ['2017-9-23', '初四', '秋分'],
+  ['2017-9-24', '初五'],
+  ['2017-9-25', '初六'],
+  ['2017-9-26', '初七'],
+  ['2017-9-27', '初八'],
+  ['2017-9-28', '初九'],
+  ['2017-9-29', '初十'],
+  ['2017-9-30', '十一'],
+  ['2017-10-1', '十二'],
+  ['2017-10-2', '十三'],
+  ['2017-10-3', '十四'],
+  ['2017-10-4', '十五'],
+  ['2017-10-5', '十六'],
+  ['2017-10-6', '十七'],
+  ['2017-10-7', '十八'],
+  ['2017-10-8', '十九', '寒露'],
+  ['2017-10-9', '二十'],
+  ['2017-10-10', '廿一'],
+  ['2017-10-11', '廿二'],
+  ['2017-10-12', '廿三'],
+  ['2017-10-13', '廿四'],
+  ['2017-10-14', '廿五'],
+  ['2017-10-15', '廿六'],
+  ['2017-10-16', '廿七'],
+  ['2017-10-17', '廿八'],
+  ['2017-10-18', '廿九'],
+  ['2017-10-19', '三十'],
+  ['2017-10-20', '九月'],
+  ['2017-10-21', '初二'],
+  ['2017-10-22', '初三'],
+  ['2017-10-23', '初四', '霜降'],
+  ['2017-10-24', '初五'],
+  ['2017-10-25', '初六'],
+  ['2017-10-26', '初七'],
+  ['2017-10-27', '初八'],
+  ['2017-10-28', '初九'],
+  ['2017-10-29', '初十'],
+  ['2017-10-30', '十一'],
+  ['2017-10-31', '十二'],
+  ['2017-11-1', '十三'],
+  ['2017-11-2', '十四'],
+  ['2017-11-3', '十五'],
+  ['2017-11-4', '十六'],
+  ['2017-11-5', '十七'],
+  ['2017-11-6', '十八'],
+  ['2017-11-7', '十九', '立冬'],
+  ['2017-11-8', '二十'],
+  ['2017-11-9', '廿一'],
+  ['2017-11-10', '廿二'],
+  ['2017-11-11', '廿三'],
+  ['2017-11-12', '廿四'],
+  ['2017-11-13', '廿五'],
+  ['2017-11-14', '廿六'],
+  ['2017-11-15', '廿七'],
+  ['2017-11-16', '廿八'],
+  ['2017-11-17', '廿九'],
+  ['2017-11-18', '十月'],
+  ['2017-11-19', '初二'],
+  ['2017-11-20', '初三'],
+  ['2017-11-21', '初四'],
+  ['2017-11-22', '初五', '小雪'],
+  ['2017-11-23', '初六'],
+  ['2017-11-24', '初七'],
+  ['2017-11-25', '初八'],
+  ['2017-11-26', '初九'],
+  ['2017-11-27', '初十'],
+  ['2017-11-28', '十一'],
+  ['2017-11-29', '十二'],
+  ['2017-11-30', '十三'],
+  ['2017-12-1', '十四'],
+  ['2017-12-2', '十五'],
+  ['2017-12-3', '十六'],
+  ['2017-12-4', '十七'],
+  ['2017-12-5', '十八'],
+  ['2017-12-6', '十九'],
+  ['2017-12-7', '二十', '大雪'],
+  ['2017-12-8', '廿一'],
+  ['2017-12-9', '廿二'],
+  ['2017-12-10', '廿三'],
+  ['2017-12-11', '廿四'],
+  ['2017-12-12', '廿五'],
+  ['2017-12-13', '廿六'],
+  ['2017-12-14', '廿七'],
+  ['2017-12-15', '廿八'],
+  ['2017-12-16', '廿九'],
+  ['2017-12-17', '三十'],
+  ['2017-12-18', '十一月'],
+  ['2017-12-19', '初二'],
+  ['2017-12-20', '初三'],
+  ['2017-12-21', '初四'],
+  ['2017-12-22', '初五', '冬至'],
+  ['2017-12-23', '初六'],
+  ['2017-12-24', '初七'],
+  ['2017-12-25', '初八'],
+  ['2017-12-26', '初九'],
+  ['2017-12-27', '初十'],
+  ['2017-12-28', '十一'],
+  ['2017-12-29', '十二'],
+  ['2017-12-30', '十三'],
+  ['2017-12-31', '十四']
 ];
 
 let heatmapData = [];
 let lunarData = [];
 for (let i = 0; i < dateList.length; i++) {
-    heatmapData.push([
-        dateList[i][0],
-        Math.random() * 300
-    ]);
-    lunarData.push([
-        dateList[i][0],
-        1,
-        dateList[i][1],
-        dateList[i][2]
-    ]);
+  heatmapData.push([dateList[i][0], Math.random() * 300]);
+  lunarData.push([dateList[i][0], 1, dateList[i][1], dateList[i][2]]);
 }
 
-
 option = {
-    tooltip: {
-        formatter: function (params) {
-            return '降雨量: ' + params.value[1].toFixed(2);
-        }
-    },
+  tooltip: {
+    formatter: function (params: any) {
+      return '降雨量: ' + params.value[1].toFixed(2);
+    }
+  },
 
-    visualMap: {
-        show: false,
-        min: 0,
-        max: 300,
-        calculable: true,
-        seriesIndex: [2],
-        orient: 'horizontal',
-        left: 'center',
-        bottom: 20,
-        inRange: {
-            color: ['#e0ffff', '#006edd'],
-            opacity: 0.3
-        },
-        controller: {
-            inRange: {
-                opacity: 0.5
-            }
-        }
+  visualMap: {
+    show: false,
+    min: 0,
+    max: 300,
+    calculable: true,
+    seriesIndex: [2],
+    orient: 'horizontal',
+    left: 'center',
+    bottom: 20,
+    inRange: {
+      color: ['#e0ffff', '#006edd'],
+      opacity: 0.3
     },
+    controller: {
+      inRange: {
+        opacity: 0.5
+      }
+    }
+  },
 
-    calendar: [{
-        left: 'center',
-        top: 'middle',
-        cellSize: [70, 70],
-        yearLabel: {show: false},
-        orient: 'vertical',
-        dayLabel: {
-            firstDay: 1,
-            nameMap: 'cn'
-        },
-        monthLabel: {
-            show: false
-        },
-        range: '2017-03'
-    }],
+  calendar: [
+    {
+      left: 'center',
+      top: 'middle',
+      cellSize: [70, 70],
+      yearLabel: { show: false },
+      orient: 'vertical',
+      dayLabel: {
+        firstDay: 1,
+        nameMap: 'cn'
+      },
+      monthLabel: {
+        show: false
+      },
+      range: '2017-03'
+    }
+  ],
 
-    series: [{
-        type: 'scatter',
-        coordinateSystem: 'calendar',
-        symbolSize: 1,
-        label: {
-            show: true,
-            formatter: function (params) {
-                var d = echarts.number.parseDate(params.value[0]);
-                return d.getDate() + '\n\n' + params.value[2] + '\n\n';
-            },
-            color: '#000'
+  series: [
+    {
+      type: 'scatter',
+      coordinateSystem: 'calendar',
+      symbolSize: 1,
+      label: {
+        show: true,
+        formatter: function (params: any) {
+          var d = echarts.number.parseDate(params.value[0]);
+          return d.getDate() + '\n\n' + params.value[2] + '\n\n';
         },
-        data: lunarData
-    }, {
-        type: 'scatter',
-        coordinateSystem: 'calendar',
-        symbolSize: 1,
-        label: {
-            show: true,
-            formatter: function (params) {
-                return '\n\n\n' + (params.value[3] || '');
-            },
-            fontSize: 14,
-            fontWeight: 700,
-            color: '#a00'
+        color: '#000'
+      },
+      data: lunarData
+    },
+    {
+      type: 'scatter',
+      coordinateSystem: 'calendar',
+      symbolSize: 1,
+      label: {
+        show: true,
+        formatter: function (params: any) {
+          return '\n\n\n' + (params.value[3] || '');
         },
-        data: lunarData
-    }, {
-        name: '降雨量',
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        data: heatmapData
-    }]
+        fontSize: 14,
+        fontWeight: 700,
+        color: '#a00'
+      },
+      data: lunarData
+    },
+    {
+      name: '降雨量',
+      type: 'heatmap',
+      coordinateSystem: 'calendar',
+      data: heatmapData
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/calendar-pie.ts b/public/examples/ts/calendar-pie.ts
index fef76b3..02458bb 100644
--- a/public/examples/ts/calendar-pie.ts
+++ b/public/examples/ts/calendar-pie.ts
@@ -11,110 +11,116 @@ const pieRadius = 30;
 type DataItem = [string, number];
 
 function getVirtulData() {
-    let date = +echarts.number.parseDate('2017-02-01');
-    let end = +echarts.number.parseDate('2017-03-01');
-    let dayTime = 3600 * 24 * 1000;
-    let data: DataItem[] = [];
-    for (let time = date; time < end; time += dayTime) {
-        data.push([
-            echarts.format.formatTime('yyyy-MM-dd', time),
-            Math.floor(Math.random() * 10000)
-        ]);
-    }
-    return data;
+  let date = +echarts.number.parseDate('2017-02-01');
+  let end = +echarts.number.parseDate('2017-03-01');
+  let dayTime = 3600 * 24 * 1000;
+  let data: DataItem[] = [];
+  for (let time = date; time < end; time += dayTime) {
+    data.push([
+      echarts.format.formatTime('yyyy-MM-dd', time),
+      Math.floor(Math.random() * 10000)
+    ]);
+  }
+  return data;
 }
 
-function getPieSeries(scatterData: DataItem[], chart: echarts.ECharts) {
-    return scatterData.map(function (item, index) {
-        var center = chart.convertToPixel('calendar', item);
-        return {
-            id: index + 'pie',
-            type: 'pie',
-            center: center,
-            label: {
-                normal: {
-                    formatter: '{c}',
-                    position: 'inside'
-                }
-            },
-            radius: pieRadius,
-            data: [
-                {name: '工作', value: Math.round(Math.random() * 24)},
-                {name: '娱乐', value: Math.round(Math.random() * 24)},
-                {name: '睡觉', value: Math.round(Math.random() * 24)}
-            ]
-        };
-    });
+function getPieSeries(
+  scatterData: DataItem[],
+  chart: echarts.ECharts
+): echarts.PieSeriesOption[] {
+  return scatterData.map(function (item, index) {
+    var center = chart.convertToPixel('calendar', item);
+    return {
+      id: index + 'pie',
+      type: 'pie',
+      center: center,
+      label: {
+        formatter: '{c}',
+        position: 'inside'
+      },
+      radius: pieRadius,
+      data: [
+        { name: '工作', value: Math.round(Math.random() * 24) },
+        { name: '娱乐', value: Math.round(Math.random() * 24) },
+        { name: '睡觉', value: Math.round(Math.random() * 24) }
+      ]
+    };
+  });
 }
 
-function getPieSeriesUpdate(scatterData: DataItem[], chart: echarts.ECharts) {
-    return scatterData.map(function (item, index) {
-        var center = chart.convertToPixel('calendar', item);
-        return {
-            id: index + 'pie',
-            center: center
-        };
-    });
+function getPieSeriesUpdate(
+  scatterData: DataItem[],
+  chart: echarts.ECharts
+): echarts.PieSeriesOption[] {
+  return scatterData.map(function (item, index) {
+    var center = chart.convertToPixel('calendar', item);
+    return {
+      id: index + 'pie',
+      center: center
+    };
+  });
 }
 
 var scatterData = getVirtulData();
 
 option = {
-    tooltip : {},
-    legend: {
-        data: ['Work', 'Entertainment', 'Sleep'],
-        bottom: 20
+  tooltip: {},
+  legend: {
+    data: ['Work', 'Entertainment', 'Sleep'],
+    bottom: 20
+  },
+  calendar: {
+    top: 'middle',
+    left: 'center',
+    orient: 'vertical',
+    cellSize: cellSize,
+    yearLabel: {
+      show: false,
+      fontSize: 30
     },
-    calendar: {
-        top: 'middle',
-        left: 'center',
-        orient: 'vertical',
-        cellSize: cellSize,
-        yearLabel: {
-            show: false,
-            fontSize: 30
-        },
-        dayLabel: {
-            margin: 20,
-            firstDay: 1,
-            nameMap: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-        },
-        monthLabel: {
-            show: false
-        },
-        range: ['2017-02']
+    dayLabel: {
+      margin: 20,
+      firstDay: 1,
+      nameMap: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+    },
+    monthLabel: {
+      show: false
     },
-    series: [{
-        id: 'label',
-        type: 'scatter',
-        coordinateSystem: 'calendar',
-        symbolSize: 1,
-        label: {
-            show: true,
-            formatter: function (params) {
-                return echarts.format.formatTime('dd', params.value[0]);
-            },
-            offset: [-cellSize[0] / 2 + 10, -cellSize[1] / 2 + 10],
-            fontSize: 14
+    range: ['2017-02']
+  },
+  series: [
+    {
+      id: 'label',
+      type: 'scatter',
+      coordinateSystem: 'calendar',
+      symbolSize: 1,
+      label: {
+        show: true,
+        formatter: function (params: any) {
+          return echarts.format.formatTime('dd', params.value[0]);
         },
-        data: scatterData
-    }]
+        offset: [-cellSize[0] / 2 + 10, -cellSize[1] / 2 + 10],
+        fontSize: 14
+      },
+      data: scatterData
+    }
+  ]
 };
 
 let pieInitialized: boolean;
 setTimeout(function () {
-    pieInitialized = true;
-    myChart.setOption<echarts.EChartsOption>({
-        series: getPieSeries(scatterData, myChart)
-    });
+  pieInitialized = true;
+  myChart.setOption<echarts.EChartsOption>({
+    series: getPieSeries(scatterData, myChart)
+  });
 }, 10);
 
 app.onresize = function () {
-    if (pieInitialized) {
-        myChart.setOption<echarts.EChartsOption>({
-            series: getPieSeriesUpdate(scatterData, myChart)
-        });
-    }
+  if (pieInitialized) {
+    myChart.setOption<echarts.EChartsOption>({
+      series: getPieSeriesUpdate(scatterData, myChart)
+    });
+  }
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/calendar-simple.ts b/public/examples/ts/calendar-simple.ts
index 607da8c..d2ae4aa 100644
--- a/public/examples/ts/calendar-simple.ts
+++ b/public/examples/ts/calendar-simple.ts
@@ -6,34 +6,34 @@ difficulty: 0
 */
 
 function getVirtulData(year: string) {
-    year = year || '2017';
-    var date = +echarts.number.parseDate(year + '-01-01');
-    var end = +echarts.number.parseDate(year + '-12-31');
-    var dayTime = 3600 * 24 * 1000;
-    var data = [];
-    for (var time = date; time <= end; time += dayTime) {
-        data.push([
-            echarts.format.formatTime('yyyy-MM-dd', time),
-            Math.floor(Math.random() * 10000)
-        ]);
-    }
-    return data;
+  year = year || '2017';
+  var date = +echarts.number.parseDate(year + '-01-01');
+  var end = +echarts.number.parseDate(year + '-12-31');
+  var dayTime = 3600 * 24 * 1000;
+  var data = [];
+  for (var time = date; time <= end; time += dayTime) {
+    data.push([
+      echarts.format.formatTime('yyyy-MM-dd', time),
+      Math.floor(Math.random() * 10000)
+    ]);
+  }
+  return data;
 }
 
 option = {
-    visualMap: {
-        show: false,
-        min: 0,
-        max: 10000
-    },
-    calendar: {
-        range: '2017'
-    },
-    series: {
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        data: getVirtulData('2017')
-    }
+  visualMap: {
+    show: false,
+    min: 0,
+    max: 10000
+  },
+  calendar: {
+    range: '2017'
+  },
+  series: {
+    type: 'heatmap',
+    coordinateSystem: 'calendar',
+    data: getVirtulData('2017')
+  }
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/calendar-vertical.ts b/public/examples/ts/calendar-vertical.ts
index 212c3d0..39c0cb2 100644
--- a/public/examples/ts/calendar-vertical.ts
+++ b/public/examples/ts/calendar-vertical.ts
@@ -7,74 +7,79 @@ difficulty: 1
 */
 
 function getVirtulData(year: string) {
-    year = year || '2017';
-    var date = +echarts.number.parseDate(year + '-01-01');
-    var end = +echarts.number.parseDate((+year + 1) + '-01-01');
-    var dayTime = 3600 * 24 * 1000;
-    var data = [];
-    for (var time = date; time < end; time += dayTime) {
-        data.push([
-            echarts.format.formatTime('yyyy-MM-dd', time),
-            Math.floor(Math.random() * 1000)
-        ]);
-    }
-    return data;
+  year = year || '2017';
+  var date = +echarts.number.parseDate(year + '-01-01');
+  var end = +echarts.number.parseDate(+year + 1 + '-01-01');
+  var dayTime = 3600 * 24 * 1000;
+  var data = [];
+  for (var time = date; time < end; time += dayTime) {
+    data.push([
+      echarts.format.formatTime('yyyy-MM-dd', time),
+      Math.floor(Math.random() * 1000)
+    ]);
+  }
+  return data;
 }
 
-
 option = {
-    tooltip: {
-        position: 'top',
-        formatter: function (p) {
-            var format = echarts.format.formatTime('yyyy-MM-dd', p.data[0]);
-            return format + ': ' + p.data[1];
-        }
+  tooltip: {
+    position: 'top',
+    formatter: function (p: any) {
+      var format = echarts.format.formatTime('yyyy-MM-dd', p.data[0]);
+      return format + ': ' + p.data[1];
+    }
+  },
+  visualMap: {
+    min: 0,
+    max: 1000,
+    calculable: true,
+    orient: 'vertical',
+    left: '670',
+    top: 'center'
+  },
+
+  calendar: [
+    {
+      orient: 'vertical',
+      range: '2015'
     },
-    visualMap: {
-        min: 0,
-        max: 1000,
-        calculable: true,
-        orient: 'vertical',
-        left: '670',
-        top: 'center'
+    {
+      left: 300,
+      orient: 'vertical',
+      range: '2016'
     },
+    {
+      left: 520,
+      cellSize: [20, 'auto'],
+      bottom: 10,
+      orient: 'vertical',
+      range: '2017',
+      dayLabel: {
+        margin: 5
+      }
+    }
+  ],
 
-    calendar: [{
-        orient: 'vertical',
-        range: '2015'
+  series: [
+    {
+      type: 'heatmap',
+      coordinateSystem: 'calendar',
+      calendarIndex: 0,
+      data: getVirtulData('2015')
     },
     {
-        left: 300,
-        orient: 'vertical',
-        range: '2016'
+      type: 'heatmap',
+      coordinateSystem: 'calendar',
+      calendarIndex: 1,
+      data: getVirtulData('2016')
     },
     {
-        left: 520,
-        cellSize: [20, 'auto'],
-        bottom: 10,
-        orient: 'vertical',
-        range: '2017',
-        dayLabel: {
-            margin: 5
-        }
-    }],
-
-    series: [{
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        calendarIndex: 0,
-        data: getVirtulData('2015')
-    }, {
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        calendarIndex: 1,
-        data: getVirtulData('2016')
-    }, {
-        type: 'heatmap',
-        coordinateSystem: 'calendar',
-        calendarIndex: 2,
-        data: getVirtulData('2017')
-    }]
+      type: 'heatmap',
+      coordinateSystem: 'calendar',
+      calendarIndex: 2,
+      data: getVirtulData('2017')
+    }
+  ]
 };
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/candlestick-brush.ts b/public/examples/ts/candlestick-brush.ts
index d5ce863..ce07c41 100644
--- a/public/examples/ts/candlestick-brush.ts
+++ b/public/examples/ts/candlestick-brush.ts
@@ -7,264 +7,270 @@ titleCN: K 线图刷选
 const upColor = '#00da3c';
 const downColor = '#ec0000';
 
-
 function splitData(rawData: number[][]) {
-    let categoryData = [];
-    let values = [];
-    let volumes = [];
-    for (let i = 0; i < rawData.length; i++) {
-        categoryData.push(rawData[i].splice(0, 1)[0]);
-        values.push(rawData[i]);
-        volumes.push([i, rawData[i][4], rawData[i][0] > rawData[i][1] ? 1 : -1]);
-    }
+  let categoryData = [];
+  let values = [];
+  let volumes = [];
+  for (let i = 0; i < rawData.length; i++) {
+    categoryData.push(rawData[i].splice(0, 1)[0]);
+    values.push(rawData[i]);
+    volumes.push([i, rawData[i][4], rawData[i][0] > rawData[i][1] ? 1 : -1]);
+  }
 
-    return {
-        categoryData: categoryData,
-        values: values,
-        volumes: volumes
-    };
+  return {
+    categoryData: categoryData,
+    values: values,
+    volumes: volumes
+  };
 }
 
-function calculateMA(dayCount: number, data: { values: number[][]}) {
-    var result = [];
-    for (var i = 0, len = data.values.length; i < len; i++) {
-        if (i < dayCount) {
-            result.push('-');
-            continue;
-        }
-        var sum = 0;
-        for (var j = 0; j < dayCount; j++) {
-            sum += data.values[i - j][1];
-        }
-        result.push(+(sum / dayCount).toFixed(3));
+function calculateMA(dayCount: number, data: { values: number[][] }) {
+  var result = [];
+  for (var i = 0, len = data.values.length; i < len; i++) {
+    if (i < dayCount) {
+      result.push('-');
+      continue;
+    }
+    var sum = 0;
+    for (var j = 0; j < dayCount; j++) {
+      sum += data.values[i - j][1];
     }
-    return result;
+    result.push(+(sum / dayCount).toFixed(3));
+  }
+  return result;
 }
 
 $.get(ROOT_PATH + '/data/asset/data/stock-DJI.json', function (rawData) {
+  var data = splitData(rawData);
 
-    var data = splitData(rawData);
-
-    myChart.setOption<echarts.EChartsOption>(option = {
-        animation: false,
-        legend: {
-            bottom: 10,
-            left: 'center',
-            data: ['Dow-Jones index', 'MA5', 'MA10', 'MA20', 'MA30']
+  myChart.setOption<echarts.EChartsOption>(
+    (option = {
+      animation: false,
+      legend: {
+        bottom: 10,
+        left: 'center',
+        data: ['Dow-Jones index', 'MA5', 'MA10', 'MA20', 'MA30']
+      },
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: {
+          type: 'cross'
         },
-        tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'cross'
-            },
-            borderWidth: 1,
-            borderColor: '#ccc',
-            padding: 10,
-            textStyle: {
-                color: '#000'
-            },
-            position: function (pos, params, el, elRect, size) {
-                const obj: Record<string, number> = {
-                    top: 10
-                };
-                obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30;
-                return obj;
-            }
-            // extraCssText: 'width: 170px'
+        borderWidth: 1,
+        borderColor: '#ccc',
+        padding: 10,
+        textStyle: {
+          color: '#000'
         },
-        axisPointer: {
-            link: [{
-                xAxisIndex: 'all'
-            }],
-            label: {
-                backgroundColor: '#777'
-            }
+        position: function (pos, params, el, elRect, size) {
+          const obj: Record<string, number> = {
+            top: 10
+          };
+          obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30;
+          return obj;
+        }
+        // extraCssText: 'width: 170px'
+      },
+      axisPointer: {
+        link: [
+          {
+            xAxisIndex: 'all'
+          }
+        ],
+        label: {
+          backgroundColor: '#777'
+        }
+      },
+      toolbox: {
+        feature: {
+          dataZoom: {
+            yAxisIndex: false
+          },
+          brush: {
+            type: ['lineX', 'clear']
+          }
+        }
+      },
+      brush: {
+        xAxisIndex: 'all',
+        brushLink: 'all',
+        outOfBrush: {
+          colorAlpha: 0.1
+        }
+      },
+      visualMap: {
+        show: false,
+        seriesIndex: 5,
+        dimension: 2,
+        pieces: [
+          {
+            value: 1,
+            color: downColor
+          },
+          {
+            value: -1,
+            color: upColor
+          }
+        ]
+      },
+      grid: [
+        {
+          left: '10%',
+          right: '8%',
+          height: '50%'
         },
-        toolbox: {
-            feature: {
-                dataZoom: {
-                    yAxisIndex: false
-                },
-                brush: {
-                    type: ['lineX', 'clear']
-                }
-            }
+        {
+          left: '10%',
+          right: '8%',
+          top: '63%',
+          height: '16%'
+        }
+      ],
+      xAxis: [
+        {
+          type: 'category',
+          data: data.categoryData,
+          scale: true,
+          boundaryGap: false,
+          axisLine: { onZero: false },
+          splitLine: { show: false },
+          splitNumber: 20,
+          min: 'dataMin',
+          max: 'dataMax',
+          axisPointer: {
+            z: 100
+          }
         },
-        brush: {
-            xAxisIndex: 'all',
-            brushLink: 'all',
-            outOfBrush: {
-                colorAlpha: 0.1
-            }
+        {
+          type: 'category',
+          gridIndex: 1,
+          data: data.categoryData,
+          scale: true,
+          boundaryGap: false,
+          axisLine: { onZero: false },
+          axisTick: { show: false },
+          splitLine: { show: false },
+          axisLabel: { show: false },
+          splitNumber: 20,
+          min: 'dataMin',
+          max: 'dataMax'
+        }
+      ],
+      yAxis: [
+        {
+          scale: true,
+          splitArea: {
+            show: true
+          }
         },
-        visualMap: {
-            show: false,
-            seriesIndex: 5,
-            dimension: 2,
-            pieces: [{
-                value: 1,
-                color: downColor
-            }, {
-                value: -1,
-                color: upColor
-            }]
+        {
+          scale: true,
+          gridIndex: 1,
+          splitNumber: 2,
+          axisLabel: { show: false },
+          axisLine: { show: false },
+          axisTick: { show: false },
+          splitLine: { show: false }
+        }
+      ],
+      dataZoom: [
+        {
+          type: 'inside',
+          xAxisIndex: [0, 1],
+          start: 98,
+          end: 100
         },
-        grid: [
-            {
-                left: '10%',
-                right: '8%',
-                height: '50%'
-            },
-            {
-                left: '10%',
-                right: '8%',
-                top: '63%',
-                height: '16%'
-            }
-        ],
-        xAxis: [
-            {
-                type: 'category',
-                data: data.categoryData,
-                scale: true,
-                boundaryGap: false,
-                axisLine: {onZero: false},
-                splitLine: {show: false},
-                splitNumber: 20,
-                min: 'dataMin',
-                max: 'dataMax',
-                axisPointer: {
-                    z: 100
-                }
-            },
-            {
-                type: 'category',
-                gridIndex: 1,
-                data: data.categoryData,
-                scale: true,
-                boundaryGap: false,
-                axisLine: {onZero: false},
-                axisTick: {show: false},
-                splitLine: {show: false},
-                axisLabel: {show: false},
-                splitNumber: 20,
-                min: 'dataMin',
-                max: 'dataMax'
-            }
-        ],
-        yAxis: [
-            {
-                scale: true,
-                splitArea: {
-                    show: true
-                }
-            },
-            {
-                scale: true,
-                gridIndex: 1,
-                splitNumber: 2,
-                axisLabel: {show: false},
-                axisLine: {show: false},
-                axisTick: {show: false},
-                splitLine: {show: false}
-            }
-        ],
-        dataZoom: [
-            {
-                type: 'inside',
-                xAxisIndex: [0, 1],
-                start: 98,
-                end: 100
-            },
-            {
-                show: true,
-                xAxisIndex: [0, 1],
-                type: 'slider',
-                top: '85%',
-                start: 98,
-                end: 100
-            }
-        ],
-        series: [
-            {
-                name: 'Dow-Jones index',
-                type: 'candlestick',
-                data: data.values,
-                itemStyle: {
-                    color: upColor,
-                    color0: downColor,
-                    borderColor: undefined,
-                    borderColor0: undefined
-                },
-                tooltip: {
-                    formatter: function (param) {
-                        param = param[0];
-                        return [
-                            'Date: ' + param.name + '<hr size=1 style="margin: 3px 0">',
-                            'Open: ' + param.data[0] + '<br/>',
-                            'Close: ' + param.data[1] + '<br/>',
-                            'Lowest: ' + param.data[2] + '<br/>',
-                            'Highest: ' + param.data[3] + '<br/>'
-                        ].join('');
-                    }
-                }
-            },
-            {
-                name: 'MA5',
-                type: 'line',
-                data: calculateMA(5, data),
-                smooth: true,
-                lineStyle: {
-                    opacity: 0.5
-                }
-            },
-            {
-                name: 'MA10',
-                type: 'line',
-                data: calculateMA(10, data),
-                smooth: true,
-                lineStyle: {
-                    opacity: 0.5
-                }
-            },
-            {
-                name: 'MA20',
-                type: 'line',
-                data: calculateMA(20, data),
-                smooth: true,
-                lineStyle: {
-                    opacity: 0.5
-                }
-            },
-            {
-                name: 'MA30',
-                type: 'line',
-                data: calculateMA(30, data),
-                smooth: true,
-                lineStyle: {
-                    opacity: 0.5
-                }
-            },
-            {
-                name: 'Volume',
-                type: 'bar',
-                xAxisIndex: 1,
-                yAxisIndex: 1,
-                data: data.volumes
+        {
+          show: true,
+          xAxisIndex: [0, 1],
+          type: 'slider',
+          top: '85%',
+          start: 98,
+          end: 100
+        }
+      ],
+      series: [
+        {
+          name: 'Dow-Jones index',
+          type: 'candlestick',
+          data: data.values,
+          itemStyle: {
+            color: upColor,
+            color0: downColor,
+            borderColor: undefined,
+            borderColor0: undefined
+          },
+          tooltip: {
+            formatter: function (param: any) {
+              param = param[0];
+              return [
+                'Date: ' + param.name + '<hr size=1 style="margin: 3px 0">',
+                'Open: ' + param.data[0] + '<br/>',
+                'Close: ' + param.data[1] + '<br/>',
+                'Lowest: ' + param.data[2] + '<br/>',
+                'Highest: ' + param.data[3] + '<br/>'
+              ].join('');
             }
-        ]
-    }, true);
+          }
+        },
+        {
+          name: 'MA5',
+          type: 'line',
+          data: calculateMA(5, data),
+          smooth: true,
+          lineStyle: {
+            opacity: 0.5
+          }
+        },
+        {
+          name: 'MA10',
+          type: 'line',
+          data: calculateMA(10, data),
+          smooth: true,
+          lineStyle: {
+            opacity: 0.5
+          }
+        },
+        {
+          name: 'MA20',
+          type: 'line',
+          data: calculateMA(20, data),
+          smooth: true,
+          lineStyle: {
+            opacity: 0.5
+          }
+        },
+        {
+          name: 'MA30',
+          type: 'line',
+          data: calculateMA(30, data),
+          smooth: true,
+          lineStyle: {
+            opacity: 0.5
+          }
+        },
+        {
+          name: 'Volume',
+          type: 'bar',
+          xAxisIndex: 1,
+          yAxisIndex: 1,
+          data: data.volumes
+        }
+      ]
+    }),
+    true
+  );
 
-    myChart.dispatchAction({
-        type: 'brush',
-        areas: [
-            {
-                brushType: 'lineX',
-                coordRange: ['2016-06-02', '2016-06-20'],
-                xAxisIndex: 0
-            }
-        ]
-    });
+  myChart.dispatchAction({
+    type: 'brush',
+    areas: [
+      {
+        brushType: 'lineX',
+        coordRange: ['2016-06-02', '2016-06-20'],
+        xAxisIndex: 0
+      }
+    ]
+  });
 });
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/candlestick-large.ts b/public/examples/ts/candlestick-large.ts
index b86038e..c36bd0f 100644
--- a/public/examples/ts/candlestick-large.ts
+++ b/public/examples/ts/candlestick-large.ts
@@ -14,200 +14,209 @@ const dataCount = 2e5;
 const data = generateOHLC(dataCount);
 
 option = {
-    dataset: {
-        source: data
-    },
-    title: {
-        text: 'Data Amount: ' + echarts.format.addCommas(dataCount)
+  dataset: {
+    source: data
+  },
+  title: {
+    text: 'Data Amount: ' + echarts.format.addCommas(dataCount)
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'line'
+    }
+  },
+  toolbox: {
+    feature: {
+      dataZoom: {
+        yAxisIndex: false
+      }
+    }
+  },
+  grid: [
+    {
+      left: '10%',
+      right: '10%',
+      bottom: 200
     },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'line'
-        }
+    {
+      left: '10%',
+      right: '10%',
+      height: 80,
+      bottom: 80
+    }
+  ],
+  xAxis: [
+    {
+      type: 'category',
+      scale: true,
+      boundaryGap: false,
+      // inverse: true,
+      axisLine: { onZero: false },
+      splitLine: { show: false },
+      splitNumber: 20,
+      min: 'dataMin',
+      max: 'dataMax'
     },
-    toolbox: {
-        feature: {
-            dataZoom: {
-                yAxisIndex: false
-            },
-        }
+    {
+      type: 'category',
+      gridIndex: 1,
+      scale: true,
+      boundaryGap: false,
+      axisLine: { onZero: false },
+      axisTick: { show: false },
+      splitLine: { show: false },
+      axisLabel: { show: false },
+      splitNumber: 20,
+      min: 'dataMin',
+      max: 'dataMax'
+    }
+  ],
+  yAxis: [
+    {
+      scale: true,
+      splitArea: {
+        show: true
+      }
     },
-    grid: [
-        {
-            left: '10%',
-            right: '10%',
-            bottom: 200
-        },
-        {
-            left: '10%',
-            right: '10%',
-            height: 80,
-            bottom: 80
-        }
-    ],
-    xAxis: [
-        {
-            type: 'category',
-            scale: true,
-            boundaryGap: false,
-            // inverse: true,
-            axisLine: {onZero: false},
-            splitLine: {show: false},
-            splitNumber: 20,
-            min: 'dataMin',
-            max: 'dataMax'
-        },
-        {
-            type: 'category',
-            gridIndex: 1,
-            scale: true,
-            boundaryGap: false,
-            axisLine: {onZero: false},
-            axisTick: {show: false},
-            splitLine: {show: false},
-            axisLabel: {show: false},
-            splitNumber: 20,
-            min: 'dataMin',
-            max: 'dataMax'
-        }
-    ],
-    yAxis: [
-        {
-            scale: true,
-            splitArea: {
-                show: true
-            }
-        },
-        {
-            scale: true,
-            gridIndex: 1,
-            splitNumber: 2,
-            axisLabel: {show: false},
-            axisLine: {show: false},
-            axisTick: {show: false},
-            splitLine: {show: false}
-        }
-    ],
-    dataZoom: [
-        {
-            type: 'inside',
-            xAxisIndex: [0, 1],
-            start: 10,
-            end: 100
-        },
-        {
-            show: true,
-            xAxisIndex: [0, 1],
-            type: 'slider',
-            bottom: 10,
-            start: 10,
-            end: 100
-        }
-    ],
-    visualMap: {
-        show: false,
-        seriesIndex: 1,
-        dimension: 6,
-        pieces: [{
-            value: 1,
-            color: upColor
-        }, {
-            value: -1,
-            color: downColor
-        }]
+    {
+      scale: true,
+      gridIndex: 1,
+      splitNumber: 2,
+      axisLabel: { show: false },
+      axisLine: { show: false },
+      axisTick: { show: false },
+      splitLine: { show: false }
+    }
+  ],
+  dataZoom: [
+    {
+      type: 'inside',
+      xAxisIndex: [0, 1],
+      start: 10,
+      end: 100
     },
-    series: [
-        {
-            type: 'candlestick',
-            itemStyle: {
-                color: upColor,
-                color0: downColor,
-                borderColor: upBorderColor,
-                borderColor0: downBorderColor
-            },
-            encode: {
-                x: 0,
-                y: [1, 4, 3, 2]
-            }
-        },
-        {
-            name: 'Volumn',
-            type: 'bar',
-            xAxisIndex: 1,
-            yAxisIndex: 1,
-            itemStyle: {
-                color: '#7fbe9e'
-            },
-            large: true,
-            encode: {
-                x: 0,
-                y: 5
-            }
-        }
+    {
+      show: true,
+      xAxisIndex: [0, 1],
+      type: 'slider',
+      bottom: 10,
+      start: 10,
+      end: 100
+    }
+  ],
+  visualMap: {
+    show: false,
+    seriesIndex: 1,
+    dimension: 6,
+    pieces: [
+      {
+        value: 1,
+        color: upColor
+      },
+      {
+        value: -1,
+        color: downColor
+      }
     ]
+  },
+  series: [
+    {
+      type: 'candlestick',
+      itemStyle: {
+        color: upColor,
+        color0: downColor,
+        borderColor: upBorderColor,
+        borderColor0: downBorderColor
+      },
+      encode: {
+        x: 0,
+        y: [1, 4, 3, 2]
+      }
+    },
+    {
+      name: 'Volumn',
+      type: 'bar',
+      xAxisIndex: 1,
+      yAxisIndex: 1,
+      itemStyle: {
+        color: '#7fbe9e'
+      },
+      large: true,
+      encode: {
+        x: 0,
+        y: 5
+      }
+    }
+  ]
 };
 
 type DataItem = [string, number, number, number, number, number, number];
 
 function generateOHLC(count: number) {
-    let data: DataItem[]= [];
-
-    let xValue = +new Date(2011, 0, 1);
-    let minute = 60 * 1000;
-    let baseValue = Math.random() * 12000;
-    let boxVals = new Array(4);
-    let dayRange = 12;
+  let data: DataItem[] = [];
 
-    for (let i = 0; i < count; i++) {
-        baseValue = baseValue + Math.random() * 20 - 10;
+  let xValue = +new Date(2011, 0, 1);
+  let minute = 60 * 1000;
+  let baseValue = Math.random() * 12000;
+  let boxVals = new Array(4);
+  let dayRange = 12;
 
-        for (let j = 0; j < 4; j++) {
-            boxVals[j] = (Math.random() - 0.5) * dayRange + baseValue;
-        }
-        boxVals.sort();
+  for (let i = 0; i < count; i++) {
+    baseValue = baseValue + Math.random() * 20 - 10;
 
-        let openIdx = Math.round(Math.random() * 3);
-        let closeIdx = Math.round(Math.random() * 2);
-        if (closeIdx === openIdx) {
-            closeIdx++;
-        }
-        let volumn = boxVals[3] * (1000 + Math.random() * 500);
+    for (let j = 0; j < 4; j++) {
+      boxVals[j] = (Math.random() - 0.5) * dayRange + baseValue;
+    }
+    boxVals.sort();
 
-        // ['open', 'close', 'lowest', 'highest', 'volumn']
-        // [1, 4, 3, 2]
-        data[i] = [
-            echarts.format.formatTime('yyyy-MM-dd\nhh:mm:ss', xValue += minute),
-            +boxVals[openIdx].toFixed(2), // open
-            +boxVals[3].toFixed(2), // highest
-            +boxVals[0].toFixed(2), // lowest
-            +boxVals[closeIdx].toFixed(2),  // close
-            +volumn.toFixed(0),
-            getSign(data, i, +boxVals[openIdx], +boxVals[closeIdx], 4) // sign
-        ];
+    let openIdx = Math.round(Math.random() * 3);
+    let closeIdx = Math.round(Math.random() * 2);
+    if (closeIdx === openIdx) {
+      closeIdx++;
     }
+    let volumn = boxVals[3] * (1000 + Math.random() * 500);
 
-    return data;
+    // ['open', 'close', 'lowest', 'highest', 'volumn']
+    // [1, 4, 3, 2]
+    data[i] = [
+      echarts.format.formatTime('yyyy-MM-dd\nhh:mm:ss', (xValue += minute)),
+      +boxVals[openIdx].toFixed(2), // open
+      +boxVals[3].toFixed(2), // highest
+      +boxVals[0].toFixed(2), // lowest
+      +boxVals[closeIdx].toFixed(2), // close
+      +volumn.toFixed(0),
+      getSign(data, i, +boxVals[openIdx], +boxVals[closeIdx], 4) // sign
+    ];
+  }
 
-    function getSign(data: DataItem[], dataIndex: number, openVal: number, closeVal: number, closeDimIdx: number) {
-        var sign;
-        if (openVal > closeVal) {
-            sign = -1;
-        }
-        else if (openVal < closeVal) {
-            sign = 1;
-        }
-        else {
-            sign = dataIndex > 0
-                // If close === open, compare with close of last record
-                ? (data[dataIndex - 1][closeDimIdx] <= closeVal ? 1 : -1)
-                // No record of previous, set to be positive
-                : 1;
-        }
+  return data;
 
-        return sign;
+  function getSign(
+    data: DataItem[],
+    dataIndex: number,
+    openVal: number,
+    closeVal: number,
+    closeDimIdx: number
+  ) {
+    var sign;
+    if (openVal > closeVal) {
+      sign = -1;
+    } else if (openVal < closeVal) {
+      sign = 1;
+    } else {
+      sign =
+        dataIndex > 0
+          ? // If close === open, compare with close of last record
+            data[dataIndex - 1][closeDimIdx] <= closeVal
+            ? 1
+            : -1
+          : // No record of previous, set to be positive
+            1;
     }
-}
 
+    return sign;
+  }
+}
 
-export {}
\ No newline at end of file
+export {};
diff --git a/public/examples/ts/candlestick-sh-2015.ts b/public/examples/ts/candlestick-sh-2015.ts
index 7d24525..fc5a5e0 100644
--- a/public/examples/ts/candlestick-sh-2015.ts
+++ b/public/examples/ts/candlestick-sh-2015.ts
@@ -4,134 +4,138 @@ category: candlestick
... 57066 lines suppressed ...

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