diff --git a/bigscreen/css/.DS_Store b/bigscreen/css/.DS_Store
deleted file mode 100644
index 2d89eb2..0000000
Binary files a/bigscreen/css/.DS_Store and /dev/null differ
diff --git a/bigscreen/css/comon0.css b/bigscreen/css/comon0.css
deleted file mode 100644
index ac23225..0000000
--- a/bigscreen/css/comon0.css
+++ /dev/null
@@ -1,630 +0,0 @@
-@charset "utf-8";
-
-/* CSS Document */
-* {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box
-}
-
-*,
-body {
- padding: 0px;
- margin: 0px;
- color: #222;
- font-family: "微软雅黑";
-}
-
-body {
- background: #000d4a url(../images/bg.jpg) center center;
- background-size: cover;
- color: #666;
- font-size: .1rem;
-}
-
-li {
- list-style-type: none;
-}
-
-@font-face {
- font-family: electronicFont;
- src: url(../font/DS-DIGIT.TTF)
-}
-
-i {
- margin: 0px;
- padding: 0px;
- text-indent: 0px;
-}
-
-img {
- border: none;
- max-width: 100%;
-}
-
-a {
- text-decoration: none;
- color: #399bff;
-}
-
-a.active,
-a:focus {
- outline: none !important;
- text-decoration: none;
-}
-
-ol,
-ul,
-p,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- padding: 0;
- margin: 0
-}
-
-a:hover {
- color: #06c;
- text-decoration: none !important
-}
-
-html,
-body {
- height: 100%;
-}
-
-.clearfix:after,
-.clearfix:before {
- display: table;
- content: " "
-}
-
-.clearfix:after {
- clear: both
-}
-
-.pulll_left {
- float: left;
-}
-
-.pulll_right {
- float: right;
-}
-
-/*谷哥滚动条样式*/
-
-::-webkit-scrollbar {
- width: 5px;
- height: 5px;
- position: absolute
-}
-
-::-webkit-scrollbar-thumb {
- background-color: #5bc0de
-}
-
-::-webkit-scrollbar-track {
- background-color: #ddd
-}
-
-/***/
-
-.loading {
- position: fixed;
- left: 0;
- top: 0;
- font-size: .3rem;
- z-index: 100000000;
- width: 100%;
- height: 100%;
- background: #1a1a1c;
- text-align: center;
-}
-
-.loadbox {
- position: absolute;
- width: 160px;
- height: 150px;
- color: #324e93;
- left: 50%;
- top: 50%;
- margin-top: -100px;
- margin-left: -75px;
-}
-
-.loadbox img {
- margin: 10px auto;
- display: block;
- width: 40px;
-}
-
-.copyright {
- line-height: .5rem;
- text-align: center;
- padding-right: 15px;
- bottom: 0;
- color: rgba(255, 255, 255, .5);
- font-size: .12rem;
- position: absolute;
- left: 0;
- width: 100%;
-}
-
-.head {
- height: 1.05rem;
- background: url(../images/head_bg.png) no-repeat center center;
- background-size: 100% 100%;
- position: relative
-}
-
-.head h1 {
- color: #fff;
- text-align: center;
- font-size: .42rem;
- line-height: .75rem;
-}
-
-.head h1 img {
- width: 1.5rem;
- display: inline-block;
- vertical-align: middle;
-}
-
-.time {
- position: absolute;
- right: .15rem;
- top: 0;
- line-height: .75rem;
- color: rgba(255, 255, 255, .7);
- font-size: .26rem;
- padding-right: .1rem;
- font-family: electronicFont;
-}
-
-.mainbox {
- padding: 0 .2rem 0rem .2rem;
- height: calc(70% - 1.05rem)
-}
-
-.mainbox>ul {
- margin-left: -.1rem;
- margin-right: -.1rem;
- height: 100%
-}
-
-.mainbox>ul>li {
- float: left;
- padding: 0 .1rem;
- height: 100%;
- width: 30%
-}
-
-.mainbox>ul>li:nth-child(2) {
- width: 40%
-}
-
-.mainbox2 {
- padding: 0 .2rem 0rem .2rem;
- height: calc(30% - .5rem)
-}
-
-.mainbox2>ul {
- margin-left: -.1rem;
- margin-right: -.1rem;
- height: 100%
-}
-
-.mainbox2>ul>li {
- float: left;
- padding: 0 .1rem;
- height: 100%;
- width: 50%
-}
-
-
-
-.boxall {
- border: 1px solid rgba(25, 186, 139, .17);
- padding: 0 .2rem .2rem .2rem;
- background: rgba(255, 255, 255, .04) url(../images/line.png);
- background-size: 100% auto;
- position: relative;
- margin-bottom: .15rem;
- z-index: 10;
-}
-
-.boxall:before,
-.boxall:after {
- position: absolute;
- width: .1rem;
- height: .1rem;
- content: "";
- border-top: 2px solid #02a6b5;
- top: 0;
-}
-
-.boxall:before,
-.boxfoot:before {
- border-left: 2px solid #02a6b5;
- left: 0;
-}
-
-.boxall:after,
-.boxfoot:after {
- border-right: 2px solid #02a6b5;
- right: 0;
-}
-
-.alltitle {
- font-size: .18rem;
- color: #fff;
- line-height: .4rem;
- border-bottom: 1px dotted rgba(255, 255, 255, .2);
-}
-
-.boxnav {
- height: calc(100% - .4rem);
-}
-
-.boxfoot {
- position: absolute;
- bottom: 0;
- width: 100%;
- left: 0;
-}
-
-.boxfoot:before,
-.boxfoot:after {
- position: absolute;
- width: .1rem;
- height: .1rem;
- content: "";
- border-bottom: 2px solid #02a6b5;
- bottom: 0;
-}
-
-.barnav {
- position: absolute;
- width: 100%;
- z-index: 100;
-}
-
-.bar {
- background: rgba(101, 132, 226, .1);
- padding: .15rem;
-}
-
-.barbox li,
-.barbox2 li {
- width: 33.33333%;
- text-align: center;
- position: relative;
-}
-
-.barbox:before,
-.barbox:after {
- position: absolute;
- width: .3rem;
- height: .1rem;
- content: "";
-}
-
-.barbox:before {
- border-left: 2px solid #02a6b5;
- left: 0;
- border-top: 2px solid #02a6b5;
-}
-
-.barbox:after {
- border-right: 2px solid #02a6b5;
- right: 0;
- bottom: 0;
- border-bottom: 2px solid #02a6b5;
-}
-
-.barbox li:before {
- position: absolute;
- content: "";
- height: 50%;
- width: 1px;
- background: rgba(255, 255, 255, .2);
- right: 0;
- top: 25%;
-}
-
-.barbox {
- border: 1px solid rgba(25, 186, 139, .17);
- position: relative;
-}
-
-.barbox li {
- font-size: .5rem;
- color: #ffeb7b;
- padding: .05rem 0;
- font-family: Gotham, "Helvetica Neue", Helvetica, Arial, "sans-serif";
- font-weight: bold;
- font-family: electronicFont;
-}
-
-.barbox2 li {
- font-size: .19rem;
- color: rgba(255, 255, 255, .7);
-}
-
-.mapbox {
- height: calc(100%);
- display: flex;
- align-items: center;
- justify-content: center;
- overflow: hidden;
-}
-
-.map {
- position: relative;
- height: 100%;
- z-index: 9;
- width: 100%;
-}
-
-.map4 {
- width: 200%;
- height: 100%;
- position: relative;
- left: -50%;
- top: 4%;
- margin-top: .2rem;
- z-index: 5;
-}
-
-.map1 {
- width: 6.43rem;
- z-index: 2;
- top: .45rem;
- left: .66rem;
- animation: myfirst2 15s infinite linear;
-}
-
-.map2 {
- width: 5.66rem;
- top: .85rem;
- left: 1.03rem;
- z-index: 3;
- opacity: 0.2;
- animation: myfirst 10s infinite linear;
-}
-
-.map3 {
- width: 5.18rem;
- top: 1.07rem;
- left: 1.4rem;
- z-index: 1;
- transform: scale(.8);
- opacity: .6
-}
-
-.map1,
-.map2,
-.map3 {
- position: absolute;
-}
-
-
-
-
-
-.wrap {
- overflow: hidden;
-}
-
-.wrap li {
- line-height: .42rem;
- height: .42rem;
- text-indent: .24rem;
- margin-bottom: .1rem;
-}
-
-.wrap li p {
- border: 1px solid rgba(25, 186, 139, .17);
-}
-
-.wrap li p {
- display: flex;
- justify-content: space-between;
-}
-
-.wrap li p {
- display: flex;
- align-items: center;
- height: 80%;
-}
-
-.wrap li p span {
- color: rgba(255, 255, 255, .6);
- text-align: center;
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
- width: 20%;
- font-size: .16rem;
-}
-
-.wrap li p span:first-child {
- width: 40%;
- text-align: left;
-}
-
-.sycm ul {
- padding: .16rem 0;
- width: 100%;
-}
-
-.sycm li {
- float: left;
- width: 25%;
- text-align: center;
- position: relative
-}
-
-.sycm li:before {
- position: absolute;
- content: "";
- height: 30%;
- width: 1px;
- background: rgba(255, 255, 255, .1);
- right: 0;
- top: 15%;
-}
-
-.sycm {
- height: 80%;
- display: flex;
- align-items: center
-}
-
-.sycm li:last-child:before,
-.sycm2 li:nth-child(3):before {
- width: 0;
-}
-
-.sycm li h2 {
- font-size: .3rem;
- color: #46b8ff;
- padding-bottom: .2rem;
-}
-
-.sycm li span {
- font-size: .2rem;
- color: #fff;
- opacity: .5;
-}
-
-.sycm2 {
- height: 90%
-}
-
-.sycm2 li {
- width: 33.3333%;
- padding: 10px 0;
-}
-
-.sycm2 li h2 {
- color: #2ad08a
-}
-
-.btbox {
- height: 100%
-}
-
-.btbox li {
- height: 100%;
- float: left;
- width: 25%;
- padding-left: 5%;
-}
-
-@keyframes myfirst2 {
- from {
- transform: rotate(0deg) scale(.8);
- }
-
- to {
- transform: rotate(359deg) scale(.8);
- }
-}
-
-@keyframes myfirst {
- from {
- transform: rotate(0deg) scale(.8);
- }
-
- to {
- transform: rotate(-359deg) scale(.8);
- }
-}
-
-
-/*Plugin CSS*/
-.str_wrap {
- overflow: hidden;
- width: 100%;
- position: relative;
- -moz-user-select: none;
- -khtml-user-select: none;
- user-select: none;
- white-space: nowrap;
-}
-
-
-.str_move {
- white-space: nowrap;
- position: absolute;
- top: 0;
- left: 0;
- cursor: move;
-}
-
-.str_move_clone {
- display: inline-block;
- vertical-align: top;
- position: absolute;
- left: 100%;
- top: 0;
-}
-
-.str_vertical .str_move_clone {
- left: 0;
- top: 100%;
-}
-
-.str_down .str_move_clone {
- left: 0;
- bottom: 100%;
-}
-
-.str_vertical .str_move,
-.str_down .str_move {
- white-space: normal;
- width: 100%;
-}
-
-.str_static .str_move,
-.no_drag .str_move,
-.noStop .str_move {
- cursor: inherit;
-}
-
-.str_wrap img {
- max-width: none !important;
-}
-
-
-.alltitle .pulll_right a {
- color: #fff;
-}
-
-.alltitle .pulll_right a span {
- display: inline-block;
- background: #58c485;
- width: .16rem;
- height: .16rem;
- vertical-align: middle;
- border-radius: 50%;
- margin: 0 .05rem 0 .1rem;
-}
-
-.alltitle .pulll_right a:nth-child(2) span {
- background: #ea7231;
-}
-
-.alltitle .sebtn a {
- opacity: .6;
- display: inline-block;
- padding: 0 .1rem
-}
-
-.alltitle .sebtn a.active {
- opacity: 1
-}
\ No newline at end of file
diff --git a/bigscreen/css/loading-1.gif b/bigscreen/css/loading-1.gif
deleted file mode 100644
index db3a483..0000000
Binary files a/bigscreen/css/loading-1.gif and /dev/null differ
diff --git a/bigscreen/font/DS-DIGI.TTF b/bigscreen/font/DS-DIGI.TTF
deleted file mode 100644
index 0925877..0000000
Binary files a/bigscreen/font/DS-DIGI.TTF and /dev/null differ
diff --git a/bigscreen/font/DS-DIGIB.TTF b/bigscreen/font/DS-DIGIB.TTF
deleted file mode 100644
index 064ad47..0000000
Binary files a/bigscreen/font/DS-DIGIB.TTF and /dev/null differ
diff --git a/bigscreen/font/DS-DIGII.TTF b/bigscreen/font/DS-DIGII.TTF
deleted file mode 100644
index 2aae3d8..0000000
Binary files a/bigscreen/font/DS-DIGII.TTF and /dev/null differ
diff --git a/bigscreen/font/DS-DIGIT.TTF b/bigscreen/font/DS-DIGIT.TTF
deleted file mode 100644
index 65642f9..0000000
Binary files a/bigscreen/font/DS-DIGIT.TTF and /dev/null differ
diff --git a/bigscreen/images/.DS_Store b/bigscreen/images/.DS_Store
deleted file mode 100644
index b83a52e..0000000
Binary files a/bigscreen/images/.DS_Store and /dev/null differ
diff --git a/bigscreen/images/bg.jpg b/bigscreen/images/bg.jpg
deleted file mode 100644
index 5fabd7a..0000000
Binary files a/bigscreen/images/bg.jpg and /dev/null differ
diff --git a/bigscreen/images/head_bg.png b/bigscreen/images/head_bg.png
deleted file mode 100644
index a2e45f6..0000000
Binary files a/bigscreen/images/head_bg.png and /dev/null differ
diff --git a/bigscreen/images/jt.png b/bigscreen/images/jt.png
deleted file mode 100644
index 1eb5cb0..0000000
Binary files a/bigscreen/images/jt.png and /dev/null differ
diff --git a/bigscreen/images/lbx.png b/bigscreen/images/lbx.png
deleted file mode 100644
index cefb215..0000000
Binary files a/bigscreen/images/lbx.png and /dev/null differ
diff --git a/bigscreen/images/line.png b/bigscreen/images/line.png
deleted file mode 100644
index 05db7f8..0000000
Binary files a/bigscreen/images/line.png and /dev/null differ
diff --git a/bigscreen/images/loading.gif b/bigscreen/images/loading.gif
deleted file mode 100644
index db3a483..0000000
Binary files a/bigscreen/images/loading.gif and /dev/null differ
diff --git a/bigscreen/images/map.png b/bigscreen/images/map.png
deleted file mode 100644
index 2138288..0000000
Binary files a/bigscreen/images/map.png and /dev/null differ
diff --git a/bigscreen/index.html b/bigscreen/index.html
deleted file mode 100644
index f9ba7f9..0000000
--- a/bigscreen/index.html
+++ /dev/null
@@ -1,229 +0,0 @@
-
-
-
-
-
- index
-
-
-
-
-
-
-

页面加载中...
-
-
-
大数据可视化系统数据分析通用模版
-
2019/11/29 0:12:42
-
-
-
- -
-
-
模块标题
-
-
- -
-
1824
- 华东地区
-
- -
-
1920
- 华西地区
-
- -
-
19%
- 华南地区
-
- -
-
1824
- 华北地区
-
-
-
-
-
-
-
-
模块标题
-
-
- -
-
1824
- 字段名称
-
- -
-
1920
- 字段名称
-
- -
-
19%
- 字段名称
-
-
- -
-
1824
- 字段名称
-
- -
-
19%
- 字段名称
-
- -
-
1824
- 字段名称
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
字段名称
-
-
- -
-
深圳腾讯科技有限公司门禁系统在线
-
- -
-
网易科技有限公司防火系统在线
-
- -
-
百度科技有限公司防火系统在线
-
- -
-
汽车之家科技有限公司定位系统在线
-
- -
-
小米科技有限公司定位系统在线
-
-
-
-
-
-
-
-
-
版权所有:深圳市深海时代网络科技有限公司 粤ICP备15031517号-4
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/bigscreen/js/.DS_Store b/bigscreen/js/.DS_Store
deleted file mode 100644
index 2e21b9a..0000000
Binary files a/bigscreen/js/.DS_Store and /dev/null differ
diff --git a/bigscreen/js/area_echarts.js b/bigscreen/js/area_echarts.js
deleted file mode 100644
index c3252be..0000000
--- a/bigscreen/js/area_echarts.js
+++ /dev/null
@@ -1,209 +0,0 @@
-
-$(function () {
- map();
- function map() {
- // 基于准备好的dom,初始化echarts实例
- var myChart = echarts.init(document.getElementById('map_1'));
-var data = [
- {name: '华南区', value: 290},//广东 value 可控制圆点大小
- {name: '华东区', value: 200},//江苏
- {name: '华西区', value: 180},//陕西
- {name: '华北区', value: 260}//北京
-];
- var toolTipData = [
-
- {name:"华南区",value:[{name:"公司数量",value:195},{name:"设备数量",value:14},{name:"人员数量",value:754}]},
- {name:"华东区",value:[{name:"公司数量",value:75},{name:"设备数量",value:32},{name:"人员数量",value:23}]},
- {name:"华西区",value:[{name:"公司数量",value:21},{name:"设备数量",value:65},{name:"人员数量",value:21}]},
- {name:"华北区",value:[{name:"公司数量",value:1533},{name:"设备数量",value:14},{name:"人员数量",value:82}]},
-
-];
-var geoCoordMap = {
- '华南区':[113.263802,23.138215],
- '华东区':[118.790825,32.061636],
- '华西区':[108.954065,34.3457],
- '华北区':[116.383491,39.921771],
-
-};
-var convertData = function (data) {
- var res = [];
- for (var i = 0; i < data.length; i++) {
- var geoCoord = geoCoordMap[data[i].name];
- if (geoCoord) {
- res.push({
- name: data[i].name,
- value: geoCoord.concat(data[i].value)
- });
- }
- }
- return res;
-};
-
-option = {
- // backgroundColor: '#404a59',
- /*** title: {
- text: '实时行驶车辆',
- subtext: 'data from PM25.in',
- sublink: 'http://www.pm25.in',
- left: 'center',
- textStyle: {
- color: '#fff'
- }
- },**/
- tooltip : {
- trigger: 'item',
- formatter: function(params) {
-
- if (typeof(params.value)[2] == "undefined") {
-
- var toolTiphtml = ''
-
- for(var i = 0;i'
-
- for(var j = 0;j"
-
- }
-
- }
-
- }
-
- console.log(toolTiphtml)
-
- // console.log(convertData(data))
-
- return toolTiphtml;
-
- } else {
-
- var toolTiphtml = ''
-
- for(var i = 0;i'
-
- for(var j = 0;j"
-
- }
-
- }
-
- }
-
- console.log(toolTiphtml)
-
- // console.log(convertData(data))
-
- return toolTiphtml;
-
- }
-
- }
-
-
- },
-
- geo: {
- map: 'china',
- label: {
- emphasis: {
- show: false
- }
- },
- roam: true,
- itemStyle: {
- normal: {
- areaColor: '#4c60ff',
- borderColor: '#002097'
- },
- emphasis: {
- areaColor: '#293fff'
- }
- }
- },
- series : [
- {
- name: '',
- type: 'effectScatter',
-
- showEffectOn: 'render',
- rippleEffect: {
- brushType: 'stroke'
- },
- coordinateSystem: 'geo',
- data: convertData(data),
- symbolSize: function (val) {
- return val[2] / 15;
- },
- label: {
- normal: {
- formatter: '{b}',
- position: 'right',
- show: true
- },
- emphasis: {
- show: true
- }
- },
- itemStyle: {
- normal: {
- color: '#ffeb7b'
- }
- }
- }
-
- /**
- ,
- {
- name: 'Top 5',
- type: 'effectScatter',
- coordinateSystem: 'geo',
- data: convertData(data.sort(function (a, b) {
- return b.value - a.value;
- }).slice(0, 6)),
- symbolSize: function (val) {
- return val[2] / 20;
- },
- showEffectOn: 'render',
- rippleEffect: {
- brushType: 'stroke'
- },
- hoverAnimation: true,
- label: {
- normal: {
- formatter: '{b}',
- position: 'right',
- show: true
- }
- },
- itemStyle: {
- normal: {
- color: '#ffd800',
- shadowBlur: 10,
- shadowColor: 'rgba(0,0,0,.3)'
- }
- },
- zlevel: 1
- }
- **/
- ]
-};
-
- myChart.setOption(option);
- window.addEventListener("resize",function(){
- myChart.resize();
- });
- }
-
-})
-
diff --git a/bigscreen/js/china.js b/bigscreen/js/china.js
deleted file mode 100644
index a79e022..0000000
--- a/bigscreen/js/china.js
+++ /dev/null
@@ -1,28 +0,0 @@
-(function (root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['exports', 'echarts'], factory);
- } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
- // CommonJS
- factory(exports, require('echarts'));
- } else {
- // Browser globals
- factory({}, root.echarts);
- }
-}(this, function (exports, echarts) {
- var log = function (msg) {
- if (typeof console !== 'undefined') {
- console && console.error && console.error(msg);
- }
- }
- if (!echarts) {
- log('ECharts is not Loaded');
- return;
- }
- if (!echarts.registerMap) {
- log('ECharts Map is not loaded')
- return;
- }
- echarts.registerMap('china1', {"type":"FeatureCollection","features":[{"id":"710000","geometry":{"type":"MultiPolygon","coordinates":[["@@°Ü¯Û","@@ƛĴÕƊÉɼģºðʀ\\ƎsÆNŌÔĚänÜƤɊĂǀĆĴĤNJŨxĚĮǂƺòƌâÔ®ĮXŦţƸZûÐƕƑGđ¨ĭMó·ęcëƝɉlÝƯֹÅŃ^Ó·śŃNjƏďíåɛGɉ¿IċããF¥ĘWǬÏĶñÄ","@@\\p|WoYG¿¥Ij@","@@
¡@V^RqBbAnTXeQr©C","@@ÆEEkWqë I"]],"encodeOffsets":[[[122886,24033],[123335,22980],[122375,24193],[122518,24117],[124427,22618]]]},"properties":{"cp":[121.509062,25.044332],"name":"台湾","childNum":5}},{"id":"130000","geometry":{"type":"MultiPolygon","coordinates":[["@@\\aM`ǽÓnUK
Ĝēs¤©yrý§uģcJ»eIP]ªrºc_ħ²G¼s`jΟnüsÂľP","@@U`Ts¿mÄ","@@FOhđ©OiÃ`ww^ÌkÑH«ƇǤŗĺtFu
{Z}Ö@U´
ʚLg®¯Oı°Ãw ^VbÉsmA
ê]]w§RRl£ŭuwNÁ`ÇFēÝčȻuT¡Ĺ¯Õ¯sŗő£YªhVƍ£ƅnëYNgq¼ś¿µı²UºÝUąąŖóxV@tƯJ]eR¾fe|rHA|h~Ėƍl§ÏjVë` ØoÅbbx³^zÃͶSj®AyÂhðk`«P˵EFÛ¬Y¨Ļrõqi¼Wi°§Ð±²°`[À|ĠO@ÆxO\\ta\\p_Zõ^û{ġȧXýĪÓjùÎRb^λj{íděYfíÙTymńŵōHim½éŅaVcř§ax¹XŻácWU£ôãºQ¨÷Ñws¥qEHÙ|šYQoŕÇyáĂ£MðoťÊP¡mWO¡v{ôvîēÜISpÌhp¨ jdeŔQÖjX³àĈ[n`Yp@UcM`RKhEbpŞlNut®EtqnsÁgAiúoHqCXhfgu~ÏWP½¢G^}¯ÅīGCÑ^ãziMáļMTÃƘrMc|O_¯Ŏ´|morDkO\\mĆJfl@c̬¢aĦtRıÒXòë¬WP{ŵǫƝ
īÛ÷ąV×qƥV¿aȉd³BqPBmaËđŻģmÅ®V¹d^KKonYg¯XhqaLdu¥ÍpDž¡KąÅkĝęěhq}HyÃ]¹ǧ£
Í÷¿qágPmoei¤o^á¾ZEY^
Ný{nOl±Í@Mċèk§daNaÇį¿]øRiiñEūiDZàUtėGyl}ÓM}jpEC~¡FtoQiHkk{ILgĽxqÈƋÄdeVDJj£J|ÅdzÂFt~KŨ¸IÆv|¢r}èonb}`RÎÄn°ÒdÞ²^®lnÐèĄlðÓ×]ªÆ}LiñÖ`^°Ç¶p®đDcŋ`ZÔ¶êqvFÆN®ĆTH®¦O¾IbÐã´BĐɢŴÆíȦpĐÞXR·nndO¤OÀĈƒQgµFo|gȒęSWb©osx|hYhgŃfmÖĩnºTÌSp¢dYĤ¶UĈjlǐpäðëx³kÛfw²Xjz~ÂqbTÑěŨ@|oMzv¢ZrÃVw¬ŧˏf°ÐTªqs{S¯r æÝl¼ÖĞ džiGĘJ¼lr}~K¨ŸƐÌWö¼Þ°nÞoĦL|C~D©|q]SvKÑcwpÏÏĿćènĪWlĄkT}¬Tp~®Hgd˒ĺBVtEÀ¢ôPĎƗè@~kü\\rÊĔÖæW_§¼F´©òDòjYÈrbĞāøŀG{ƀ|¦ðrb|ÀH`pʞkvGpuARhÞÆǶgĘTǼƹS£¨¡ù³ŘÍ]¿ÂyôEP xX¶¹ÜO¡gÚ¡IwÃé¦ÅBÏ|ǰ
N«úmH¯âbęU~xĈbȒ{^xÖlD¸dɂ~"]],"encodeOffsets":[[[120023,41045],[121616,39981],[122102,42307]]]},"properties":{"cp":[114.502461,38.045474],"name":"河北","childNum":3}},{"id":"140000","geometry":{"type":"Polygon","coordinates":["@@ħÜ_ªlìwGkÛÃǏokćiµVZģ¡coTS˹ĪmnÕńehZg{gtwªpXaĚThȑp{¶Eh®RćƑP¿£PmcªaJyý{ýȥoÅîɡųAďä³aÏJ½¥PGąSMsWz½µÛYÓŖgxoOkĒCoȵ]¯_²ÕjāK~©ÅØ^ÔkïçămÏk]±cݯÑÃmQÍ~_apm
~ç¡qu{JÅŧ·Ls}EyÁÆcI{¤IiCfUcƌÃp§]ě«vD@¡SÀµMÅwuYY¡DbÑc¡h×]nkoQdaMç~eDÛtT©±@¥ù@É¡ZcW|WqOJmĩl«ħşvOÓ«IqăV¥D[mI~Ó¢cehiÍ]Ɠ~ĥqX·eƷn±}v[ěďŕ]_œ`¹§ÕōIo©bs^}Ét±ū«³p£ÿ¥WÑxçÁ«h×u×¥ř¾dÒ{ºvĴÎêÌɊ²¶ü¨|ÞƸµȲLLúÉƎ¤ϊęĔV`_bªS^|dzY|dz¥pZbÆ£¶ÒK}tĦÔņƠPYznÍvX¶Ěn ĠÔzý¦ª÷ÑĸÙUȌ¸dòÜJð´ìúNM¬XZ´¤ŊǸ_tldI{¦ƀðĠȤ¥NehXnYGR° ƬDj¬¸|CĞKqºfƐiĺ©ª~ĆOQª ¤@ìǦɌ²æBÊTĞHƘÁĪËĖĴŞȀÆÿȄlŤĒötνî¼ĨXh|ªM¤ÐzÞĩÒSrao³"],"encodeOffsets":[[117016,41452]]},"properties":{"cp":[112.549248,37.857014],"name":"山西","childNum":1}},{"id":"150000","geometry":{"type":"MultiPolygon","coordinates":[["@@ǪƫÌÛM
Ă[`ÕCn}¶Vc
ês¯PqFB
|S³C|kñHdiÄ¥sʼnÅ
PóÑÑE^ÅPpy_YtShQ·aHwsOnʼnÃs©iqjUSiº]ïW«gW¡ARëśijĘ
ů`çõh]y»ǃǛҤxÒm~zf}pf|ÜroÈzrKÈĵSƧżĠu~è¬vîS¼ĂhĖMÈÄw\\fŦ°W ¢¾luŸDw\\Ŗĝ","@@GVu»Aylßí¹ãe]Eāò³C¹ð¾²iÒAdkò^P²CǜңDŽ z¼g^èöŰ_IJĕê}gÁnUI«m
]jvV¼euhwqAaW_µj
»çjioQR¹ēÃßt@r³[ÛlćË^ÍÉáGOUÛOB±XkŹ£k|e]olkVͼÕqtaÏõjgÁ£§U^RLËnX°ÇBz^~wfvypV ¯ƫĉ˭ȫƗŷɿÿĿƑ˃ĝÿÃǃßËőó©ǐȍŒĖM×ÍEyxþp]ÉvïèvƀnÂĴÖ@V~Ĉ³MEĸÅĖtējyÄDXÄxGQuv_i¦aBçw˛wD©{tāmQ{EJ§KPśƘƿ¥@sCTÉ}ɃwƇy±gÑ}T[÷kÐ禫
SÒ¥¸ëBX½HáŵÀğtSÝÂa[ƣ°¯¦Pï¡]£ġÒk®G²èQ°óMq}EóƐÇ\\@áügQÍu¥FTÕ¿Jû]|mvāÎYua^WoÀa·ząÒot×¶CLƗi¯¤mƎHNJ¤îìɾŊìTdåwsRÖgĒųúÍġäÕ}Q¶¿A[¡{d×uQAMxVvMOmăl«ct[wº_ÇÊjb£ĦS_éQZ_lwgOiýe`YYJq¥IÁdz£ÙË[ÕªuƏ³ÍTs·bÁĽäė[b[ŗfãcn¥îC¿÷µ[ŏÀQōĉm¿Á^£mJVmL[{Ï_£F¥Ö{ŹA}
×Wu©ÅaųijƳhB{·TQqÙIķËZđ©Yc|M¡
LeVUóK_QWk_ĥ¿ãZ»X\\ĴuUèlG®ěłTĠğDŃGÆÍz]±
ŭ©Å]ÅÐ}UË¥©TċïxgckfWgi\\ÏĒ¥HkµEë{»ÏetcG±ahUiñiWsɁ·cCÕk]wȑ|ća}w
VaĚá G°ùnM¬¯{ÈÐÆA¥ÄêJxÙ¢hP¢ÛºµwWOóFÁz^ÀŗÎú´§¢T¤ǻƺSėǵhÝÅQgvBHouʝl_o¿Ga{ïq{¥|ſĿHĂ÷aĝÇqZñiñC³ª
»E`¨åXēÕqÉû[l}ç@čƘóO¿¡FUsAʽīccocÇS}£IS~ălkĩXçmĈ
ŀÐoÐdxÒuL^T{r@¢ÍĝKén£kQyÅõËXŷƏL§~}kq»IHėDžjĝ»ÑÞoå°qTt|r©ÏS¯·eŨĕx«È[eM¿yupN~¹ÏyN£{©għWí»Í¾səšDž_ÃĀɗ±ąijĉʍŌŷSÉA±åǥɋ@ë£R©ąP©}ĹªƏj¹erLDĝ·{i«ƫC½ÉshVz
GS|úþXgp{ÁX¿ć{ƱȏñZáĔyoÁhA}ŅĆfdʼn_¹Y°ėǩÑ¡H¯¶oMQqð¡Ë|Ñ`ƭŁX½·óÛxğįÅcQs«tȋDžFù^it«Č¯[hAi©á¥ÇĚ×l|¹y¯Kȝqgů{ñǙµïċĹzŚȭ¶¡oŽäÕG\\ÄT¿Òõr¯LguÏYęRƩɷŌO\\İТæ^Ŋ IJȶȆbÜGĝ¬¿ĚVĎgª^íu½jÿĕęjık@Ľ]ėl¥ËĭûÁėéV©±ćn©ȇÍq¯½YÃÔʼnÉNÑÅÝy¹NqáʅDǡËñƁYÅy̱os§ȋµʽǘǏƬɱàưN¢ƔÊuľýľώȪƺɂļxZĈ}ÌʼnŪĺœĭFЛĽ̅ȣͽÒŵìƩÇϋÿȮǡŏçƑůĕ~ǼȳÐUfdIxÿ\\G zâɏÙOº·pqy£@qþ@Ǟ˽IBäƣzsÂZÁàĻdñ°ŕzéØűzșCìDȐĴĺf®Àľưø@ɜÖÞKĊŇƄ§͑těï͡VAġÑÑ»d³öǍÝXĉĕÖ{þĉu¸ËʅğU̎éhɹƆ̗̮ȘNJ֥ड़ࡰţાíϲäʮW¬®ҌeרūȠkɬɻ̼ãüfƠSצɩςåȈHϚÎKdzͲOðÏȆƘ¼CϚǚ࢚˼ФÔ¤ƌĞ̪Qʤ´¼mȠJˀƲÀɠmɆDŽĜƠ´ǠN~ʢĜ¶ƌĆĘźʆȬ˪ĚǏĞGȖƴƀj`ĢçĶāàŃºēĢĖćYÀŎüôQÐÂŎŞdžŞêƖoˆDĤÕºÑǘÛˤ³̀gńƘĔÀ^ªƂ`ªt¾äƚêĦ¼ÐĔǎ¨Ȕ»͠^ˮÊȦƤøxRrŜH¤¸ÂxDÄ|ø˂˜ƮЬɚwɲFjĔ²Äw°dždÀÉ_ĸdîàŎjÊêTЪŌŜWÈ|tqĢUB~´°ÎFCU¼pĀēƄN¦¾O¶łKĊOjĚj´ĜYp{¦SĚÍ\\TתV÷Ší¨ÅDK°ßtŇĔK¨ǵÂcḷ̌ĚǣȄĽFlġUĵŇȣFʉɁMğįʏƶɷØŭOǽ«ƽū¹Ʊő̝Ȩ§ȞʘĖiɜɶʦ}¨֪ࠜ̀ƇǬ¹ǨE˦ĥªÔêFxúQEr´Wrh¤Ɛ \\talĈDJÜ|[Pll̚¸ƎGú´P¬W¦^¦H]prRn|or¾wLVnÇIujkmon£cX^Bh`¥V¦U¤¸}xRj[^xN[~ªxQ[`ªHÆÂExx^wN¶Ê|¨ìMrdYpoRzNyÀDs~bcfÌ`L¾n|¾T°c¨È¢ar¤`[|òDŞĔöxElÖdHÀI`Ď\\Àì~ÆR¼tf¦^¢ķ¶eÐÚMptgjɡČÅyġLûŇV®ÄÈƀϰP|ªVVªj¬ĚÒêp¬E|ŬÂ_~¼rƐK f{ĘFĒƌXưăkÃĄ}nµo×q£çkX{uĩ«āíÓUŅÝVUŌ]Ť¥lyň[oi{¦Lĸ
Ħ^ôâJ¨^UZðÚĒL¿Ìf£K£ʺoqNwğc`uetOj×°KJ±qÆġmĚŗos¬
qehqsuH{¸kH¡
ÊRǪÇƌbȆ¢´äÜ¢NìÉʖ¦â©Ɨؗ"]],"encodeOffsets":[[[128500,52752],[127089,51784]]]},"properties":{"cp":[111.670801,40.818311],"name":"内蒙古","childNum":2}},{"id":"210000","geometry":{"type":"MultiPolygon","coordinates":[["@@L@@s]","@@MnNm","@@dc","@@eÀC@b","@@f
XwkbrÄ`qg","@@^jtWQ","@@~ Y[c","@@I`ĖN^_¿ZÁM","@@Ïxnj{q_×^Gigp","@@iX¶B
Y","@@Y
Z","@@L_yG`b","@@^WqCTZ","@@\\[§t|]","@@m`p[","@@@é^BntaÊU]x ¯ÄPIJ°hʙK³VÕ@Y~|EvĹsǦL^pòŸÒG Ël]xxÄ_fT¤Ď¤cPC¨¸TVjbgH²sdÎdHt`B²¬GJję¶[ÐhjeXdlwhðSȦªVÊÏÆZÆŶ®²^ÎyÅHńĚDMħĜŁHkçvV[ij¼WYÀäĦ`XlR`ôLUVfK¢{NZdĒªYĸÌÚJRr¸SA|ƴgŴĴÆbvªØX~źB|¦ÕE¤Ð`\\|KUnnI]¤ÀÂĊnŎR®Ő¿¶\\ÀøíDm¦ÎbŨabaĘ\\ľã¸atÎSƐ´©v\\ÖÚÌǴ¤Â¨JKrZ_ZfjþhPkx`YRIjJcVf~sCN¤ EhæmsHy¨SðÑÌ\\\\ĐRÊwS¥fqŒßýáĞÙÉÖ[^¯ǤŲê´\\¦¬ĆPM¯£»uïpùzExanµyoluqe¦W^£ÊL}ñrkqWňûPUP¡ôJoo·U}£[·¨@XĸDXmÛݺGUCÁª½{íĂ^cjk¶Ã[q¤LÉö³cux«|Zd²BWÇ®Yß½ve±ÃCý£W{Ú^q^sÑ·¨ËMr¹·C¥GDrí@wÕKţëV·i}xËÍ÷i©ĝɝǡ]{c±OW³Ya±_ç©HĕoƫŇqr³Lys[ñ³¯OSďOMisZ±ÅFC¥Pq{Ã[Pg}\\¿ghćO
k^ĩÃXaĕËĥMoEqqZûěʼn³F¦oĵhÕP{¯~TÍlªNßYÐ{Ps{ÃVUeĎwk±ʼnVÓ½ŽJãÇÇ»Jm°dhcÀffdF~ĀeĖd`sx² ®EĦ¦dQÂd^~ăÔH¦\\LKpĄVez¤NP ǹÓRÆąJSha[¦´ÂghwmBШźhI|VV|p] ¼èNä¶ÜBÖ¼L`¼bØæKVpoúNZÞÒKxpw|ÊEMnzEQIZZNBčÚFÜçmĩWĪñtÞĵÇñZ«uD±|ƏlǗw·±PmÍada CLǑkùó¡³Ï«QaċÏOÃ¥ÕđQȥċƭy³ÁA"]],"encodeOffsets":[[[123686,41445],[126019,40435],[124393,40128],[126117,39963],[125322,40140],[126686,40700],[126041,40374],[125584,40168],[125509,40217],[125453,40165],[125362,40214],[125280,40291],[125774,39997],[125976,40496],[125822,39993],[122731,40949]]]},"properties":{"cp":[123.429096,41.796767],"name":"辽宁","childNum":16}},{"id":"220000","geometry":{"type":"Polygon","coordinates":["@@ñr½ÉKāGÁ¤ia Éȹ`\\xs¬dĆkNnuNUwNx¶c¸|\\¢
GªóĄ~RãÖÎĢùđŴÕhQxtcæëSɽʼníëlj£ƍG£nj°KƘµDsØÑpyƸ®¿bXp]vbÍZuĂ{n^IüÀSÖ¦EvRÎûh@â[ƏÈô~FNr¯ôçR±HÑlĢ^¤¢OðætxsŒ]ÞÁTĠs¶¿âÆGW¾ìA¦·TѬè¥ÏÐJ¨¼ÒÖ¼ƦɄxÊ~StD@Ă¼Ŵ¡jlºWvÐzƦZвCH AxiukdGgetqmcÛ£Ozy¥cE}|
¾cZ
k¿uŐã[oxGikfeäT@
SUwpiÚFM©£è^Ú`@v¶eňf heP¶täOlÃUgÞzŸU`l}ÔÆUvØ_Ō¬Öi^ĉi§²ÃB~¡ĈÚEgc|DC_Ȧm²rBx¼MÔ¦ŮdĨÃâYxƘDVÇĺĿg¿cwÅ\\¹¥Yĭl¤OvLjM_a W`zļMž·\\swqÝSAqŚij¯°kRē°wx^ĐkǂÒ\\]nrĂ}²ĊŲÒøãh·M{yMzysěnĒġV·°G³¼XÀ¤¹i´o¤ŃÈ`ÌDzÄUĞd\\iÖmÈBĤÜɲDEh LG¾ƀľ{WaYÍÈĢĘÔRîĐj}ÇccjoUb½{h§Ǿ{KƖµÎ÷GĄØŜçưÌs«lyiē«`å§H¥Ae^§GK}iã\\c]v©ģZmÃ|[M}ģTɟĵÂÂ`ÀçmFK¥ÚíÁbX³ÌQÒHof{]ept·GŋĜYünĎųVY^ydõkÅZW«WUa~U·SbwGçǑiW^qFuNĝ·EwUtW·Ýďæ©PuqEzwAVXRãQ`©GY
YhcUGorBd}ģÉb¡·µMicF«Yƅ»
é\\ɹ~ǙG³mØ©BšuT§Ĥ½¢Ã_ýL¡ûsT\\rke\\PnwAKy}ywdSefµ]UhĿD@mÿvaÙNSkCun
cÿ`lWėVâ¦÷~^fÏ~vwHCį`xqTlW«ï¸skmßEGqd¯R
©Ý¯¯S\\cZ¹iűƏCuƍÓXoR}M^o£
R}oªUF
uuXHlEÅÏ©¤ßgXþ¤D²ÄufàÀXXȱAc{Yw¬dvõ´KÊ£\\rµÄlidā]|DÂVH¹Þ®ÜWnCķ W§@\\¸~¤Vp¸póIO¢VOŇürXql~òÉK]¤¥Xrfkvzpm¶bwyFoúv𼤠N°ąO¥«³[éǣű]°Õ\\ÚÊĝôîŇÔaâBYlďQ[ Ë[ïÒ¥RI|`j]P"],"encodeOffsets":[[126831,44503]]},"properties":{"cp":[125.3245,43.886841],"name":"吉林","childNum":1}},{"id":"230000","geometry":{"type":"MultiPolygon","coordinates":[["@@UµNÿ¥īèçHÍøƕ¶Lǽ|g¨|a¾pVidd~ÈiíďÓQġėÇZÎXb½|ſÃH½KFgɱCģÛÇAnjÕc[VĝDZÃËÇ_ £ń³pj£º¿»WH´¯U¸đĢmtĜyzzNN|g¸÷äűѱĉā~mq^[ǁÑďlw]¯xQĔ¯l°řĴrBÞTxr[tޏĻN_yX`biNKu
P£kZĮ¦[ºxÆÀdhĹŀUÈƗCwáZħÄŭcÓ¥»NAw±qȥnD`{ChdÙFć}¢A±Äj¨]ĊÕjŋ«×`VuÓÅ~_kŷVÝyhVkÄãPsOµfgeŇ
µf@u_Ù ÙcªNªÙEojVxT@ãSefjlwH\\pŏäÀvlY½d{F~¦dyz¤PÜndsrhfHcvlwjF£G±DÏƥYyÏu¹XikĿ¦ÏqƗǀOŜ¨LI|FRĂn sª|C˜zxAè¥bfudTrFWÁ¹Am|ĔĕsķÆF´N}ć
UÕ@Áijſmuçuð^ÊýowFzØÎĕNőǏȎôªÌŒDŽàĀÄ˄ĞŀƒʀĀƘŸˮȬƬĊ°Uzouxe]}
AyÈW¯ÌmKQ]Īºif¸ÄX|sZt|½ÚUÎ lk^p{f¤lºlÆW A²PVÜPHÊâ]ÎĈÌÜk´\\@qàsĔÄQºpRij¼èi`¶bXrBgxfv»uUi^v~J¬mVp´£´VWrnP½ì¢BX¬hðX¹^TjVriªjtŊÄmtPGx¸bgRsT`ZozÆO]ÒFôÒOÆŊvÅpcGêsx´DR{AEOr°x|íb³Wm~DVjºéNNËܲɶGxŷCSt}]ûōSmtuÇÃĕNāg»íT«u}ç½BĵÞʣ¥ëÊ¡MÛ³ãȅ¡ƋaǩÈÉQG¢·lG|tvgrrf«ptęŘnÅĢrI²¯LiØsPf_vĠdxM prʹL¤¤eËÀđKïÙVY§]Ióáĥ]ķK¥j|pŇ\\kzţ¦šnņäÔVĂîά|vW®l¤èØrxm¶ă~lÄƯĄ̈́öȄEÔ¤ØQĄĄ»ƢjȦOǺ¨ìSŖÆƬyQv`cwZSÌ®ü±DŽ]ŀç¬B¬©ńzƺŷɄeeOĨSfm ĊƀP̎ēz©ĊÄÕÊmgÇsJ¥ƔŊśæÎÑqv¿íUOµªÂnĦÁ_½ä@êí
£P}Ġ[@gġ}gɊ×ûÏWXá¢užƻÌsNͽƎÁ§čŐAēeL³àydl¦ĘVçŁpśdžĽĺſÊQíÜçÛġÔsĕ¬Ǹ¯YßċġHµ ¡eå`ļrĉŘóƢFìĎWøxÊkƈdƬv|I|·©NqńRŀ¤éeŊŀàŀU²ŕƀBQ£Ď}L¹Îk@©ĈuǰųǨÚ§ƈnTËÇéƟÊcfčŤ^XmHĊĕË«W·ċëx³ǔķÐċJāwİ_ĸȀ^ôWr°oú¬Ħ
ŨK~ȰCĐ´Ƕ£fNÎèâw¢XnŮeÂÆĶ¾¾xäLĴĘlļO¤ÒĨA¢Êɚ¨®ØCÔ ŬGƠƦYĜĘÜƬDJg_ͥœ@čŅĻA¶¯@wÎqC½Ĉ»NăëKďÍQÙƫ[«ÃígßÔÇOÝáWñuZ¯ĥŕā¡ÑķJu¤E 寰WKɱ_d_}}vyõu¬ï¹ÓU±½@gÏ¿rýDg
Cdµ°MFYxw¿CG£Rƛ½Õ{]L§{qqą¿BÇƻğëܭNJË|c²}Fµ}ÙRsÓpg±QNqǫŋRwŕnéÑÉK«SeYR
ŋ@{¤SJ}D Ûǖ֍]gr¡µŷjqWÛham³~S«Ü[","@@ƨĶTLÇyqpÇÛqe{~oyen}s`qiXGù]Ëp½©lÉÁp]Þñ´FĂ^fäîºkàz¼BUv¬D"]],"encodeOffsets":[[[134456,44547],[127123,51780]]]},"properties":{"cp":[126.642464,45.756967],"name":"黑龙江","childNum":2}},{"id":"320000","geometry":{"type":"Polygon","coordinates":["@@Õg^vÁbnÀ`Jnĝ¬òM¶ĘTÖŒbe¦¦{¸ZâćNp©Hp|`mjhSEb\\afv`sz^lkljÄtg¤D¾X¿À|ĐiZȀåB·î}GL¢õcßjayBFµÏC^ĭcÙt¿sğH]j{s©HM¢QnDÀ©DaÜÞ·jgàiDbPufjDk`dPOîhw¡ĥ¥GP²ĐobºrYî¶aHŢ´ ]´rılw³r_{£DB_Ûdåuk|Ũ¯F Cºyr{XFye³Þċ¿ÂkĭB¿MvÛpm`rÚã@ƹhågËÖƿxnlč¶Åì½Ot¾dJlVJĂǀŞqvnO^JZż·Q}êÍÅmµÒ]ƍ¦Dq}¬R^èĂ´ŀĻĊIÔtIJyQŐĠMNtR®òLhĚs©»}OÓGZz¶A\\jĨFäOĤHYJvÞHNiÜaĎÉnFQlNM¤B´ĄNöɂtpŬdZÅglmuÇUšŞÚb¤uŃJŴu»¹ĄlȖħŴw̌ŵ²ǹǠ͛hĭłƕrçü±Yrřl¥i`ã__¢ćSÅr[Çq^ùzWmOĈaŐÝɞï²ʯʊáĘijĒǭPħ͍ôƋÄÄÍīçÛɈǥ£ÛmY`ó£Z«§°Ó³QafusNıDž_k}¢m[ÝóDµ¡RLčiXyÅNïă¡¸iĔÏNÌķoıdōîåŤûHcs}~Ûwbù¹£¦ÓCtOPrE^ÒogĉIµÛÅʹK
¤½phMú`mR¸¦PƚgÉLRs`£¯ãhD¨|³¤C"],"encodeOffsets":[[121451,32518]]},"properties":{"cp":[118.767413,32.041544],"name":"江苏","childNum":1}},{"id":"330000","geometry":{"type":"MultiPolygon","coordinates":[["@@jX^n
","@@sfdM","@@qP\\xz[_i","@@o\\VzRZ}mECy","@@R¢FX}°[m]","@@Cb\\}","@@e|v\\laus","@@v~s{","@@QxÂF©}","@@¹nvÞs©m","@@rQgYIh","@@bi«ZX","@@p[}ILd","@@À¿|","@@¹dnb
","@@rS}[Kl","@@g~h}","@@FlCk","@@ůTG°ĄLHm°UF","@@OdRe","@@v[u\\","@@FjâL~wyoo~sµLZ","@@¬e¹aH","@@\\nÔ¡q]L³ë\\ÿ®QÌ","@@ÊA©]ª","@@Kxv{","@@@hlIk_","@@pWcrxp","@@Md|_iA","@@¢
X£½z\\ðpN","@@hlÜ[LykAvyfw^E ","@@fp¤MusH","@@®_ma~LÁ¬`","@@@°¡mÛGĕ¨§Ianá[ýƤjfæÐNäGp","@@iMt\\","@@Zc[b","@@X®±GrưZæĉm","@@Z~dOSo|A¿qZv","@@@`EN£p","@@|s","@@@nDi","@@n
a£¾uYL¯Qª
mĉÅdMgÇjcº«ę¬K´B«Âącoċ\\xK`cįŧ«®á[~ıxu·ÅKsËÉc¢Ù\\ĭƛëbf¹ģSĜkáƉÔĈZB{aMµfzʼnfÓÔŹŁƋǝÊĉ{ğč±g³ne{çií´S¬\\ßðK¦w\\iqªĭiAuAµ_W¥ƣO\\lċĢttC¨£t`PZäuXßBsĻyekOđġĵHuXBµ]×\\°®¬F¢¾pµ¼kŘó¬Wät¸|@L¨¸µrºù³Ù~§WIZW®±Ð¨ÒÉx`²pĜrOògtÁZ{üÙ[|ûKwsPlU[}¦Rvn`hsª^nQ´ĘRWb_ rtČFIÖkĦPJ¶ÖÀÖJĈĄTĚòC ²@Pú
Øz©PCÈÚDZhŖl¬â~nm¨f©iļ«mntqÒTÜÄjL®EÌFª²iÊxبIÈhhst[Ôx}dtüGæţŔïĬaĸpMËÐj碷ðĄÆMzjWKĎ¢Q¶À_ê_@ıi«pZgf¤Nrq]§ĂN®«H±yƳí¾×ŊďŀĐÏŴǝĂíÀBŖÕªÁŐTFqĉ¯³ËCĕģi¨hÜ·ñt»¯Ï","@@ºwZRkĕWK "]],"encodeOffsets":[[[125785,31436],[125729,31431],[125513,31380],[125329,30690],[125223,30438],[125115,30114],[124815,29155],[124419,28746],[124095,28635],[124005,28609],[125000,30713],[125111,30698],[125078,30682],[125150,30684],[124014,28103],[125008,31331],[125411,31468],[125329,31479],[125369,31139],[125626,30916],[125417,30956],[125254,30976],[125199,30997],[125095,31058],[125083,30915],[124885,31015],[125218,30798],[124867,30838],[124755,30788],[124802,30809],[125267,30657],[125218,30578],[125200,30562],[125192,30787],[124968,30474],[125167,30396],[125115,30363],[124955,29879],[124714,29781],[124762,29462],[124325,28754],[124863,30077],[125366,31477]]]},"properties":{"cp":[120.153576,30.287459],"name":"浙江","childNum":43}},{"id":"340000","geometry":{"type":"MultiPolygon","coordinates":[["@@^iuLV\\","@@e©Edh","@@´CE¶zAXêeödK¡~H¸íæAȽd{ďÅÀ½W®£ChÃsikkly]_teu[bFaTign{]GqªoĈMYá|·¥f¥őaSÕėNµñĞ«Im_m¿Âa]uĜp
Z_§{Cäg¤°r[_YjÆOdý[I[á·¥Q_nùgL¾mzˆDÜÆ¶ĊJhpc¹O]iŠ]¥ jtsggDÑ¡w×jÉ©±EFËKiÛÃÕYv
sm¬njĻª§emná}k«ŕgđ²ÙDÇ¤í¡ªOy×Où±@DñSęćăÕIÕ¿IµĥOlJÕÍRÍ|JìĻÒåyķrĕq§ÄĩsWÆßF¶X®¿mw
RIÞfßoG³¾©uyHį{Ɓħ¯AFnuP
ÍÔzVdàôº^Ðæd´oG¤{S¬ćxã}ŧ×Kǥĩ«ÕOEзÖdÖsƘѨ[Û^Xr¢¼§xvÄÆµ`K§ tÒ´Cvlo¸fzŨð¾NY´ı~ÉĔē
ßúLÃÃ_ÈÏ|]ÂÏHlg`ben¾¢pUh~ƴ˶_r sĄ~cƈ]|r c~`¼{À{ȒiJjz`îÀT¥Û³
]u}f
ïQl{skloNdjäËzDvčoQďHI¦rbrHĖ~BmlNRaĥTX\\{fÁKÁ®TLÂÄMtÊgĀDĄXƔvDcÎJbt[¤D@®hh~kt°ǾzÖ@¾ªdbYhüóV´ŮŒ¨Üc±r@J|àuYÇÔG·ĚąĐlŪÚpSJ¨ĸLvÞcPæķŨ®mÐálsgd×mQ¨ųƩޤIÎs°KZpĄ|XwWdϵmkǀwÌÕæhºgBĝâqÙĊzÖgņtÀÁĂÆáhEz|WzqD¹°Eŧl{ævÜcA`¤C`|´qxIJkq^³³GšµbíZ
¹qpa±ď OH¦Ħx¢gPícOl_iCveaOjCh߸iÝbÛªCC¿mRV§¢A|tbkĜEÀtîm^g´fÄ"]],"encodeOffsets":[[[121722,32278],[119475,30423],[121606,33646]]]},"properties":{"cp":[117.283042,31.86119],"name":"安徽","childNum":3}},{"id":"350000","geometry":{"type":"MultiPolygon","coordinates":[["@@zht´}[","@@aj^~ĆGå","@@edH
se","@@@vPGsyQ","@@sBzddW[O","@@S¨Qy","@@NVucW","@@qptB@q","@@¸[iu","@@Q\\pD[_","@@jSwUappI","@@eXª~","@@AjvFoo","@@fT_Çí\\v|ba¦jZÆy|®","@@IjLg","@@wJIx«¼AoNe{M¥","@@K±¡ÓČ~N¾","@@k¡¹Eh~c®uDqZì¡I~Māe£bN¨gZý¡a±Öcp©PhI¢Qq
ÇGj|¥U g[Ky¬ŏv@OptÉEF\\@ åA¬V{XģĐBy
cpě
¼³Ăp·¤¥ohqqÚ¡ŅLs^á§qlÀhH¨MCe»åÇGD¥zPO£čÙkJA¼ßėuĕeûÒiÁŧS[¡Uûŗ½ùěcݧSùĩąSWó«íęACµeRåǃRCÒÇZÍ¢ź±^dlstjD¸ZpuÔâÃH¾oLUêÃÔjjēò´ĄWƛ
^Ñ¥Ħ@ÇòmOw¡õyJyD}¢ďÑÈġfZda©º²z£NjD°Ötj¶¬ZSÎ~¾c°¶ÐmxO¸¢Pl´SL|¥AȪĖMņIJg®áIJČĒü` QF¬h|ĂJ@zµ |ê³È ¸UÖŬŬÀCtrĸr]ðM¤ĶIJHtÏ AĬkvsq^aÎbvdfÊòSD´Z^xPsĂrvƞŀjJd×ŘÉ ®AΦĤdxĆqAZRÀMźnĊ»İÐZ YXæJyĊ²·¶q§·K@·{sXãô«lŗ¶»o½E¡«¢±¨Y®Ø¶^AvWĶGĒĢPlzfļtàAvWYãO_¤sD§ssČġ[kƤPX¦`¶®BBvĪjv©jx[L¥àï[F
¼ÍË»ğV`«Ip}ccÅĥZEãoP
´B@D¸m±z«Ƴ¿å³BRضWlâþäą`]Z£Tc ĹGµ¶Hm@_©k¾xĨôȉðX«½đCIbćqK³ÁÄš¬OAwã»aLʼnËĥW[ÂGIÂNxij¤D¢îĎÎB§°_JGs¥E@
¤uć
PåcuMuw¢BI¿]zG¹guĮI"]],"encodeOffsets":[[[123250,27563],[122541,27268],[123020,27189],[122916,27125],[122887,26845],[122808,26762],[122568,25912],[122778,26197],[122515,26757],[122816,26587],[123388,27005],[122450,26243],[122578,25962],[121255,25103],[120987,24903],[122339,25802],[121042,25093],[122439,26024]]]},"properties":{"cp":[119.306239,26.075302],"name":"福建","childNum":18}},{"id":"360000","geometry":{"type":"Polygon","coordinates":["@@ÖP¬ǦĪØLŨä~Ĉw«|TH£pc³Ïå¹]ĉđxe{ÎÓvOEm°BƂĨİ|Gvz½ª´HàpeJÝQxnÀWEµàXÅĪt¨ÃĖrÄwÀFÎ|Ă¡WÕ¸cf¥XaęST±m[r«_gmQu~¥V\\OkxtL E¢Ú^~ýØkbēqoě±_Êw§Ñ²ÏƟė¼mĉŹ¿NQ
YBąrwģcÍ¥BŗÊcØiIƝĿuqtāwO]³YCñTeÉcaubÍ]trluī
BÐGsĵıN£ï^ķqsq¿DūūVÕ·´Ç{éĈýÿOER_đûIċâJhŅıNȩĕB
¦K{Tk³¡OP·wnµÏd¯}½TÍ«YiµÕsC¯iM¤¦¯P|ÿUHvhe¥oFTuõ\\OSsMòđƇiaºćXĊĵà·çhƃ÷Ç{ígu^đgm[ÙxiIN¶Õ»lđÕwZSÆv©_ÈëJbVkĔVÀ¤P¾ºÈMÖxlò~ªÚàGĂ¢B±ÌKyñ`w²¹·
`gsÙfIěxŕeykpudjuTfb·hh¿Jd[\\LáƔĨƐAĈepÀÂMD~ņªe^\\^§ý©j×cZبzdÒa¶lÒJìõ`oz÷@¤u޸´ôęöY¼HČƶajlÞƩ¥éZ[|h}^U ¥pĄžƦO lt¸Æ Q\\aÆ|CnÂOjtĚĤdÈF`¶@Ðë ¦ōÒ¨SêvHĢÛ@[Æ
QoxHW[ŰîÀt¦DŽ~NĠ¢lĄtZoCƞÔºCxrpČNpj¢{f_Y`_eq®Aot`@oDXfkp¨|s¬\\DÄSfè©Hn¬
^DhÆyøJhØxĢĀLÊƠPżċĄwĮ¶"],"encodeOffsets":[[118923,30536]]},"properties":{"cp":[115.892151,28.676493],"name":"江西","childNum":1}},{"id":"370000","geometry":{"type":"MultiPolygon","coordinates":[["@@Xjd]mE","@@itnq","@@Dl@k","@@TGw","@@K¬U","@@Wd`c","@@PtMs","@@LnXlc","@@ppVu]Qn","@@cdzAU_","@@udRhnCE
","@@oIpP","@@M{ĿčwbxƨîKÎMĮ]ZF½Y]â£ph¶¨râøÀÎǨ¤^ºÄGz~grĚĜlĞÆLĆdž¢Îo¦cvKbgr°WhmZp L]LºcUÆnżĤÌĒbAnrOA´ȊcÀbƦUØrĆUÜøĬƞŶǬĴóò_Ä«ªdÎÉnb²ĦhņBĖįĦåXćì@L¯´ywƕCéõė ƿ¸lµZæyj|BíÂKNNnoƈfÈMZwnŐNàúÄsTJULîVjǎ¾ĒØDz²XPn±ŴPè¸ŔLƔÜƺ_TüÃĤBBċÈöA´faM¨{«M`¶d¡ôÖ°mȰBÔjj´PM|c^d¤u¤Û´ä«ƢfPk¶Môl]Lb}su^ke{lC
MrDÇ]NÑFsmoõľHyGă{{çrnÓEƕZGª¹Fj¢ÿ©}ÌCǷë¡ąuhÛ¡^KxC`C\\bÅxì²ĝÝ¿_NīCȽĿåB¥¢·IŖÕy\\¹kxãČáKµË¤ÁçFQ¡KtŵƋ]CgÏAùSedcÚźuYfyMmhUWpSyGwMPqŀÁ¼zK¶GY§Ë@´śÇµƕBm@IogZ¯uTMx}CVKï{éƵP_K«pÛÙqċtkkù]gTğwoɁsMõ³ăAN£MRkmEÊčÛbMjÝGu
IZGPģãħE[iµBEuDPÔ~ª¼ęt]ûG§¡QMsğNPŏįzs£Ug{đJĿļā³]ç«Qr~¥CƎÑ^n¶ÆéÎR~ݏYI] PumŝrƿIā[xedzL¯v¯s¬ÁY
~}
ťuŁgƋpÝĄ_ņī¶ÏSR´ÁP~¿Cyċßdwk´SsX|t`Ä ÈðAªìÎT°¦Dda^lĎDĶÚY°`ĪŴǒàŠv\\ebZHŖR¬ŢƱùęOÑM³FÛaj"]],"encodeOffsets":[[[123806,39303],[123821,39266],[123742,39256],[123702,39203],[123649,39066],[123847,38933],[123580,38839],[123894,37288],[123043,36624],[123344,38676],[123522,38857],[123628,38858],[118267,36772]]]},"properties":{"cp":[117.000923,36.675807],"name":"山东","childNum":13}},{"id":"410000","geometry":{"type":"MultiPolygon","coordinates":[["@@dXD}~Hgq~ÔN~zkĘHVsDzßjŬŢ`Pûàl¢\\ÀEhİgÞē X¼`khÍLùµP³swIÓzeŠĠð´E®ÚPtºIŊʺL«šŕQGYfa[şußǑĩų_Z¯ĵÙčC]kbc¥CS¯ëÍB©ïÇÃ_{sWTt³xlàcČzÀD}ÂOQ³ÐTĬµƑпŸghłŦv~}ÂZ«¤lPÇ£ªÝŴÅR§ØnhctâknÏľŹUÓÝdKuķI§oTũÙďkęĆH¸Ó\\Ä¿PcnS{wBIvÉĽ[GqµuŇôYgûZca©@½Õǽys¯}lgg@C\\£asIdÍuCQñ[L±ęk·ţb¨©kK»KC²òGKmĨS`UQnk}AGēsqaJ¥ĐGRĎpCuÌy ã iMcplk|tRkðev~^´¦ÜSí¿_iyjI|ȑ|¿_»d}q^{Ƈdă}tqµ`ŷ飩V¡om½ZÙÏÁRD|JOÈpÀRsI{ùÓjuµ{t}uËRivGçJFjµåkWê´MÂHewixGw½Yŷpµú³XU½ġyłåkÚwZX·l¢Á¢KzOÎÎjc¼htoDHr
|J½}JZ_¯iPq{tę½ĕ¦Zpĵø«kQ
Ť]MÛfaQpě±ǽ¾]uFu÷nčįADp}AjmcEÇaª³o³ÆÍSƇĈÙDIzçñİ^KNiÞñ[aA²zzÌ÷D|[íijgfÕÞd®|`Ć~oĠƑô³ŊD×°¯CsøÂ«ìUMhTº¨¸ǝêWÔDruÂÇZ£ĆPZW~ØØv¬gèÂÒw¦X¤Ā´oŬ¬²Ês~]®tªapŎJ¨Öº_ŔfŐ\\Đ\\Ĝu~m²Ƹ¸fWĦrƔ}Î^gjdfÔ¡J}\\n C¦þWxªJRÔŠu¬ĨĨmFdM{\\d\\YÊ¢ú@@¦ª²SÜsC}fNècbpRmlØ^gd¢aÒ¢CZZxvƶN¿¢T@uC¬^ĊðÄn|lIlXhun[","@@hzUq"]],"encodeOffsets":[[[116744,37216],[116480,33048]]]},"properties":{"cp":[113.665412,34.757975],"name":"河南","childNum":2}},{"id":"420000","geometry":{"type":"MultiPolygon","coordinates":[["@@ASd","@@ls{d","@@¾«}{ra®pîÃ\\{øCËyyB±b\\òÝjKL ]ĎĽÌJyÚCƈćÎT´Å´pb©ÈdFin~BCo°BĎÃømv®E^vǾ½Ĝ²RobÜeN^ĺ£R¬lĶ÷YoĖ¥Ě¾|sOr°jY`~I¾®I{GqpCgyl{£ÍÍyPL¡¡¸kWxYlÙæŁĢz¾V´W¶ùŸo¾ZHxjwfxGNÁ³Xéæl¶EièIH ujÌQ~v|sv¶Ôi|ú¢FhQsğ¦SiŠBgÐE^ÁÐ{čnOÂÈUÎóĔÊēIJ}Z³½Mŧïeyp·uk³DsѨL¶_Åuèw»¡WqÜ]\\Ò§tƗcÕ¸ÕFÏǝĉăxŻČƟOKÉġÿ×wg÷IÅzCg]m«ªGeçÃTC«[t§{loWeC@ps_Bprf_``Z|ei¡oċMqow¹DƝÓDYpûsYkıǃ}s¥ç³[§cY§HK«Qy]¢wwö¸ïx¼ņ¾Xv®ÇÀµRĠÐHM±cÏdƒǍũȅȷ±DSyúĝ£ŤĀàtÖÿï[îb\\}pĭÉI±Ñy
¿³x¯No|¹HÏÛmjúË~TuęjCöAwě¬Rđl¯ ÑbŇTĿ_[IčĄʿnM¦ğ\\É[T·k¹©oĕ@A¾wya¥Y\\¥Âaz¯ãÁ¡k¥ne£ÛwE©Êō¶˓uoj_U¡cF¹[WvP©whuÕyBF`RqJUw\\i¡{jEPïÿ½fć
QÑÀQ{°fLÔ~wXgītêݾĺHd³fJd]HJ²
EoU¥HhwQsƐ»Xmg±çve]DmÍPoCc¾_hhøYrŊU¶eD°Č_N~øĹĚ·`z]Äþp¼
äÌQv\\rCé¾TnkžŐÚÜa¼ÝƆ̶Ûo
d
ĔňТJqPb ¾|J¾fXƐîĨ_Z¯À}úƲN_ĒÄ^ĈaŐyp»CÇÄKñL³ġM²wrIÒŭxjb[n«øæà ^²h¯ÚŐªÞ¸Y²ĒVø}Ā^İ´LÚm¥ÀJÞ{JVųÞŃx×sxxƈē ģMřÚðòIfĊŒ\\Ʈ±ŒdʧĘDvČ_Àæ~Dċ´A®µ¨ØLV¦êHÒ¤"]],"encodeOffsets":[[[113712,34000],[115612,30507],[113649,34054]]]},"properties":{"cp":[114.298572,30.584355],"name":"湖北","childNum":3}},{"id":"430000","geometry":{"type":"MultiPolygon","coordinates":[["@@nFZw","@@ãÆá½ÔXrCO
ËRïÿĩTooQyÓ[ŅBE¬ÎÓXaį§Ã¸G °ITxpúxÚij¥Ï̾edÄ©ĸG
àGhM¤Â_U}Ċ}¢pczfþg¤ÇôAV","@@ȴÚĖÁĐiOĜ«BxDõĚivSÌ}iùÜnкG{p°M°yÂÒzJ²Ì ÂcXëöüiáÿñőФùTz²CȆȸǎŪƑÐc°dPÎğ˶[Ƚu¯½WM¡ÉB·rínZÒ `¨GA¾\\pēXhÃRCüWGġu
Té§ŎÑ©êLM³}_EÇģc®ęisÁPDmÅ{b[RÅs·kPŽƥóRoOV~]{g\\êYƪ¦kÝbiċƵGZ»Ěõ
ó·³vŝ£ø@pyö_ëIkѵbcѧy
×dYتiþUjҳC}ÁN»hĻħƏâƓKA·³CQ±µ§¿AUƑ¹AtćOwD]JUÖgk¯b£ylZFËѱH}EbóľA¡»Ku¦·³åş¥ùBD^{ÌC´¦ŷJ£^[ª¿ğ|ƅ
N
skóā¹¿ï]ă~÷O§@Vm¡Qđ¦¢Ĥ{ºjÔª¥nf´~Õo×ÛąGû¥cÑ[Z¶ŨβSÊǔƐƀAÚŌ¦Qؼrŭ«}NÏürʬmjr@ĘrTW SsdHzƓ^ÇÂyUi¯DÅYlŹu{hT}mĉ¹¥ěDÿë©ıÓ[Oº£¥ótł¹MÕƪ`P
DiÛU¾ÅâìUñBÈ£ýhedy¡oċ`pfmjP~kZa
ZsÐd°wj§@Ĵ®w~^kÀÅKvNmX\\¨aŃqvíó¿F¤¡@ũÑVw}S@j}¾«pĂrªg àÀ²NJ¶¶Dô
K|^ª°LX¾ŴäPα£EXd^¶IJÞÜ~u¸ǔMRhsR
e`ÄofIÔ\\Ø ićymnú¨cj ¢»GČìƊÿШXeĈ¾Oð Fi ¢|[jVxrIQ_EzAN¦zLU`cªxOTu RLĪpUĪȴ^ŎµªÉFx
Üf¤ºgIJèy°Áb[¦Zb¦z½xBĖ@ªpºjS´rVźOd©ʪiĎăJP`"]],"encodeOffsets":[[[115640,30489],[112577,27316],[114113,30649]]]},"properties":{"cp":[112.982279,28.19409],"name":"湖南","childNum":3}},{"id":"440000","geometry":{"type":"MultiPolygon","coordinates":[["@@QdAsa","@@lxDRm","@@sbhNLo","@@Ă ý","@@WltOY[","@@Kr]S","@@e~AS}","@@I|Mym","@@Û³LS²Q","@@nvºBë¥cÕº","@@zdÛJm","@@°³","@@a yAª¸ËJIxØ@ĀHÉÕZofo
o","@@sŗÃÔėAƁZÄ ~°ČPºb","@@¶ÝÌvmĞh¹Ĺ","@@HdSjĒ¢D}war
u«ZqadY{K","@@el\\LqqO","@@~rMmX","@@f^E","@@øPªoj÷ÍÝħXČx°Q¨ıXJp","@@gÇƳmxatfu","@@EÆC½","@@¸B_¶ekWvSivc}p}Ăº¾NĎyj¦Èm th_®Ä}»âUzL˲Aā¡ßH©Ùñ}wkNÕ¹ÇO½¿£ēUlaUìIǪ`uTÅxYĒÖ¼kÖµMjJÚwn\\hĒv]îh|ÈƄøèg¸Ķß ĉĈWb¹ƀdéĘNTtP[öSvrCZaGubo´ŖÒÇĐ~¡zCI
özx¢PnÈñ @ĥÒ¦]ƜX³ăĔñiiÄÓVépKG½ÄÓávYoC·sitiaÀyŧΡÈYDÑům}ý|m[węõĉZÅxUO}÷N¹³ĉo_qtăqwµŁYÙǝŕ¹tïÛUïmRCº
ĭ|µÕÊK½Rē ó]GªęAxNqSF|ām¡diď×YïYWªʼnOeÚtĐ«zđ¹T
āúEáÎÁWwíHcòßÎſ¿Çdğ·ùT×Çūʄ¡XgWÀLJğ·¿ÃOj YÇ÷Sğ³kzőõmĝ[³¡VÙæÅöM̳¹pÁaËýý©D©ÜJŹƕģGą¤{Ùū
ÇO²«BƱéAÒĥ¡«BhlmtÃPµyU¯ucd·w_bŝcīímGOGBȅŹãĻFŷŽŕ@Óoo¿ē±ß}}ÓF÷tIJWÈCőâUâǙIğʼn©IijE×
Á³AĥDĈ±ÌÜÓĨ£L]ĈÙƺZǾĆĖMĸĤfÎĵlŨnÈĐtFFĤêk¶^k°f¶g}®Faf`vXŲxl¦ÔÁ²¬Ð¦pqÊ̲iXØRDÎ}Ä@ZĠsx®AR~®ETtĄZƈfŠŠHâÒÐAµ\\S¸^wĖkRzalŜ|E¨ÈNĀňZTpBh£\\ĎƀuXĖtKL¶G|»ĺEļĞ~ÜĢÛĊrOÙîvd]n¬VÊĜ°RÖpMƀ¬HbwEÀ©\\
¤]ŸI®¥D³|Ë]CúAЦ
æ´¥¸Lv¼¢ĽBaôF~®²GÌÒEYzk¤°ahlVÕI^CxĈPsBƒºVÀB¶¨R²´D","@@OR"]],"encodeOffsets":[[[117381,22988],[116552,22934],[116790,22617],[116973,22545],[116444,22536],[116931,22515],[116496,22490],[116453,22449],[113301,21439],[118726,21604],[118709,21486],[113210,20816],[115482,22082],[113171,21585],[113199,21590],[115232,22102],[115739,22373],[115134,22184],[113056,21175],[119573,21271],[119957,24020],[115859,22356],[116680,26053],[116561,22649]]]},"properties":{"cp":[113.280637,23.125178],"name":"广东","childNum":24}},{"id":"450000","geometry":{"type":"MultiPolygon","coordinates":[["@@H TI¡U","@@Ɣ_LÊFZg
čPkini«qÇczÍY®¬Ů»qR×ō©DÕ§ƙǃŵTÉĩ±ıdÑnYYIJvNĆĆØÜ Öp}e³¦m©iÓ|¹ħņ|ª¦QF¢Â¬ʖovg¿em^ucäāmÇÖåB¡Õçĝ}FϼĹ{µHKsLSđƃrč¤[AgoSŇYMÿ§Ç{FśbkylQxĕ]T·¶[B
ÑÏGáşşƇe
ăYSsFQ}BwtYğÃ@~
CÍQ ×Wj˱rÉ¥oÏ ±«ÓÂ¥kwWűue_bE~µh¯ecl¯Ïr¯EģJğ}w³Ƈē`ãògK_ÛsUʝćğ¶höO¤Ǜn³c`¡yię[ďĵűMę§]XÎ_íÛ]éÛUćİÕBƣ±
dy¹T^dûÅÑŦ·PĻþÙ`K¦
¢ÍeĥR¿³£[~äu¼dltW¸oRM¢ď\\z}Æzdvň{ÎXF¶°Â_ÒÂÏL©ÖTmu¼ãlīkiqéfA·Êµ\\őDc¥ÝFyÔćcűH_hLÜêĺШc}rn`½Ì@¸¶ªVLhŒ\\Ţĺk~Ġið°|gtTĭĸ^xvKVGréAébUuMJVÃO¡
qĂXËSģãlýà_juYÛÒBG^éÖ¶§EGÅzěƯ¤EkN[kdåucé¬dnYpAyČ{`]þ±X\\ÞÈk¡ĬjàhÂƄ¢Hè ŔâªLĒ^Öm¶ħĊAǦė¸zÚGn£¾rªŀÜt¬@ÖÚSx~øOŒŶÐÂæȠ\\ÈÜObĖw^oÞLf¬°bI lTØBÌF£Ć¹gñĤaYt¿¤VSñK¸¤nM¼JE±½¸ñoÜCƆæĪ^ĚQÖ¦^f´QüÜÊz¯lzUĺš@ìp¶n]sxtx¶@~ÒĂJb©gk{°~c°`Ô¬rV\\la¼¤ôá`¯¹LCÆbxEræOv[H[~|aB£ÖsºdAĐzNÂðsÞÆ
Ĥªbab`ho¡³F«èVZs\\\\ÔRzpp®SĪº¨ÖºN
ijd`a¦¤F³¢@`¢ĨĀìhYvlĆº¦Ċ~nS|gźv^kGÆÀè·"]],"encodeOffsets":[[[111707,21520],[113706,26955]]]},"properties":{"cp":[108.320004,22.82402],"name":"广西","childNum":2}},{"id":"460000","geometry":{"type":"Polygon","coordinates":["@@¦Ŝil¢XƦƞòïè§ŞCêɕrŧůÇąĻõ·ĉ³œ̅kÇm@ċȧŧĥĽʉƅſȓÒ˦ŝE}ºƑ[ÍĜȋ gÎfǐÏĤ¨êƺ\\Ɔ¸ĠĎvʄȀоjNðĀÒRZdžzÐĊ¢DÀɘZ"],"encodeOffsets":[[112750,20508]]},"properties":{"cp":[110.33119,20.031971],"name":"海南","childNum":1}},{"id":"510000","geometry":{"type":"MultiPolygon","coordinates":[["@@LqSn","@@ĆOìÛÐ@ĞǔNY{¤Á§d
i´ezÝúØãwIþËQǦÃqÉSJ»ĂéʔõÔƁİlƞ¹§ĬqtÀƄmÀêErĒtD®ċæcQE®³^ĭ¥©l}äQtoŖÜqÆkµªÔĻĴ¡@Ċ°B²Èw^^RsºT£ڿQPJvÄz^Đ¹Æ¯fLà´GC²dtĀRt¼¤ĦOðğfÔðDŨŁĞƘïPÈ®âbMüÀXZ ¸£@Å»»QÉ]dsÖ×_Í_ÌêŮPrĔĐÕGĂeZÜîĘqBhtO ¤tE[h|YÔZśÎs´xº±Uñt|OĩĠºNbgþJy^dÂY Į]Řz¦gC³R`Āz¢Aj¸CL¤RÆ»@Ŏk\\Ç´£YW}z@Z}öoû¶]´^NÒ}èNªPÍy¹`S°´ATeVamdUĐwʄvĮÕ\\uÆŗ¨Yp¹àZÂmWh{á}WØǍÉüwga§ßAYrÅÂQĀÕ¬LŐý®Xøxª½Ű¦¦[þ`ÜUÖ´òrÙŠ°²ÄkijnDX{U~ET{ļº¦PZcjF²Ė@pg¨B{u¨ŦyhoÚD®¯¢ WòàFΤ¨GDäz¦kŮPġqË¥À]eâÚ´ªKxīPÖ|æ[xäJÞĥsNÖ½I¬nĨY´®ÐƐmDŝuäđđEb
ee_v¡}ìęNJē}qÉåT¯µRs¡M@}ůaa¯wvƉåZw\\Z{åû`[±oiJDŦ]ĕãïrG réÏ·~ąSfy×Í·ºſƽĵȁŗūmHQ¡Y¡®ÁÃ×t«T¤JJJyJÈ`Ohߦ¡uËhIyCjmÿw
ZG
TiSsOB²fNmsPa{M{õE^Hj}gYpaeu¯oáwHjÁ½M¡pMuåmni{fk\\oÎqCwEZ¼KĝAy{m÷LwO×SimRI¯rKõBS«sFe]fµ¢óY_ÆPRcue°Cbo×bd£ŌIHgtrnyPt¦foaXďxlBowz_{ÊéWiêEGhܸºuFĈIxf®Y½ĀǙ]¤EyF²ċw¸¿@g¢§RGv»áW`ÃĵJwi]t¥wO½a[×]`ÃiüL¦LabbTÀåc}ÍhÆh®BHî|îºÉk¤Sy£ia©taį·Ɖ`ō¥UhO
ĝLk}©Fos´JmµlŁu
ønÑJWΪYÀïAetTŅÓGË«bo{ıwodƟ½OġܵxàNÖ¾P²§HKv¾]|BÆåoZ`¡Ø`ÀmºĠ~ÌЧnÇ
¿¤]wğ@srğu~Io[é±¹ ¿ſđÓ@qg¹zƱřaí°KtǤV»Ã[ĩǭƑ^ÇÓ@áťsZÏÅĭƋěpwDóÖáŻneQËq·GCœýS]x·ýq³OÕ¶Qzßti{řáÍÇWŝŭñzÇWpç¿JXĩè½cFÂLiVjx}\\NŇĖ¥GeJA¼ÄHfÈu~¸Æ«dE³ÉMA|bÒ
ćhG¬CMõƤąAvüVéŀ_V̳ĐwQj´·ZeÈÁ¨X´Æ¡Qu·»ÕZ³ġqDoy`L¬gdp°şp¦ėìÅĮZ°Iähzĵf²å ĚÑKpIN|Ñz]ń
·FU×é»R³MÉ»GM«kiér}Ã`¹ăÞmÈnÁîRǀ³ĜoİzŔwǶVÚ£À]ɜ»ĆlƂ²Ġ
þTº·àUȞÏʦ¶I«dĽĢdĬ¿»Ĕ×h\\c¬ä²GêëĤł¥ÀǿżÃÆMº}BÕĢyFVvwxBèĻĒ©Ĉt@Ğû¸£B¯¨ˋäßkķ½ªôNÔ~t¼Ŵu^s¼{TA¼ø°¢İªDè¾Ň¶ÝJ®Z´ğ~Sn|ªWÚ©òzPOȸbð¢|øĞA"]],"encodeOffsets":[[[108815,30935],[100197,35028]]]},"properties":{"cp":[104.065735,30.659462],"name":"四川","childNum":2}},{"id":"520000","geometry":{"type":"MultiPolygon","coordinates":[["@@G\\lY£cj","@@q|mc¯vÏV","@@hÑ£IsNgßHHªķÃh_¹¡ĝħń¦uÙùgS¯JH|sÝÅtÁïyMDč»eÕtA¤{b\\}G®u\\åPFqwÅaD
K°ºâ_£ùbµmÁÛĹM[q|hlaªāI}ѵ@swtwm^oµD鼊yVky°ÉûÛR
³e¥]RÕěħ[ƅåÛDpJiVÂF²I
»mN·£LbÒYbWsÀbpkiTZĄă¶Hq`
ĥ_J¯ae«KpÝx]aĕÛPÇȟ[ÁåŵÏő÷Pw}TÙ@Õs«ĿÛq©½m¤ÙH·yǥĘĉBµĨÕnđ]K©œáGçş§ÕßgǗĦTèƤƺ{¶ÉHÎd¾ŚÊ·OÐjXWrãLyzÉAL¾ę¢bĶėy_qMĔąro¼hĊw¶øV¤w²Ĉ]ÊKx|`ź¦ÂÈdrcÈbe¸`I¼čTF´¼Óýȃr¹ÍJ©k_șl³´_pĐ`oÒh¶pa^ÓĔ}D»^Xy`d[Kv
JPhèhCrĂĚÂ^Êƌ wZLĠ£ÁbrzOIlMMĪŐžËr×ÎeŦtw|¢mKjSǘňĂStÎŦEtqFT¾E쬬ôxÌO¢ K³ŀºäYPVgŎ¦Ŋm޼VZwVlz¤
£Tl®ctĽÚó{GAÇge~Îd¿æaSba¥KKûj®_Ä^\\ؾbP®¦x^sxjĶI_Ä Xâ¼Hu¨Qh¡À@Ëô}±GNìĎlT¸
`V~R°tbÕĊ`¸úÛtÏFDu[MfqGH·¥yAztMFe|R_GkChZeÚ°tov`xbDnÐ{E}ZèxNEÞREn[Pv@{~rĆAB§EO¿|UZ~ìUf¨J²ĂÝÆsªB`s¶fvö¦Õ~dÔq¨¸º»uù[[§´sb¤¢zþF¢Æ
ÀhÂW\\ıËIÝo±ĭŠ£þÊs}¡R]ěDg´VG¢j±®èºÃmpU[Á뺰rÜbNu¸}º¼`niºÔXĄ¤¼ÔdaµÁ_Ã
ftQQgR·Ǔv}Ý×ĵ]µWc¤F²OĩųãW½¯K©
]{LóµCIµ±Mß¿h©āq¬o½~@i~TUxð´ĐhwÀEîôuĶb[§nWuMÆJl½]vuıµb"]],"encodeOffsets":[[[112158,27383],[112105,27474],[112095,27476]]]},"properties":{"cp":[106.713478,26.578343],"name":"贵州","childNum":3}},{"id":"530000","geometry":{"type":"Polygon","coordinates":["@@[ùx½}ÑRHYīĺûsÍniEoã½Ya²ė{c¬ĝgĂsAØÅwďõzFjw}«Dx¿}Uũlê@HÅF¨ÇoJ´Ónũuą¡Ã¢pÒÅØ TF²xa²ËXcÊlHîAßËŁkŻƑŷÉ©hWæßUËs¡¦}teèÆ¶StÇÇ}Fd£jĈZĆÆ¤Tč\\D}O÷£U§~ŃGåŃDĝ¸Tsd¶¶Bª¤u¢ŌĎo~t¾ÍŶÒtD¦ÚiôözØX²ghįh½Û±¯ÿm·zR¦Ɵ`ªŊÃh¢rOÔ´£Ym¼èêf¯ŪĽncÚbw\\zlvWªâ ¦gmĿBĹ£¢ƹřbĥkǫßeeZkÙIKueT»sVesbaĕ ¶®dNĄÄpªy¼³BE®lGŭCǶwêżĔÂepÍÀQƞpC¼ŲÈAÎô¶RäQ^Øu¬°_Èôc´¹ò¨P΢hlϦ´ĦÆ´sâÇŲPnÊD^¯°Upv}®BP̪jǬxSöwlfòªvqĸ|`HviļndĜĆhňem·FyÞqóSᝳX_ĞçêtryvL¤§z¦c¦¥jnŞklD¤øz½ĜàĂŧMÅ|áƆàÊcðÂFÜáŢ¥\\\\ºİøÒÐJĴîD¦zK²ǏÎEh~CDhMn^ÌöÄ©ČZÀaüfɭyœpį´ěFűk]Ôě¢qlÅĆÙa¶~ÄqêljN¬¼HÊNQ´ê¼VظE^ŃÒyM{JLoÒęæe±Ķygã¯JYÆĭĘëo¥Šo¯hcK«z_prC´ĢÖY¼ v¸¢RÅW³Â§fǸYi³xR´ďUË`êĿUûuĆBƣöNDH«ĈgÑaB{ÊNF´¬c·Åv}eÇÃGB»If¦HňĕM
~[iwjUÁKE¾dĪçWIèÀoÈXòyŞŮÈXâÎŚj|àsRyµÖPr´þ ¸^wþTDŔHr¸RÌmfżÕâCôoxĜƌÆĮÐYtâŦÔ@]ÈǮƒ\\μģUsȯLbîƲŚºyhr@ĒÔƀÀ²º\\êpJ}ĠvqtĠ@^xÀ£È¨mËÏğ}n¹_¿¢×Y_æpÅA^{½Lu¨GO±Õ½ßM¶wÁĢÛPƢ¼pcIJx|ap̬HÐŊSfsðBZ¿©XÏÒKk÷Eû¿S
rEFsÕūkóVǥʼniTL¡n{uxţÏhôŝ¬ğōNNJkyPaqÂğ¤K®YxÉƋÁ]āęDqçgOgILu\\_gz]W¼~CÔē]bµogpÑ_oď`´³Țkl`IªºÎȄqÔþ»E³ĎSJ»_f·adÇqÇc¥Á_Źw{L^ɱćxU£µ÷xgĉp»ĆqNē`rĘzaĵĚ¡K½ÊBzyäKXqiWPÏɸ½řÍcÊG|µƕƣGË÷k°_^ý|_zċBZocmø¯hhcæ\\lMFlư£ĜÆyHF¨µêÕ]HA
àÓ^it `þßäkĤÎT~Wlÿ¨ÔPzUCNVv [jâôDôď[}z¿msSh¯{jïğl}šĹ[őgK©U·µË@¾m_~q¡f¹
ÅË^»f³ø}Q¡Ö˳gͱ^Ç
\\ëÃA_¿bWÏ[¶ƛé£F{īZgm@|kHǭƁć¦UĔť×ëǟ
eċ¼ȡȘÏíBÉ£āĘPªij¶ʼnÿy©nď£G¹¡I±LÉĺÑdĉÜW¥}gÁ{aqÃ¥aıęÏZÁ`"],"encodeOffsets":[[104636,22969]]},"properties":{"cp":[102.712251,25.040609],"name":"云南","childNum":1}},{"id":"540000","geometry":{"type":"Polygon","coordinates":["@@ÂhľxŖxÒVºÅâAĪÝȆµę¯Ňa±r_w~uSÕňqOj]ɄQ
£Z
UDûoY»©M[L¼qãË{VÍçWVi]ë©Ä÷àyƛhÚU°adcQ~Mx¥caÛcSyFÖkuRýq¿ÔµQĽ³aG{¿FµëªéĜÿª@¬·K·àariĕĀ«V»ŶĴūgèLǴŇƶaftèBŚ£^âǐÝ®M¦ÁǞÿ¬LhJ¾óƾƺcxwf]Y
´¦|QLn°adĊ
\\¨oǀÍŎ´ĩĀd`tÊQŞŕ|¨C^©Ĉ¦¦ÎJĊ{ëĎjª²rÐl`¼Ą[t|¦Stè¾PÜK¸dƄı]s¤î_v¹ÎVòŦj£Əsc¬_Ğ´|٦Av¦w`ăaÝaa¢e¤ı²©ªSªÈMĄwÉØŔì@T¤Ę\\õª@þo´xA sÂtŎKzó²Çȵ¢r^nĊƬ×üG¢³ {âĊ]G~bÀgVjzlhǶfOfdªB]pjTOtĊn¤}®¦Č¥d¢¼»ddY¼t¢eȤJ¤}Ǿ¡°§¤AÐlc@ĝsªćļđAçwxUuzEÖġ~AN¹ÄÅȀݦ¿ģŁéì±H
ãd«g[ؼēÀcīľġ¬cJµ
ÐʥVȝ¸ßS¹ý±ğkƁ¼ą^ɛ¤Ûÿb[}¬ōõÃ]ËNm®g@Bg}ÍF±ǐyL¥íCIijÏ÷Ñį[¹¦[âšEÛïÁÉdƅß{âNÆāŨß¾ě÷yC£k´ÓH@¹TZ¥¢į·ÌAЧ®Zc
v½Z¹|ÅWZqgW|ieZÅYVÓqdqbc²R@c¥Rã»GeeƃīQ}J[ÒK
¬Ə|oėjġĠÑN¡ð¯EBčnwôɍėª²CλŹġǝʅįĭạ̃ūȹ]ΓͧgšsgȽóϧµǛęgſ¶ҍć`ĘąŌJÞä¤rÅň¥ÖÁUětęuůÞiĊÄÀ\\Æs¦ÓRb|Â^řÌkÄŷ¶½÷f±iMÝ@ĥ°G¬ÃM¥n£Øąğ¯ß§aëbéüÑOčk£{\\eµª×MÉfm«Ƒ{Å×Gŏǩãy³©WÑăû··Qòı}¯ãIéÕÂZ¨īès¶ZÈsæĔTŘvgÌsN@îá¾ó@ÙwU±ÉT廣TđWxq¹Zobs[ׯcĩvėŧ³BM|¹kªħ¥TzNYnÝßpęrñĠĉRS~½ěVVµõ«M££µBĉ¥áºae~³AuĐh`ܳç@BÛïĿa©|z²Ý¼D£àč²ŸIûI āóK¥}rÝ_Á´éMaň¨~ªSĈ½½KÙóĿeƃÆB·¬ën×W|Uº}LJrƳlŒµ`bÔ`QÐÓ@s¬ñIÍ@ûws¡åQÑßÁ`ŋĴ{ĪTÚÅTSijYo|Ç[ǾµMW¢ĭiÕØ¿@Mh
pÕ]jéò¿OƇĆƇpêĉâlØwěsǩĵ¸c
bU¹ř¨WavquSMzeo_^gsÏ·¥Ó@~¯¿RiīB\\qTGªÇĜçPoÿfñòą¦óQīÈáPābß{ZŗĸIæÅhnszÁCËìñÏ·ąĚÝUm®óL·ăUÈíoù´Êj°ŁŤ_uµ^°ìÇ@tĶĒ¡ÆM³Ģ«İĨÅ®ğRāðggheÆ¢zÊ©Ô\\°ÝĎz~ź¤PnMĪÖB£kné§żćĆKǰ¼L¶èâz¨u¦¥LDĘz¬ýÎmĘd¾ßFzhg²Fy¦ĝ¤ċņbÎ@yĄæm°NĮZRÖíJ²öLĸÒ¨Y®ƌÐVàtt_ÚÂyĠz]ŢhzĎ{ÂĢXc|ÐqfO¢¤ögÌHNPKŖUú´xx[xvĐCûĀìÖT¬¸^}Ìsòd´_KgžLĴ
ÀBon|H@Êx¦BpŰŌ¿fµƌA¾zLjRx¶FkĄźRzŀ~¶[´HnªVƞuĒȨƎcƽÌm¸ÁÈM¦x͊ëÀxdžBú^´W£dkɾĬpw˂ØɦļĬIŚÊnŔa¸~J°îlɌxĤÊÈðhÌ®gT´øàCÀ^ªerrƘd¢İP|Ė ŸWªĦ^¶´ÂLaT±üWƜǀRÂŶUńĖ[QhlLüAÜ\\qRĄ©"],"encodeOffsets":[[90849,37210]]},"properties":{"cp":[91.132212,29.660361],"name":"西藏","childNum":1}},{"id":"610000","geometry":{"type":"Polygon","coordinates":["@@¸ÂW¢xRFq§uF@N¢XLRMº[ğȣſï|¥Jkc`sʼnǷ£Y³WN«ùMëï³ÛIg÷±mTșÚÒķø©þ¥yÓğęmWµÎumZyOŅƟĥÓ~sÑL¤µaÅ
Y¦ocyZ{y c]{Ta©`U_Ěē£ωÊƍKùK¶ȱÝƷ§{û»ÅÁȹÍéuij|¹cÑdìUYOuFÕÈYvÁCqÓTǢí§·S¹NgV¬ë÷Át°DدC´ʼnƒópģ}ąiEË
FéGU¥×K
§¶³BČ}C¿åċ`wġB·¤őcƭ²ő[Å^axwQO
ñJÙïŚĤNĔwƇÄńwĪo[_KÓª³ÙnKÇěÿ]ďă_d©·©Ýŏ°Ù®g]±ß×¥¬÷m\\iaǑkěX{¢|ZKlçhLtŇîŵœè[É@ƉĄEtƇϳħZ«mJ
×¾MtÝĦ£IwÄå\\Õ{OwĬ©LÙ³ÙTª¿^¦rÌĢŭO¥lãyC§HÍ£ßEñX¡°ÙCgpťzb`wIvA|¥hoĕ@E±iYd¥OÿµÇvPW|mCĴŜǂÒW¶¸AĜh^Wx{@¬F¸¡ķn£P|ªĴ@^ĠĈæbÔc¶lYi
^MicϰÂ[ävï¶gv@ÀĬ·lJ¸sn|¼u~a]ÆÈtŌºJpþ£KKf~¦UbyäIĺãnÔ¿^ŵMThĠܤko¼Ŏìąǜh`[tRd²IJ_XPrɲlXiL§à¹H°Ȧqº®QCbAŌJ¸ĕÚ³ĺ§ `d¨YjiZvRĺ±öVKkjGȊÄePĞZmļKÀ[`ösìhïÎoĬdtKÞ{¬èÒÒBÔpIJÇĬJŊ¦±J«[©ārHµàåVKe§|P²ÇÓ·vUzgnN¾yI@oHĆÛķhxen¡QQ±ƝJǖRbzy¸ËÐl¼EºpĤ¼x¼½~Ğà@ÚüdK^mÌSjp²ȮµûGĦ}Ħðǚ¶òƄjɂz°{ºØkÈęâ¦jªBg\\ċ°s¬]jú EȌdž¬stRÆdĠİwܸôW¾ƮłÒ_{Ìû¼jº¹¢GǪÒ¯ĘZ`ºŊecņą~BÂgzpâēòYƲȐĎ"],"encodeOffsets":[[113634,40474]]},"properties":{"cp":[108.948024,34.263161],"name":"陕西","childNum":1}},{"id":"620000","geometry":{"type":"MultiPolygon","coordinates":[["@@Vu_^","@@ųEĠtt~nkh`Q¦ÅÄÜdwAb×ĠąJ¤DüègĺqBqj°lI¡Ĩ¶ĖIHdjÎB°aZ¢KJO[|A£Dx}NìHUnrk kp¼Y kMJn[aGáÚÏ[½rc}aQxOgsPMnUsncZ
sKúvAtÞġ£®ĀYKdnFw¢JE°Latf`¼h¬we|Æbj}GA·~W`¢MC¤tL©IJ°qdfObÞĬ¹ttu`^ZúE`[@Æsîz®¡CƳƜG²R¢RmfwĸgÜą G@pzJM½mhVy¸uÈÔO±¨{LfæU¶ßGĂq\\ª¬²I¥IʼnÈīoıÓÑAçÑ|«LÝcspīðÍg
të_õ\\ĉñLYnĝgRǡÁiHLlõUĹ²uQjYi§Z_c¨´ĹĖÙ·ŋI
aBDR¹ȥr¯GºßK¨jWkɱOqWij\\aQ\\sg_ĆǛōëp»£lğÛgSŶN®À]ÓämĹãJaz¥V}Le¤Lýo¹IsŋÅÇ^bz
³tmEÁ´a¹cčecÇNĊãÁ\\č¯dNj]jZµkÓdaćå]ğij@ ©O{¤ĸm¢E·®«|@Xwg]A챝XǁÑdzªcwQÚŝñsÕ³ÛV_ý¥\\ů¥©¾÷w©WÕÊĩhÿÖÁRo¸V¬âDb¨hûxÊ×nj~Zâg|XÁnßYoº§ZÅŘv[ĭÖʃuďxcVbnUSf
B¯³_TzºÎO©çMÑ~M³]µ^püµÄY~y@X~¤Z³[Èōl@®Å¼£QK·Di¡ByÿQ_´D¥hŗy^ĭÁZ]cIzýah¹MĪğPs{ò²Vw¹t³ŜË[Ñ}X\\gsF£sPAgěp×ëfYHāďÖqēŭOÏëdLü\\it^c®Rʺ¶¢H°mrY£B¹čIoľu¶uI]vģSQ{UŻÅ}QÂ|̰ƅ¤ĩŪU ęĄÌZÒ\\v²PĔ»ƢNHĂyAmƂwVm`]ÈbH`Ì¢²ILvĜH®¤Dlt_¢JJÄämèÔDëþgºƫaʎÌrêYi~ ÎݤNpÀA¾Ĕ¼b
ð÷®üszMzÖĖQdȨýv§Tè|ªHþa¸|Ð ƒwKĢx¦ivr^ÿ ¸l öæfƟĴ·PJv}n\\h¹¶v·À|\\ƁĚN´ĜçèÁz]ġ¤²¨QÒŨTIlªťØ}¼˗ƦvÄùØE«FïËIqōTvāÜŏíÛßÛVj³âwGăÂíNOPìyV³ʼnĖýZso§HÑiYw[ß\\X¦¥c]ÔƩÜ·«jÐqvÁ¦m^ċ±R¦ƈťĚgÀ»IïĨʗƮ°ƝĻþÍAƉſ±tÍEÕÞāNUÍ¡\\ſčåÒʻĘm ƭÌŹöʥëQ¤µÇcƕªoIýIÉ_mkl³ăƓ¦j¡YzŇi}Msßõīʋ }ÁVm_[n}eıUĥ¼ªI{ΧDÓƻėojqYhĹT©oūĶ£]ďxĩǑMĝq`B´ƃ˺Чç~²ņj@¥@đ´ί}ĥtPńǾV¬ufÓÉCtÓ̻
¹£G³]ƖƾŎĪŪĘ̖¨ʈĢƂlɘ۪üºňUðǜȢƢż̌ȦǼĤŊɲĖÂKqĘʼn¼ĔDzņɾªǀÞĈĂD½ĄĎÌŗĞrôñnN¼â¾ʄľԆ|DŽ֦ज़ȗlj̘̭ɺƅêgV̍ʆĠ·ÌĊv|ýĖÕWĊǎÞ´õ¼cÒÒBĢ͢UĜð͒s¨ňƃLĉÕÝ@ɛƯ÷¿ĽĹeȏijëCȚDŲyê×Ŗyò¯ļcÂßY
tÁƤyAã˾J@ǝrý@¤
rz¸oP¹ɐÚyáHĀ[Jw
cVeȴÏ»ÈĖ}ƒŰŐèȭǢόĀƪÈŶë;Ñ̆ȤМľĮEŔĹŊũ~ËUă{ĻƹɁύȩþĽvĽƓÉ@ēĽɲßǐƫʾǗĒpäWÐxnsÀ^ƆwW©¦cÅ¡Ji§vúF¶¨c~c¼īeXǚ\\đ¾JwÀďksãAfÕ¦L}waoZD½Ml«]eÒÅaɲáo½FõÛ]ĻÒ¡wYR£¢rvÓ®y®LFLzĈôe]gx}|KK}xklL]c¦£fRtív¦PŨ£","@@M T¥"]],"encodeOffsets":[[[108619,36299],[108594,36341],[108600,36306]]]},"properties":{"cp":[103.823557,36.058039],"name":"甘肃","childNum":3}},{"id":"630000","geometry":{"type":"MultiPolygon","coordinates":[["@@InJo","@@CƽOŃĦsΰ~dz¦@@Ņi±è}ШƄ˹A³r_ĞǒNĪĐw¤^ŬĵªpĺSZgrpiƼĘÔ¨C|ÍJ©Ħ»®VIJ~f\\m `UnÂ~ʌĬàöNt~ňjy¢ZiƔ¥Ąk´nl`JÊJþ©pdƖ®È£¶ìRʦźõƮËnʼėæÑƀĎ[¢VÎĂMÖÝÎF²sƊƀÎBļýƞ¯ʘƭðħ¼Jh¿ŦęΌƇ¥²Q]Č¥nuÂÏri¸¬ƪÛ^Ó¦d¥[Wà
x\\ZjÒ¨GtpþYŊĕ´zUOëPîMĄÁxH´áiÜUàîÜŐĂÛSuŎrJð̬EFÁú×uÃÎkrĒ{V}İ«O_ÌËĬ©ÓŧSRѱ§Ģ£^ÂyèçěM³Ƃę{[¸¿u
ºµ[gt£¸OƤĿéYõ·kĀq]juw¥DĩƍõÇPéĽG©ã¤G
uȧþRcÕĕNyyûtøï»a½ē¿BMoį£Íj}éZËqbʍƬh¹ìÿÓAçãnIáI`ks£CGěUy×Cy
@¶ʡÊBnāzGơMē¼±O÷õJËĚăVĪũƆ£¯{ËL½ÌzżVR|ĠTbuvJvµhĻĖHAëáa
OÇðñęNw
œľ·LmI±íĠĩPÉ×®ÿscB³±JKßĊ«`
ađ»·QAmOVţéÿ¤¹SQt]]Çx±¯A@ĉij¢Óļ©l¶ÅÛrŕspãRk~¦ª]Į´FRådČsCqđéFn¿ÅƃmÉx{W©ºƝºįkÕƂƑ¸wWūЩÈF£\\tÈ¥ÄRÈýÌJ lGr^×äùyÞ³fjc¨£ÂZ|ǓMĝÏ@ëÜőRĝ÷¡{aïȷPu°ËXÙ{©TmĠ}Y³ÞIňµç½©C¡į÷¯B»|St»]vųs»}MÓ ÿʪƟǭA¡fs»PY¼c¡»¦cċ¥£~msĉPSi^o©AecPeǵkgyUi¿h}aHĉ^|á´¡HØûÅ«ĉ®]m¡qċ¶±ÈyôōLÁstB®wn±ă¥HSòė£Së@לÊăxÇN©©T±ª£IJ¡fb®Þbb_Ą¥xu¥B{łĝ³«`dƐt¤ťiñÍUuºí`£^tƃIJc·ÛLO½sç¥Ts{ă\\_»kϱq©čiìĉ|ÍI¥ć¥]ª§D{ŝŖÉR_sÿc³ĪōƿΧp[ĉc¯bKmR¥{³Ze^wx¹dƽŽôIg §Mĕ ƹĴ¿ǣÜÍ]Ý]snåA{eƭ`ǻŊĿ\\ijŬűYÂÿ¬jĖqßb¸L«¸©@ěĀ©ê¶ìÀEH|´bRľÓ¶rÀQþvl®ÕETzÜdb hw¤{LRdcb¯ÙVgƜßzÃôì®^jUèXÎ|UäÌ»rK\\ªN¼pZCüVY¤ɃRi^rPŇTÖ}|br°qňb̰ªiƶGQ¾²x¦PmlŜ[Ĥ¡ΞsĦÔÏâ\\ªÚŒU\\f
¢N²§x|¤§xĔsZPòʛ²SÐqF`ªVÞŜĶƨVZÌL`¢dŐIqr\\oäõF礻Ŷ×h¹]ClÙ\\¦ďÌį¬řtTӺƙgQÇÓHţĒ´ÃbEÄlbʔC|CŮkƮ[ʼ¬ň´KŮÈΰÌζƶlðļATUvdTGº̼ÔsÊDÔveMg"]],"encodeOffsets":[[[105308,37219],[95370,40081]]]},"properties":{"cp":[101.778916,36.623178],"name":"青海","childNum":2}},{"id":"640000","geometry":{"type":"Polygon","coordinates":["@@KëÀęĞ«Oęȿȕı]ʼn¡åįÕÔ«ǴõƪĚQÐZhv K°öqÀÑS[ÃÖHƖčËnL]ûc
Ùß@ĝ¾}w»»oģF¹»kÌÏ·{zP§B¢íyÅt@@á]Yv_ssģ¼ißĻL¾ġsKD£¡N_
X¸}B~HaiÅf{«x»ge_bsKF¯¡IxmELcÿZ¤ĢÝsuBLùtYdmVtNmtOPhRw~bd
¾qÐ\\âÙH\\bImlNZ»loqlVmGā§~QCw¤{A\\PKNY¯bFkC¥sks_Ã\\ă«¢ħkJi¯rrAhĹûç£CUĕĊ_ÔBixÅÙĄnªÑaM~ħpOu¥sîeQ¥¤^dkKwlL~{L~hw^ófćKyEKzuÔ¡qQ¤xZÑ¢^ļöܾEp±âbÊÑÆ^fk¬
NC¾YpxbK~¥eÖäBlt¿Đx½I[ĒǙWf»Ĭ}d§dµùEuj¨IÆ¢¥dXªƅx¿]mtÏwßRĶX¢͎vÆzƂZò®ǢÌʆCrâºMÞzÆMÒÊÓŊZľr°Î®Ȉmª²ĈUªĚîøºĮ¦ÌĘk^FłĬhĚiĀ˾iİbjË"],"encodeOffsets":[[109366,40242]]},"properties":{"cp":[106.278179,38.46637],"name":"宁夏","childNum":1}},{"id":"650000","geometry":{"type":"Polygon","coordinates":["@@QØĔ²X¨~ǘBºjʐߨvKƔX¨vĊO÷¢i@~cĝe_«E}QxgɪëÏÃ@sÅyXoŖ{ô«ŸuX
êÎf`C¹ÂÿÐGĮÕĞXŪōŸMźÈƺQèĽôe|¿ƸJR¤ĘEjcUóº¯Ĩ_ŘÁMª÷Ð¥OéÈ¿ÖğǤǷÂFÒzÉx[]Ĥĝœ¦EP}ûƥé¿İƷTėƫœŕƅƱB»Đ±ēO
¦E}`cȺrĦáŖuÒª«IJπdƺÏØZƴwʄ¤ĖGĐǂZĶèH¶}ÚZצʥĪï|ÇĦMŔ»İĝLjì¥Βba¯¥ǕǚkĆŵĦɑĺƯxūД̵nơʃĽá½M»òmqóŘĝč˾ăC
ćāƿÝɽ©DZŅ»ēėŊLrÁ®ɱĕģʼnǻ̋ȥơŻǛȡVï¹Ň۩ûkɗġƁ§ʇė̕ĩũƽō^ƕUv£ƁQïƵkŏ½ΉÃŭdzLŇʻ«ƭ\\lŭD{ʓDkaFÃÄa³ŤđÔGRÈƚhSӹŚsİ«ĐË[¥ÚDkº^Øg¼ŵ¸£EÍöůʼnT¡c_ËKYƧUśĵÝU_©rETÏʜ±OñtYwē¨{£¨uM³x½şL©Ùá[ÓÐĥ Νtģ¢\\śnkOw¥±T»ƷFɯàĩÞáB¹Æ
ÑUwŕĽw]kE½Èå~Æ÷QyěCFmĭZīŵVÁƿQƛûXS²b½KϽĉS©ŷXĕ{ĕK·¥Ɨcqq©f¿]ßDõU³hgËÇïģÉɋwk¯í}I·œbmÉřīJɥĻˁ×xoɹīlc
¤³Xù]DžA¿w͉ì¥wÇN·ÂËnƾƍdǧđ®ƝvUm©³G\\}µĿQyŹlăµEwLJQ½yƋBe¶ŋÀůo¥AÉw@{Gpm¿AijŽKLh³`ñcËtW±»ÕSëüÿďDu\\wwwù³VLŕOMËGh£õP¡erÏd{ġWÁ
č|yšg^ğyÁzÙs`s|ÉåªÇ}m¢Ń¨`x¥ù^}Ì¥H«YªƅAйn~ź¯f¤áÀzgÇDIÔ´AňĀÒ¶ûEYospõD[{ù°]uJqU|Soċxţ[õÔĥkŋÞŭZ˺óYËüċrw ÞkrťË¿XGÉbřaDü·Ē÷Aê[ÄäI®BÕĐÞ_¢āĠpÛÄȉĖġDKwbmÄNôfƫVÉvidzHQµâFùœ³¦{YGd¢ĚÜO {Ö¦ÞÍÀP^bƾl[vt×ĈÍE˨¡Đ~´î¸ùÎhuè`¸HÕŔVºwĠââWò@{ÙNÝ´ə²ȕn{¿¥{l÷eé^eďXj©î\\ªÑòÜìc\\üqÕ[Č¡xoÂċªbØø|¶ȴZdÆÂońéG\\¼C°ÌÆn´nxÊOĨŪƴĸ¢¸òTxÊǪMīĞÖŲÃɎOvʦƢ~FRěò¿ġ~åŊúN¸qĘ[Ĕ¶ÂćnÒPĒÜvúĀÊbÖ{Äî¸~Ŕünp¤ÂH¾ĄYÒ©ÊfºmÔĘcDoĬMŬS¤s²ʘÚžȂVŦ èW°ªB|IJXŔþÈJĦÆæFĚêYĂªĂ]øªŖNÞüAfɨJ¯ÎrDDĤ`mz\\§~D¬{vJ«lµĂb¤pŌŰNĄ¨ĊXW|ų ¿¾ɄĦƐMTòP÷fØĶK¢ȝ˔Sô¹òEð`Ɩ½ǒÂň×äı§ĤƝ§C~¡hlåǺŦŞkâ~}FøàIJaĞfƠ¥Ŕd®U¸źXv¢aƆúŪtŠųƠjdƺƺÅìnrh\\ĺ¯äɝĦ]èpĄ¦´LƞĬ´ƤǬ˼Ēɸ¤rºǼ²¨zÌPðŀbþ¹ļD¢¹\\ĜÑŚ¶ZƄ³âjĦoâȴLÊȮĐĚăÀêZǚŐ¤qȂ\\L¢ŌİfÆs|zºeªÙæ§{Ā´ƐÚ¬¨Ĵà²łhʺKÞºÖTiƢ¾ªì°`öøu®Ê¾ãÖ"],"encodeOffsets":[[88824,50096]]},"properties":{"cp":[87.617733,43.792818],"name":"新疆","childNum":1}},{"id":"110000","geometry":{"type":"Polygon","coordinates":["@@RºaYÕQaúÍÔiþĩȨWĢü|Ėu[qb[swP@ÅğP¿{\\¯Y²·Ñ¨j¯X\\¯MSvU¯YIŕY{[fkVÁûtŷmiÍt_H»Ĩ±d`¹{bw
Yr³S]§§o¹qGtm_SŧoaFLgQN_dV@Zom_ć\\ßW´ÕiœRcfi
o§ËgToÛJíĔóu
|wP¤XnO¢ÉŦ¯pNÄā¤zâŖÈRpŢZÚ{GrFt¦Òx§ø¹RóäV¤XdżâºWbwڍUd®bêņ¾jnŎGŃŶnzÚScîĚZen¬"],"encodeOffsets":[[119421,42013]]},"properties":{"cp":[116.405285,39.904989],"name":"北京","childNum":1}},{"id":"120000","geometry":{"type":"Polygon","coordinates":["@@ŬgX§Ü«E
¶F̬O_ïlÁgz±AXeµÄĵ{¶]gitgIj·¥ì_iU¨ÐƎk}ĕ{gBqGf{¿aU^fIư³õ{YıëNĿk©ïËZukāAīlĕĥs¡bġ«@dekąI[nlPqCnp{ō³°`{PNdƗqSÄĻNNâyj]äÒD ĬH°Æ]~¡HO¾X}ÐxgpgWrDGpù^LrzWxZ^¨´T\\|~@IzbĤjeĊªz£®ĔvěLmV¾Ô_ÈNW~zbĬvG²ZmDM~~"],"encodeOffsets":[[120237,41215]]},"properties":{"cp":[117.190182,39.125596],"name":"天津","childNum":1}},{"id":"310000","geometry":{"type":"MultiPolygon","coordinates":[["@@ɧư¬EpƸÁx]","@@©²","@@MA","@@QpªKWT
§¨","@@bŝÕÕEȣÚƥêImɇǦèÜĠÚÄÓŴ·ʌÇ","@@Sô¤r]ìƬįǜûȬɋŭ×^sYɍDŋŽąñCG²«ªč@h_p¯A{oloY¬j@IJ`gQÚpptǀ^MIJvtbe´Rh@oj¨","@@ÆLH{a}Eo¦"]],"encodeOffsets":[[[124702,32062],[124547,32200],[124808,31991],[124726,32110],[124903,32376],[124065,32166],[124870,31965]]]},"properties":{"cp":[121.472644,31.231706],"name":"上海","childNum":7}},{"id":"500000","geometry":{"type":"Polygon","coordinates":["@@TÂÛ`Ùƅően½SêqDu[Rå͹÷eXÍy¸_ĺę}÷`M¯ċfCVµqʼn÷Zgg^d½pDOÎCn^uf²ènh¼WtƏxRGg¦
pVFI±G^Ic´ecGĹÞ½sëÆNä̤KÓe¯|R¸§LÜkPoïƭNï¶}Gywdiù©nkĈzj@Óc£»Wă¹Óf§c[µo·Ó|MvÛaq½«è\\ÂoVnÓØÍ²«bq¿ehCĜ^Q~ Évýş¤²ĮpEĶyhsŊwH½¿gÅ¡ýE¡ya£³t\\¨\\vú¹¼©·Ñr_oÒý¥et³]Et©uÖ¥±ă©KVeë]}wVPÀFA¨ąB}qTjgRemfFmQFÝ
MyùnÑAmÑCawu_p¯sfÛ_gI_pNysB¦zG¸rHeN\\CvEsÐñÚkcDÖĉsaQ¯}_UzÁē}^R Äd^ÍĸZ¾·¶`wećJE¹vÛ·HgéFXjÉê`|ypxkAwWĐpb¥eOsmzwqChóUQl¥F^lafanòsrEvfQdÁUVfÎvÜ^eftET¬ôA\\¢sJnQTjPØxøK|nBzĞ»LY
FDxÓvr[ehľvN¢o¾NiÂxGpâ¬zbfZo~hGi]öF||NbtOMn eA±tPTLjpYQ|SHYĀxinzDJÌg¢và¥Pg_ÇzIIII£®S¬Øs쥨^LnGIJļIJƤjÎƀƾ¹¸ØÎezĆT¸}êÐqHðqĖä¥^CÆIj²p
\\_ æüY|[YxƊæu°xb®
Űb@~¢NQt°¶Sæ Ê~rljĔëĚ¢~uf`faĔJåĊnÔ]jƎćÊ@£¾a®£Ű{ŶĕFègLk{Y|¡ĜWƔtƬJÑxq±ĢN´òKLÈüD|s`ŋć]Ã`đMùƱ¿~Y°ħ`ƏíW½eI½{aOIrÏ¡ĕŇapµÜƃġ²"],"encodeOffsets":[[111728,31311]]},"properties":{"cp":[106.504962,29.533155],"name":"重庆","childNum":1}},{"id":"810000","geometry":{"type":"MultiPolygon","coordinates":[["@@AlFi","@@mp","@@EpHo","@@rMUwAS¬]","@@ea¢pl¸Eõ¹hj[]ÔCÎ@lj¡uBX
´AI¹
[yDU]W`çwZkmc
MpÅv}IoJlcafŃK°ä¬XJmÐ đhI®æÔtSHnEÒrÄc"]],"encodeOffsets":[[[117111,23002],[117072,22876],[117045,22887],[116882,22747],[116975,23082]]]},"properties":{"cp":[114.173355,22.320048],"name":"香港","childNum":5}},{"id":"820000","geometry":{"type":"Polygon","coordinates":["@@áw{Îr"],"encodeOffsets":[[116285,22746]]},"properties":{"cp":[112.54909,22.198951],"name":"澳门","childNum":1}}],"UTF8Encoding":true});
- echarts.registerMap('china', {"type":"FeatureCollection","features":[{"id":"710000","geometry":{"type":"MultiPolygon","coordinates":[["@@°Ü¯Û","@@ƛĴÕƊÉɼģºðʀ\\ƎsÆNŌÔĚänÜƤɊĂǀĆĴĤNJŨxĚĮǂƺòƌâÔ®ĮXŦţƸZûÐƕƑGđ¨ĭMó·ęcëƝɉlÝƯֹÅŃ^Ó·śŃNjƏďíåɛGɉ¿IċããF¥ĘWǬÏĶñÄ","@@\\p|WoYG¿¥Ij@","@@
¡@V^RqBbAnTXeQr©C","@@ÆEEkWqë I"]],"encodeOffsets":[[[122886,24033],[123335,22980],[122375,24193],[122518,24117],[124427,22618]]]},"properties":{"cp":[121,24],"name":"台湾","childNum":5}},{"id":"130000","geometry":{"type":"MultiPolygon","coordinates":[["@@\\aM`ǽÓnUK
Ĝēs¤©yrý§uģcJ»eIP]ªrºc_ħ²G¼s`jΟnüsÂľP","@@U`Ts¿mÄ","@@FOhđ©OiÃ`ww^ÌkÑH«ƇǤŗĺtFu
{Z}Ö@U´
ʚLg®¯Oı°Ãw ^VbÉsmA
ê]]w§RRl£ŭuwNÁ`ÇFēÝčȻuT¡Ĺ¯Õ¯sŗő£YªhVƍ£ƅnëYNgq¼ś¿µı²UºÝUąąŖóxV@tƯJ]eR¾fe|rHA|h~Ėƍl§ÏjVë` ØoÅbbx³^zÃͶSj®AyÂhðk`«P˵EFÛ¬Y¨Ļrõqi¼Wi°§Ð±²°`[À|ĠO@ÆxO\\ta\\p_Zõ^û{ġȧXýĪÓjùÎRb^λj{íděYfíÙTymńŵōHim½éŅaVcř§ax¹XŻácWU£ôãºQ¨÷Ñws¥qEHÙ|šYQoŕÇyáĂ£MðoťÊP¡mWO¡v{ôvîēÜISpÌhp¨ jdeŔQÖjX³àĈ[n`Yp@UcM`RKhEbpŞlNut®EtqnsÁgAiúoHqCXhfgu~ÏWP½¢G^}¯ÅīGCÑ^ãziMáļMTÃƘrMc|O_¯Ŏ´|morDkO\\mĆJfl@c̬¢aĦtRıÒXòë¬WP{ŵǫƝ
īÛ÷ąV×qƥV¿aȉd³BqPBmaËđŻģmÅ®V¹d^KKonYg¯XhqaLdu¥ÍpDž¡KąÅkĝęěhq}HyÃ]¹ǧ£
Í÷¿qágPmoei¤o^á¾ZEY^
Ný{nOl±Í@Mċèk§daNaÇį¿]øRiiñEūiDZàUtėGyl}ÓM}jpEC~¡FtoQiHkk{ILgĽxqÈƋÄdeVDJj£J|ÅdzÂFt~KŨ¸IÆv|¢r}èonb}`RÎÄn°ÒdÞ²^®lnÐèĄlðÓ×]ªÆ}LiñÖ`^°Ç¶p®đDcŋ`ZÔ¶êqvFÆN®ĆTH®¦O¾IbÐã´BĐɢŴÆíȦpĐÞXR·nndO¤OÀĈƒQgµFo|gȒęSWb©osx|hYhgŃfmÖĩnºTÌSp¢dYĤ¶UĈjlǐpäðëx³kÛfw²Xjz~ÂqbTÑěŨ@|oMzv¢ZrÃVw¬ŧˏf°ÐTªqs{S¯r æÝl¼ÖĞ džiGĘJ¼lr}~K¨ŸƐÌWö¼Þ°nÞoĦL|C~D©|q]SvKÑcwpÏÏĿćènĪWlĄkT}¬Tp~®Hgd˒ĺBVtEÀ¢ôPĎƗè@~kü\\rÊĔÖæW_§¼F´©òDòjYÈrbĞāøŀG{ƀ|¦ðrb|ÀH`pʞkvGpuARhÞÆǶgĘTǼƹS£¨¡ù³ŘÍ]¿ÂyôEP xX¶¹ÜO¡gÚ¡IwÃé¦ÅBÏ|ǰ
N«úmH¯âbęU~xĈbȒ{^xÖlD¸dɂ~"]],"encodeOffsets":[[[120023,41045],[121616,39981],[122102,42307]]]},"properties":{"cp":[115.5,38.5],"name":"河北","childNum":3}},{"id":"140000","geometry":{"type":"Polygon","coordinates":["@@ħÜ_ªlìwGkÛÃǏokćiµVZģ¡coTS˹ĪmnÕńehZg{gtwªpXaĚThȑp{¶Eh®RćƑP¿£PmcªaJyý{ýȥoÅîɡųAďä³aÏJ½¥PGąSMsWz½µÛYÓŖgxoOkĒCoȵ]¯_²ÕjāK~©ÅØ^ÔkïçămÏk]±cݯÑÃmQÍ~_apm
~ç¡qu{JÅŧ·Ls}EyÁÆcI{¤IiCfUcƌÃp§]ě«vD@¡SÀµMÅwuYY¡DbÑc¡h×]nkoQdaMç~eDÛtT©±@¥ù@É¡ZcW|WqOJmĩl«ħşvOÓ«IqăV¥D[mI~Ó¢cehiÍ]Ɠ~ĥqX·eƷn±}v[ěďŕ]_œ`¹§ÕōIo©bs^}Ét±ū«³p£ÿ¥WÑxçÁ«h×u×¥ř¾dÒ{ºvĴÎêÌɊ²¶ü¨|ÞƸµȲLLúÉƎ¤ϊęĔV`_bªS^|dzY|dz¥pZbÆ£¶ÒK}tĦÔņƠPYznÍvX¶Ěn ĠÔzý¦ª÷ÑĸÙUȌ¸dòÜJð´ìúNM¬XZ´¤ŊǸ_tldI{¦ƀðĠȤ¥NehXnYGR° ƬDj¬¸|CĞKqºfƐiĺ©ª~ĆOQª ¤@ìǦɌ²æBÊTĞHƘÁĪËĖĴŞȀÆÿȄlŤĒötνî¼ĨXh|ªM¤ÐzÞĩÒSrao³"],"encodeOffsets":[[117016,41452]]},"properties":{"cp":[112.3,37.5],"name":"山西","childNum":1}},{"id":"150000","geometry":{"type":"MultiPolygon","coordinates":[["@@ǪƫÌÛM
Ă[`ÕCn}¶Vc
ês¯PqFB
|S³C|kñHdiÄ¥sʼnÅ
PóÑÑE^ÅPpy_YtShQ·aHwsOnʼnÃs©iqjUSiº]ïW«gW¡ARëśijĘ
ů`çõh]y»ǃǛҤxÒm~zf}pf|ÜroÈzrKÈĵSƧżĠu~è¬vîS¼ĂhĖMÈÄw\\fŦ°W ¢¾luŸDw\\Ŗĝ","@@GVu»Aylßí¹ãe]Eāò³C¹ð¾²iÒAdkò^P²CǜңDŽ z¼g^èöŰ_IJĕê}gÁnUI«m
]jvV¼euhwqAaW_µj
»çjioQR¹ēÃßt@r³[ÛlćË^ÍÉáGOUÛOB±XkŹ£k|e]olkVͼÕqtaÏõjgÁ£§U^RLËnX°ÇBz^~wfvypV ¯ƫĉ˭ȫƗŷɿÿĿƑ˃ĝÿÃǃßËőó©ǐȍŒĖM×ÍEyxþp]ÉvïèvƀnÂĴÖ@V~Ĉ³MEĸÅĖtējyÄDXÄxGQuv_i¦aBçw˛wD©{tāmQ{EJ§KPśƘƿ¥@sCTÉ}ɃwƇy±gÑ}T[÷kÐ禫
SÒ¥¸ëBX½HáŵÀğtSÝÂa[ƣ°¯¦Pï¡]£ġÒk®G²èQ°óMq}EóƐÇ\\@áügQÍu¥FTÕ¿Jû]|mvāÎYua^WoÀa·ząÒot×¶CLƗi¯¤mƎHNJ¤îìɾŊìTdåwsRÖgĒųúÍġäÕ}Q¶¿A[¡{d×uQAMxVvMOmăl«ct[wº_ÇÊjb£ĦS_éQZ_lwgOiýe`YYJq¥IÁdz£ÙË[ÕªuƏ³ÍTs·bÁĽäė[b[ŗfãcn¥îC¿÷µ[ŏÀQōĉm¿Á^£mJVmL[{Ï_£F¥Ö{ŹA}
×Wu©ÅaųijƳhB{·TQqÙIķËZđ©Yc|M¡
LeVUóK_QWk_ĥ¿ãZ»X\\ĴuUèlG®ěłTĠğDŃGÆÍz]±
ŭ©Å]ÅÐ}UË¥©TċïxgckfWgi\\ÏĒ¥HkµEë{»ÏetcG±ahUiñiWsɁ·cCÕk]wȑ|ća}w
VaĚá G°ùnM¬¯{ÈÐÆA¥ÄêJxÙ¢hP¢ÛºµwWOóFÁz^ÀŗÎú´§¢T¤ǻƺSėǵhÝÅQgvBHouʝl_o¿Ga{ïq{¥|ſĿHĂ÷aĝÇqZñiñC³ª
»E`¨åXēÕqÉû[l}ç@čƘóO¿¡FUsAʽīccocÇS}£IS~ălkĩXçmĈ
ŀÐoÐdxÒuL^T{r@¢ÍĝKén£kQyÅõËXŷƏL§~}kq»IHėDžjĝ»ÑÞoå°qTt|r©ÏS¯·eŨĕx«È[eM¿yupN~¹ÏyN£{©għWí»Í¾səšDž_ÃĀɗ±ąijĉʍŌŷSÉA±åǥɋ@ë£R©ąP©}ĹªƏj¹erLDĝ·{i«ƫC½ÉshVz
GS|úþXgp{ÁX¿ć{ƱȏñZáĔyoÁhA}ŅĆfdʼn_¹Y°ėǩÑ¡H¯¶oMQqð¡Ë|Ñ`ƭŁX½·óÛxğįÅcQs«tȋDžFù^it«Č¯[hAi©á¥ÇĚ×l|¹y¯Kȝqgů{ñǙµïċĹzŚȭ¶¡oŽäÕG\\ÄT¿Òõr¯LguÏYęRƩɷŌO\\İТæ^Ŋ IJȶȆbÜGĝ¬¿ĚVĎgª^íu½jÿĕęjık@Ľ]ėl¥ËĭûÁėéV©±ćn©ȇÍq¯½YÃÔʼnÉNÑÅÝy¹NqáʅDǡËñƁYÅy̱os§ȋµʽǘǏƬɱàưN¢ƔÊuľýľώȪƺɂļxZĈ}ÌʼnŪĺœĭFЛĽ̅ȣͽÒŵìƩÇϋÿȮǡŏçƑůĕ~ǼȳÐUfdIxÿ\\G zâɏÙOº·pqy£@qþ@Ǟ˽IBäƣzsÂZÁàĻdñ°ŕzéØűzșCìDȐĴĺf®Àľưø@ɜÖÞKĊŇƄ§͑těï͡VAġÑÑ»d³öǍÝXĉĕÖ{þĉu¸ËʅğU̎éhɹƆ̗̮ȘNJ֥ड़ࡰţાíϲäʮW¬®ҌeרūȠkɬɻ̼ãüfƠSצɩςåȈHϚÎKdzͲOðÏȆƘ¼CϚǚ࢚˼ФÔ¤ƌĞ̪Qʤ´¼mȠJˀƲÀɠmɆDŽĜƠ´ǠN~ʢĜ¶ƌĆĘźʆȬ˪ĚǏĞGȖƴƀj`ĢçĶāàŃºēĢĖćYÀŎüôQÐÂŎŞdžŞêƖoˆDĤÕºÑǘÛˤ³̀gńƘĔÀ^ªƂ`ªt¾äƚêĦ¼ÐĔǎ¨Ȕ»͠^ˮÊȦƤøxRrŜH¤¸ÂxDÄ|ø˂˜ƮЬɚwɲFjĔ²Äw°dždÀÉ_ĸdîàŎjÊêTЪŌŜWÈ|tqĢUB~´°ÎFCU¼pĀēƄN¦¾O¶łKĊOjĚj´ĜYp{¦SĚÍ\\TתV÷Ší¨ÅDK°ßtŇĔK¨ǵÂcḷ̌ĚǣȄĽFlġUĵŇȣFʉɁMğįʏƶɷØŭOǽ«ƽū¹Ʊő̝Ȩ§ȞʘĖiɜɶʦ}¨֪ࠜ̀ƇǬ¹ǨE˦ĥªÔêFxúQEr´Wrh¤Ɛ \\talĈDJÜ|[Pll̚¸ƎGú´P¬W¦^¦H]prRn|or¾wLVnÇIujkmon£cX^Bh`¥V¦U¤¸}xRj[^xN[~ªxQ[`ªHÆÂExx^wN¶Ê|¨ìMrdYpoRzNyÀDs~bcfÌ`L¾n|¾T°c¨È¢ar¤`[|òDŞĔöxElÖdHÀI`Ď\\Àì~ÆR¼tf¦^¢ķ¶eÐÚMptgjɡČÅyġLûŇV®ÄÈƀϰP|ªVVªj¬ĚÒêp¬E|ŬÂ_~¼rƐK f{ĘFĒƌXưăkÃĄ}nµo×q£çkX{uĩ«āíÓUŅÝVUŌ]Ť¥lyň[oi{¦Lĸ
Ħ^ôâJ¨^UZðÚĒL¿Ìf£K£ʺoqNwğc`uetOj×°KJ±qÆġmĚŗos¬
qehqsuH{¸kH¡
ÊRǪÇƌbȆ¢´äÜ¢NìÉʖ¦â©Ɨؗ"]],"encodeOffsets":[[[128500,52752],[127089,51784]]]},"properties":{"cp":[110,41],"name":"内蒙古","childNum":2}},{"id":"210000","geometry":{"type":"MultiPolygon","coordinates":[["@@L@@s]","@@MnNm","@@dc","@@eÀC@b","@@f
XwkbrÄ`qg","@@^jtWQ","@@~ Y[c","@@I`ĖN^_¿ZÁM","@@Ïxnj{q_×^Gigp","@@iX¶B
Y","@@Y
Z","@@L_yG`b","@@^WqCTZ","@@\\[§t|]","@@m`p[","@@@é^BntaÊU]x ¯ÄPIJ°hʙK³VÕ@Y~|EvĹsǦL^pòŸÒG Ël]xxÄ_fT¤Ď¤cPC¨¸TVjbgH²sdÎdHt`B²¬GJję¶[ÐhjeXdlwhðSȦªVÊÏÆZÆŶ®²^ÎyÅHńĚDMħĜŁHkçvV[ij¼WYÀäĦ`XlR`ôLUVfK¢{NZdĒªYĸÌÚJRr¸SA|ƴgŴĴÆbvªØX~źB|¦ÕE¤Ð`\\|KUnnI]¤ÀÂĊnŎR®Ő¿¶\\ÀøíDm¦ÎbŨabaĘ\\ľã¸atÎSƐ´©v\\ÖÚÌǴ¤Â¨JKrZ_ZfjþhPkx`YRIjJcVf~sCN¤ EhæmsHy¨SðÑÌ\\\\ĐRÊwS¥fqŒßýáĞÙÉÖ[^¯ǤŲê´\\¦¬ĆPM¯£»uïpùzExanµyoluqe¦W^£ÊL}ñrkqWňûPUP¡ôJoo·U}£[·¨@XĸDXmÛݺGUCÁª½{íĂ^cjk¶Ã[q¤LÉö³cux«|Zd²BWÇ®Yß½ve±ÃCý£W{Ú^q^sÑ·¨ËMr¹·C¥GDrí@wÕKţëV·i}xËÍ÷i©ĝɝǡ]{c±OW³Ya±_ç©HĕoƫŇqr³Lys[ñ³¯OSďOMisZ±ÅFC¥Pq{Ã[Pg}\\¿ghćO
k^ĩÃXaĕËĥMoEqqZûěʼn³F¦oĵhÕP{¯~TÍlªNßYÐ{Ps{ÃVUeĎwk±ʼnVÓ½ŽJãÇÇ»Jm°dhcÀffdF~ĀeĖd`sx² ®EĦ¦dQÂd^~ăÔH¦\\LKpĄVez¤NP ǹÓRÆąJSha[¦´ÂghwmBШźhI|VV|p] ¼èNä¶ÜBÖ¼L`¼bØæKVpoúNZÞÒKxpw|ÊEMnzEQIZZNBčÚFÜçmĩWĪñtÞĵÇñZ«uD±|ƏlǗw·±PmÍada CLǑkùó¡³Ï«QaċÏOÃ¥ÕđQȥċƭy³ÁA"]],"encodeOffsets":[[[123686,41445],[126019,40435],[124393,40128],[126117,39963],[125322,40140],[126686,40700],[126041,40374],[125584,40168],[125509,40217],[125453,40165],[125362,40214],[125280,40291],[125774,39997],[125976,40496],[125822,39993],[122731,40949]]]},"properties":{"cp":[123.2,41.3],"name":"辽宁","childNum":16}},{"id":"220000","geometry":{"type":"Polygon","coordinates":["@@ñr½ÉKāGÁ¤ia Éȹ`\\xs¬dĆkNnuNUwNx¶c¸|\\¢
GªóĄ~RãÖÎĢùđŴÕhQxtcæëSɽʼníëlj£ƍG£nj°KƘµDsØÑpyƸ®¿bXp]vbÍZuĂ{n^IüÀSÖ¦EvRÎûh@â[ƏÈô~FNr¯ôçR±HÑlĢ^¤¢OðætxsŒ]ÞÁTĠs¶¿âÆGW¾ìA¦·TѬè¥ÏÐJ¨¼ÒÖ¼ƦɄxÊ~StD@Ă¼Ŵ¡jlºWvÐzƦZвCH AxiukdGgetqmcÛ£Ozy¥cE}|
¾cZ
k¿uŐã[oxGikfeäT@
SUwpiÚFM©£è^Ú`@v¶eňf heP¶täOlÃUgÞzŸU`l}ÔÆUvØ_Ō¬Öi^ĉi§²ÃB~¡ĈÚEgc|DC_Ȧm²rBx¼MÔ¦ŮdĨÃâYxƘDVÇĺĿg¿cwÅ\\¹¥Yĭl¤OvLjM_a W`zļMž·\\swqÝSAqŚij¯°kRē°wx^ĐkǂÒ\\]nrĂ}²ĊŲÒøãh·M{yMzysěnĒġV·°G³¼XÀ¤¹i´o¤ŃÈ`ÌDzÄUĞd\\iÖmÈBĤÜɲDEh LG¾ƀľ{WaYÍÈĢĘÔRîĐj}ÇccjoUb½{h§Ǿ{KƖµÎ÷GĄØŜçưÌs«lyiē«`å§H¥Ae^§GK}iã\\c]v©ģZmÃ|[M}ģTɟĵÂÂ`ÀçmFK¥ÚíÁbX³ÌQÒHof{]ept·GŋĜYünĎųVY^ydõkÅZW«WUa~U·SbwGçǑiW^qFuNĝ·EwUtW·Ýďæ©PuqEzwAVXRãQ`©GY
YhcUGorBd}ģÉb¡·µMicF«Yƅ»
é\\ɹ~ǙG³mØ©BšuT§Ĥ½¢Ã_ýL¡ûsT\\rke\\PnwAKy}ywdSefµ]UhĿD@mÿvaÙNSkCun
cÿ`lWėVâ¦÷~^fÏ~vwHCį`xqTlW«ï¸skmßEGqd¯R
©Ý¯¯S\\cZ¹iűƏCuƍÓXoR}M^o£
R}oªUF
uuXHlEÅÏ©¤ßgXþ¤D²ÄufàÀXXȱAc{Yw¬dvõ´KÊ£\\rµÄlidā]|DÂVH¹Þ®ÜWnCķ W§@\\¸~¤Vp¸póIO¢VOŇürXql~òÉK]¤¥Xrfkvzpm¶bwyFoúv𼤠N°ąO¥«³[éǣű]°Õ\\ÚÊĝôîŇÔaâBYlďQ[ Ë[ïÒ¥RI|`j]P"],"encodeOffsets":[[126831,44503]]},"properties":{"cp":[126,43.7],"name":"吉林","childNum":1}},{"id":"230000","geometry":{"type":"MultiPolygon","coordinates":[["@@UµNÿ¥īèçHÍøƕ¶Lǽ|g¨|a¾pVidd~ÈiíďÓQġėÇZÎXb½|ſÃH½KFgɱCģÛÇAnjÕc[VĝDZÃËÇ_ £ń³pj£º¿»WH´¯U¸đĢmtĜyzzNN|g¸÷äűѱĉā~mq^[ǁÑďlw]¯xQĔ¯l°řĴrBÞTxr[tޏĻN_yX`biNKu
P£kZĮ¦[ºxÆÀdhĹŀUÈƗCwáZħÄŭcÓ¥»NAw±qȥnD`{ChdÙFć}¢A±Äj¨]ĊÕjŋ«×`VuÓÅ~_kŷVÝyhVkÄãPsOµfgeŇ
µf@u_Ù ÙcªNªÙEojVxT@ãSefjlwH\\pŏäÀvlY½d{F~¦dyz¤PÜndsrhfHcvlwjF£G±DÏƥYyÏu¹XikĿ¦ÏqƗǀOŜ¨LI|FRĂn sª|C˜zxAè¥bfudTrFWÁ¹Am|ĔĕsķÆF´N}ć
UÕ@Áijſmuçuð^ÊýowFzØÎĕNőǏȎôªÌŒDŽàĀÄ˄ĞŀƒʀĀƘŸˮȬƬĊ°Uzouxe]}
AyÈW¯ÌmKQ]Īºif¸ÄX|sZt|½ÚUÎ lk^p{f¤lºlÆW A²PVÜPHÊâ]ÎĈÌÜk´\\@qàsĔÄQºpRij¼èi`¶bXrBgxfv»uUi^v~J¬mVp´£´VWrnP½ì¢BX¬hðX¹^TjVriªjtŊÄmtPGx¸bgRsT`ZozÆO]ÒFôÒOÆŊvÅpcGêsx´DR{AEOr°x|íb³Wm~DVjºéNNËܲɶGxŷCSt}]ûōSmtuÇÃĕNāg»íT«u}ç½BĵÞʣ¥ëÊ¡MÛ³ãȅ¡ƋaǩÈÉQG¢·lG|tvgrrf«ptęŘnÅĢrI²¯LiØsPf_vĠdxM prʹL¤¤eËÀđKïÙVY§]Ióáĥ]ķK¥j|pŇ\\kzţ¦šnņäÔVĂîά|vW®l¤èØrxm¶ă~lÄƯĄ̈́öȄEÔ¤ØQĄĄ»ƢjȦOǺ¨ìSŖÆƬyQv`cwZSÌ®ü±DŽ]ŀç¬B¬©ńzƺŷɄeeOĨSfm ĊƀP̎ēz©ĊÄÕÊmgÇsJ¥ƔŊśæÎÑqv¿íUOµªÂnĦÁ_½ä@êí
£P}Ġ[@gġ}gɊ×ûÏWXá¢užƻÌsNͽƎÁ§čŐAēeL³àydl¦ĘVçŁpśdžĽĺſÊQíÜçÛġÔsĕ¬Ǹ¯YßċġHµ ¡eå`ļrĉŘóƢFìĎWøxÊkƈdƬv|I|·©NqńRŀ¤éeŊŀàŀU²ŕƀBQ£Ď}L¹Îk@©ĈuǰųǨÚ§ƈnTËÇéƟÊcfčŤ^XmHĊĕË«W·ċëx³ǔķÐċJāwİ_ĸȀ^ôWr°oú¬Ħ
ŨK~ȰCĐ´Ƕ£fNÎèâw¢XnŮeÂÆĶ¾¾xäLĴĘlļO¤ÒĨA¢Êɚ¨®ØCÔ ŬGƠƦYĜĘÜƬDJg_ͥœ@čŅĻA¶¯@wÎqC½Ĉ»NăëKďÍQÙƫ[«ÃígßÔÇOÝáWñuZ¯ĥŕā¡ÑķJu¤E 寰WKɱ_d_}}vyõu¬ï¹ÓU±½@gÏ¿rýDg
Cdµ°MFYxw¿CG£Rƛ½Õ{]L§{qqą¿BÇƻğëܭNJË|c²}Fµ}ÙRsÓpg±QNqǫŋRwŕnéÑÉK«SeYR
ŋ@{¤SJ}D Ûǖ֍]gr¡µŷjqWÛham³~S«Ü[","@@ƨĶTLÇyqpÇÛqe{~oyen}s`qiXGù]Ëp½©lÉÁp]Þñ´FĂ^fäîºkàz¼BUv¬D"]],"encodeOffsets":[[[134456,44547],[127123,51780]]]},"properties":{"cp":[127.8,46.8],"name":"黑龙江","childNum":2}},{"id":"320000","geometry":{"type":"Polygon","coordinates":["@@Õg^vÁbnÀ`Jnĝ¬òM¶ĘTÖŒbe¦¦{¸ZâćNp©Hp|`mjhSEb\\afv`sz^lkljÄtg¤D¾X¿À|ĐiZȀåB·î}GL¢õcßjayBFµÏC^ĭcÙt¿sğH]j{s©HM¢QnDÀ©DaÜÞ·jgàiDbPufjDk`dPOîhw¡ĥ¥GP²ĐobºrYî¶aHŢ´ ]´rılw³r_{£DB_Ûdåuk|Ũ¯F Cºyr{XFye³Þċ¿ÂkĭB¿MvÛpm`rÚã@ƹhågËÖƿxnlč¶Åì½Ot¾dJlVJĂǀŞqvnO^JZż·Q}êÍÅmµÒ]ƍ¦Dq}¬R^èĂ´ŀĻĊIÔtIJyQŐĠMNtR®òLhĚs©»}OÓGZz¶A\\jĨFäOĤHYJvÞHNiÜaĎÉnFQlNM¤B´ĄNöɂtpŬdZÅglmuÇUšŞÚb¤uŃJŴu»¹ĄlȖħŴw̌ŵ²ǹǠ͛hĭłƕrçü±Yrřl¥i`ã__¢ćSÅr[Çq^ùzWmOĈaŐÝɞï²ʯʊáĘijĒǭPħ͍ôƋÄÄÍīçÛɈǥ£ÛmY`ó£Z«§°Ó³QafusNıDž_k}¢m[ÝóDµ¡RLčiXyÅNïă¡¸iĔÏNÌķoıdōîåŤûHcs}~Ûwbù¹£¦ÓCtOPrE^ÒogĉIµÛÅʹK
¤½phMú`mR¸¦PƚgÉLRs`£¯ãhD¨|³¤C"],"encodeOffsets":[[121451,32518]]},"properties":{"cp":[120,32.4],"name":"江苏","childNum":1}},{"id":"330000","geometry":{"type":"MultiPolygon","coordinates":[["@@jX^n
","@@sfdM","@@qP\\xz[_i","@@o\\VzRZ}mECy","@@R¢FX}°[m]","@@Cb\\}","@@e|v\\laus","@@v~s{","@@QxÂF©}","@@¹nvÞs©m","@@rQgYIh","@@bi«ZX","@@p[}ILd","@@À¿|","@@¹dnb
","@@rS}[Kl","@@g~h}","@@FlCk","@@ůTG°ĄLHm°UF","@@OdRe","@@v[u\\","@@FjâL~wyoo~sµLZ","@@¬e¹aH","@@\\nÔ¡q]L³ë\\ÿ®QÌ","@@ÊA©]ª","@@Kxv{","@@@hlIk_","@@pWcrxp","@@Md|_iA","@@¢
X£½z\\ðpN","@@hlÜ[LykAvyfw^E ","@@fp¤MusH","@@®_ma~LÁ¬`","@@@°¡mÛGĕ¨§Ianá[ýƤjfæÐNäGp","@@iMt\\","@@Zc[b","@@X®±GrưZæĉm","@@Z~dOSo|A¿qZv","@@@`EN£p","@@|s","@@@nDi","@@n
a£¾uYL¯Qª
mĉÅdMgÇjcº«ę¬K´B«Âącoċ\\xK`cįŧ«®á[~ıxu·ÅKsËÉc¢Ù\\ĭƛëbf¹ģSĜkáƉÔĈZB{aMµfzʼnfÓÔŹŁƋǝÊĉ{ğč±g³ne{çií´S¬\\ßðK¦w\\iqªĭiAuAµ_W¥ƣO\\lċĢttC¨£t`PZäuXßBsĻyekOđġĵHuXBµ]×\\°®¬F¢¾pµ¼kŘó¬Wät¸|@L¨¸µrºù³Ù~§WIZW®±Ð¨ÒÉx`²pĜrOògtÁZ{üÙ[|ûKwsPlU[}¦Rvn`hsª^nQ´ĘRWb_ rtČFIÖkĦPJ¶ÖÀÖJĈĄTĚòC ²@Pú
Øz©PCÈÚDZhŖl¬â~nm¨f©iļ«mntqÒTÜÄjL®EÌFª²iÊxبIÈhhst[Ôx}dtüGæţŔïĬaĸpMËÐj碷ðĄÆMzjWKĎ¢Q¶À_ê_@ıi«pZgf¤Nrq]§ĂN®«H±yƳí¾×ŊďŀĐÏŴǝĂíÀBŖÕªÁŐTFqĉ¯³ËCĕģi¨hÜ·ñt»¯Ï","@@ºwZRkĕWK "]],"encodeOffsets":[[[125785,31436],[125729,31431],[125513,31380],[125329,30690],[125223,30438],[125115,30114],[124815,29155],[124419,28746],[124095,28635],[124005,28609],[125000,30713],[125111,30698],[125078,30682],[125150,30684],[124014,28103],[125008,31331],[125411,31468],[125329,31479],[125369,31139],[125626,30916],[125417,30956],[125254,30976],[125199,30997],[125095,31058],[125083,30915],[124885,31015],[125218,30798],[124867,30838],[124755,30788],[124802,30809],[125267,30657],[125218,30578],[125200,30562],[125192,30787],[124968,30474],[125167,30396],[125115,30363],[124955,29879],[124714,29781],[124762,29462],[124325,28754],[124863,30077],[125366,31477]]]},"properties":{"cp":[120,29.2],"name":"浙江","childNum":43}},{"id":"340000","geometry":{"type":"MultiPolygon","coordinates":[["@@^iuLV\\","@@e©Edh","@@´CE¶zAXêeödK¡~H¸íæAȽd{ďÅÀ½W®£ChÃsikkly]_teu[bFaTign{]GqªoĈMYá|·¥f¥őaSÕėNµñĞ«Im_m¿Âa]uĜp
Z_§{Cäg¤°r[_YjÆOdý[I[á·¥Q_nùgL¾mzˆDÜÆ¶ĊJhpc¹O]iŠ]¥ jtsggDÑ¡w×jÉ©±EFËKiÛÃÕYv
sm¬njĻª§emná}k«ŕgđ²ÙDÇ¤í¡ªOy×Où±@DñSęćăÕIÕ¿IµĥOlJÕÍRÍ|JìĻÒåyķrĕq§ÄĩsWÆßF¶X®¿mw
RIÞfßoG³¾©uyHį{Ɓħ¯AFnuP
ÍÔzVdàôº^Ðæd´oG¤{S¬ćxã}ŧ×Kǥĩ«ÕOEзÖdÖsƘѨ[Û^Xr¢¼§xvÄÆµ`K§ tÒ´Cvlo¸fzŨð¾NY´ı~ÉĔē
ßúLÃÃ_ÈÏ|]ÂÏHlg`ben¾¢pUh~ƴ˶_r sĄ~cƈ]|r c~`¼{À{ȒiJjz`îÀT¥Û³
]u}f
ïQl{skloNdjäËzDvčoQďHI¦rbrHĖ~BmlNRaĥTX\\{fÁKÁ®TLÂÄMtÊgĀDĄXƔvDcÎJbt[¤D@®hh~kt°ǾzÖ@¾ªdbYhüóV´ŮŒ¨Üc±r@J|àuYÇÔG·ĚąĐlŪÚpSJ¨ĸLvÞcPæķŨ®mÐálsgd×mQ¨ųƩޤIÎs°KZpĄ|XwWdϵmkǀwÌÕæhºgBĝâqÙĊzÖgņtÀÁĂÆáhEz|WzqD¹°Eŧl{ævÜcA`¤C`|´qxIJkq^³³GšµbíZ
¹qpa±ď OH¦Ħx¢gPícOl_iCveaOjCh߸iÝbÛªCC¿mRV§¢A|tbkĜEÀtîm^g´fÄ"]],"encodeOffsets":[[[121722,32278],[119475,30423],[121606,33646]]]},"properties":{"cp":[117.2,31.5],"name":"安徽","childNum":3}},{"id":"350000","geometry":{"type":"MultiPolygon","coordinates":[["@@zht´}[","@@aj^~ĆGå","@@edH
se","@@@vPGsyQ","@@sBzddW[O","@@S¨Qy","@@NVucW","@@qptB@q","@@¸[iu","@@Q\\pD[_","@@jSwUappI","@@eXª~","@@AjvFoo","@@fT_Çí\\v|ba¦jZÆy|®","@@IjLg","@@wJIx«¼AoNe{M¥","@@K±¡ÓČ~N¾","@@k¡¹Eh~c®uDqZì¡I~Māe£bN¨gZý¡a±Öcp©PhI¢Qq
ÇGj|¥U g[Ky¬ŏv@OptÉEF\\@ åA¬V{XģĐBy
cpě
¼³Ăp·¤¥ohqqÚ¡ŅLs^á§qlÀhH¨MCe»åÇGD¥zPO£čÙkJA¼ßėuĕeûÒiÁŧS[¡Uûŗ½ùěcݧSùĩąSWó«íęACµeRåǃRCÒÇZÍ¢ź±^dlstjD¸ZpuÔâÃH¾oLUêÃÔjjēò´ĄWƛ
^Ñ¥Ħ@ÇòmOw¡õyJyD}¢ďÑÈġfZda©º²z£NjD°Ötj¶¬ZSÎ~¾c°¶ÐmxO¸¢Pl´SL|¥AȪĖMņIJg®áIJČĒü` QF¬h|ĂJ@zµ |ê³È ¸UÖŬŬÀCtrĸr]ðM¤ĶIJHtÏ AĬkvsq^aÎbvdfÊòSD´Z^xPsĂrvƞŀjJd×ŘÉ ®AΦĤdxĆqAZRÀMźnĊ»İÐZ YXæJyĊ²·¶q§·K@·{sXãô«lŗ¶»o½E¡«¢±¨Y®Ø¶^AvWĶGĒĢPlzfļtàAvWYãO_¤sD§ssČġ[kƤPX¦`¶®BBvĪjv©jx[L¥àï[F
¼ÍË»ğV`«Ip}ccÅĥZEãoP
´B@D¸m±z«Ƴ¿å³BRضWlâþäą`]Z£Tc ĹGµ¶Hm@_©k¾xĨôȉðX«½đCIbćqK³ÁÄš¬OAwã»aLʼnËĥW[ÂGIÂNxij¤D¢îĎÎB§°_JGs¥E@
¤uć
PåcuMuw¢BI¿]zG¹guĮI"]],"encodeOffsets":[[[123250,27563],[122541,27268],[123020,27189],[122916,27125],[122887,26845],[122808,26762],[122568,25912],[122778,26197],[122515,26757],[122816,26587],[123388,27005],[122450,26243],[122578,25962],[121255,25103],[120987,24903],[122339,25802],[121042,25093],[122439,26024]]]},"properties":{"cp":[118.2,26],"name":"福建","childNum":18}},{"id":"360000","geometry":{"type":"Polygon","coordinates":["@@ÖP¬ǦĪØLŨä~Ĉw«|TH£pc³Ïå¹]ĉđxe{ÎÓvOEm°BƂĨİ|Gvz½ª´HàpeJÝQxnÀWEµàXÅĪt¨ÃĖrÄwÀFÎ|Ă¡WÕ¸cf¥XaęST±m[r«_gmQu~¥V\\OkxtL E¢Ú^~ýØkbēqoě±_Êw§Ñ²ÏƟė¼mĉŹ¿NQ
YBąrwģcÍ¥BŗÊcØiIƝĿuqtāwO]³YCñTeÉcaubÍ]trluī
BÐGsĵıN£ï^ķqsq¿DūūVÕ·´Ç{éĈýÿOER_đûIċâJhŅıNȩĕB
¦K{Tk³¡OP·wnµÏd¯}½TÍ«YiµÕsC¯iM¤¦¯P|ÿUHvhe¥oFTuõ\\OSsMòđƇiaºćXĊĵà·çhƃ÷Ç{ígu^đgm[ÙxiIN¶Õ»lđÕwZSÆv©_ÈëJbVkĔVÀ¤P¾ºÈMÖxlò~ªÚàGĂ¢B±ÌKyñ`w²¹·
`gsÙfIěxŕeykpudjuTfb·hh¿Jd[\\LáƔĨƐAĈepÀÂMD~ņªe^\\^§ý©j×cZبzdÒa¶lÒJìõ`oz÷@¤u޸´ôęöY¼HČƶajlÞƩ¥éZ[|h}^U ¥pĄžƦO lt¸Æ Q\\aÆ|CnÂOjtĚĤdÈF`¶@Ðë ¦ōÒ¨SêvHĢÛ@[Æ
QoxHW[ŰîÀt¦DŽ~NĠ¢lĄtZoCƞÔºCxrpČNpj¢{f_Y`_eq®Aot`@oDXfkp¨|s¬\\DÄSfè©Hn¬
^DhÆyøJhØxĢĀLÊƠPżċĄwĮ¶"],"encodeOffsets":[[118923,30536]]},"properties":{"cp":[115.7,28],"name":"江西","childNum":1}},{"id":"370000","geometry":{"type":"MultiPolygon","coordinates":[["@@Xjd]mE","@@itnq","@@Dl@k","@@TGw","@@K¬U","@@Wd`c","@@PtMs","@@LnXlc","@@ppVu]Qn","@@cdzAU_","@@udRhnCE
","@@oIpP","@@M{ĿčwbxƨîKÎMĮ]ZF½Y]â£ph¶¨râøÀÎǨ¤^ºÄGz~grĚĜlĞÆLĆdž¢Îo¦cvKbgr°WhmZp L]LºcUÆnżĤÌĒbAnrOA´ȊcÀbƦUØrĆUÜøĬƞŶǬĴóò_Ä«ªdÎÉnb²ĦhņBĖįĦåXćì@L¯´ywƕCéõė ƿ¸lµZæyj|BíÂKNNnoƈfÈMZwnŐNàúÄsTJULîVjǎ¾ĒØDz²XPn±ŴPè¸ŔLƔÜƺ_TüÃĤBBċÈöA´faM¨{«M`¶d¡ôÖ°mȰBÔjj´PM|c^d¤u¤Û´ä«ƢfPk¶Môl]Lb}su^ke{lC
MrDÇ]NÑFsmoõľHyGă{{çrnÓEƕZGª¹Fj¢ÿ©}ÌCǷë¡ąuhÛ¡^KxC`C\\bÅxì²ĝÝ¿_NīCȽĿåB¥¢·IŖÕy\\¹kxãČáKµË¤ÁçFQ¡KtŵƋ]CgÏAùSedcÚźuYfyMmhUWpSyGwMPqŀÁ¼zK¶GY§Ë@´śÇµƕBm@IogZ¯uTMx}CVKï{éƵP_K«pÛÙqċtkkù]gTğwoɁsMõ³ăAN£MRkmEÊčÛbMjÝGu
IZGPģãħE[iµBEuDPÔ~ª¼ęt]ûG§¡QMsğNPŏįzs£Ug{đJĿļā³]ç«Qr~¥CƎÑ^n¶ÆéÎR~ݏYI] PumŝrƿIā[xedzL¯v¯s¬ÁY
~}
ťuŁgƋpÝĄ_ņī¶ÏSR´ÁP~¿Cyċßdwk´SsX|t`Ä ÈðAªìÎT°¦Dda^lĎDĶÚY°`ĪŴǒàŠv\\ebZHŖR¬ŢƱùęOÑM³FÛaj"]],"encodeOffsets":[[[123806,39303],[123821,39266],[123742,39256],[123702,39203],[123649,39066],[123847,38933],[123580,38839],[123894,37288],[123043,36624],[123344,38676],[123522,38857],[123628,38858],[118267,36772]]]},"properties":{"cp":[117.5,36.3],"name":"山东","childNum":13}},{"id":"410000","geometry":{"type":"MultiPolygon","coordinates":[["@@dXD}~Hgq~ÔN~zkĘHVsDzßjŬŢ`Pûàl¢\\ÀEhİgÞē X¼`khÍLùµP³swIÓzeŠĠð´E®ÚPtºIŊʺL«šŕQGYfa[şußǑĩų_Z¯ĵÙčC]kbc¥CS¯ëÍB©ïÇÃ_{sWTt³xlàcČzÀD}ÂOQ³ÐTĬµƑпŸghłŦv~}ÂZ«¤lPÇ£ªÝŴÅR§ØnhctâknÏľŹUÓÝdKuķI§oTũÙďkęĆH¸Ó\\Ä¿PcnS{wBIvÉĽ[GqµuŇôYgûZca©@½Õǽys¯}lgg@C\\£asIdÍuCQñ[L±ęk·ţb¨©kK»KC²òGKmĨS`UQnk}AGēsqaJ¥ĐGRĎpCuÌy ã iMcplk|tRkðev~^´¦ÜSí¿_iyjI|ȑ|¿_»d}q^{Ƈdă}tqµ`ŷ飩V¡om½ZÙÏÁRD|JOÈpÀRsI{ùÓjuµ{t}uËRivGçJFjµåkWê´MÂHewixGw½Yŷpµú³XU½ġyłåkÚwZX·l¢Á¢KzOÎÎjc¼htoDHr
|J½}JZ_¯iPq{tę½ĕ¦Zpĵø«kQ
Ť]MÛfaQpě±ǽ¾]uFu÷nčįADp}AjmcEÇaª³o³ÆÍSƇĈÙDIzçñİ^KNiÞñ[aA²zzÌ÷D|[íijgfÕÞd®|`Ć~oĠƑô³ŊD×°¯CsøÂ«ìUMhTº¨¸ǝêWÔDruÂÇZ£ĆPZW~ØØv¬gèÂÒw¦X¤Ā´oŬ¬²Ês~]®tªapŎJ¨Öº_ŔfŐ\\Đ\\Ĝu~m²Ƹ¸fWĦrƔ}Î^gjdfÔ¡J}\\n C¦þWxªJRÔŠu¬ĨĨmFdM{\\d\\YÊ¢ú@@¦ª²SÜsC}fNècbpRmlØ^gd¢aÒ¢CZZxvƶN¿¢T@uC¬^ĊðÄn|lIlXhun[","@@hzUq"]],"encodeOffsets":[[[116744,37216],[116480,33048]]]},"properties":{"cp":[113.6,34],"name":"河南","childNum":2}},{"id":"420000","geometry":{"type":"MultiPolygon","coordinates":[["@@ASd","@@ls{d","@@¾«}{ra®pîÃ\\{øCËyyB±b\\òÝjKL ]ĎĽÌJyÚCƈćÎT´Å´pb©ÈdFin~BCo°BĎÃømv®E^vǾ½Ĝ²RobÜeN^ĺ£R¬lĶ÷YoĖ¥Ě¾|sOr°jY`~I¾®I{GqpCgyl{£ÍÍyPL¡¡¸kWxYlÙæŁĢz¾V´W¶ùŸo¾ZHxjwfxGNÁ³Xéæl¶EièIH ujÌQ~v|sv¶Ôi|ú¢FhQsğ¦SiŠBgÐE^ÁÐ{čnOÂÈUÎóĔÊēIJ}Z³½Mŧïeyp·uk³DsѨL¶_Åuèw»¡WqÜ]\\Ò§tƗcÕ¸ÕFÏǝĉăxŻČƟOKÉġÿ×wg÷IÅzCg]m«ªGeçÃTC«[t§{loWeC@ps_Bprf_``Z|ei¡oċMqow¹DƝÓDYpûsYkıǃ}s¥ç³[§cY§HK«Qy]¢wwö¸ïx¼ņ¾Xv®ÇÀµRĠÐHM±cÏdƒǍũȅȷ±DSyúĝ£ŤĀàtÖÿï[îb\\}pĭÉI±Ñy
¿³x¯No|¹HÏÛmjúË~TuęjCöAwě¬Rđl¯ ÑbŇTĿ_[IčĄʿnM¦ğ\\É[T·k¹©oĕ@A¾wya¥Y\\¥Âaz¯ãÁ¡k¥ne£ÛwE©Êō¶˓uoj_U¡cF¹[WvP©whuÕyBF`RqJUw\\i¡{jEPïÿ½fć
QÑÀQ{°fLÔ~wXgītêݾĺHd³fJd]HJ²
EoU¥HhwQsƐ»Xmg±çve]DmÍPoCc¾_hhøYrŊU¶eD°Č_N~øĹĚ·`z]Äþp¼
äÌQv\\rCé¾TnkžŐÚÜa¼ÝƆ̶Ûo
d
ĔňТJqPb ¾|J¾fXƐîĨ_Z¯À}úƲN_ĒÄ^ĈaŐyp»CÇÄKñL³ġM²wrIÒŭxjb[n«øæà ^²h¯ÚŐªÞ¸Y²ĒVø}Ā^İ´LÚm¥ÀJÞ{JVųÞŃx×sxxƈē ģMřÚðòIfĊŒ\\Ʈ±ŒdʧĘDvČ_Àæ~Dċ´A®µ¨ØLV¦êHÒ¤"]],"encodeOffsets":[[[113712,34000],[115612,30507],[113649,34054]]]},"properties":{"cp":[113,31],"name":"湖北","childNum":3}},{"id":"430000","geometry":{"type":"MultiPolygon","coordinates":[["@@nFZw","@@ãÆá½ÔXrCO
ËRïÿĩTooQyÓ[ŅBE¬ÎÓXaį§Ã¸G °ITxpúxÚij¥Ï̾edÄ©ĸG
àGhM¤Â_U}Ċ}¢pczfþg¤ÇôAV","@@ȴÚĖÁĐiOĜ«BxDõĚivSÌ}iùÜnкG{p°M°yÂÒzJ²Ì ÂcXëöüiáÿñőФùTz²CȆȸǎŪƑÐc°dPÎğ˶[Ƚu¯½WM¡ÉB·rínZÒ `¨GA¾\\pēXhÃRCüWGġu
Té§ŎÑ©êLM³}_EÇģc®ęisÁPDmÅ{b[RÅs·kPŽƥóRoOV~]{g\\êYƪ¦kÝbiċƵGZ»Ěõ
ó·³vŝ£ø@pyö_ëIkѵbcѧy
×dYتiþUjҳC}ÁN»hĻħƏâƓKA·³CQ±µ§¿AUƑ¹AtćOwD]JUÖgk¯b£ylZFËѱH}EbóľA¡»Ku¦·³åş¥ùBD^{ÌC´¦ŷJ£^[ª¿ğ|ƅ
N
skóā¹¿ï]ă~÷O§@Vm¡Qđ¦¢Ĥ{ºjÔª¥nf´~Õo×ÛąGû¥cÑ[Z¶ŨβSÊǔƐƀAÚŌ¦Qؼrŭ«}NÏürʬmjr@ĘrTW SsdHzƓ^ÇÂyUi¯DÅYlŹu{hT}mĉ¹¥ěDÿë©ıÓ[Oº£¥ótł¹MÕƪ`P
DiÛU¾ÅâìUñBÈ£ýhedy¡oċ`pfmjP~kZa
ZsÐd°wj§@Ĵ®w~^kÀÅKvNmX\\¨aŃqvíó¿F¤¡@ũÑVw}S@j}¾«pĂrªg àÀ²NJ¶¶Dô
K|^ª°LX¾ŴäPα£EXd^¶IJÞÜ~u¸ǔMRhsR
e`ÄofIÔ\\Ø ićymnú¨cj ¢»GČìƊÿШXeĈ¾Oð Fi ¢|[jVxrIQ_EzAN¦zLU`cªxOTu RLĪpUĪȴ^ŎµªÉFx
Üf¤ºgIJèy°Áb[¦Zb¦z½xBĖ@ªpºjS´rVźOd©ʪiĎăJP`"]],"encodeOffsets":[[[115640,30489],[112577,27316],[114113,30649]]]},"properties":{"cp":[112,28],"name":"湖南","childNum":3}},{"id":"440000","geometry":{"type":"MultiPolygon","coordinates":[["@@QdAsa","@@lxDRm","@@sbhNLo","@@Ă ý","@@WltOY[","@@Kr]S","@@e~AS}","@@I|Mym","@@Û³LS²Q","@@nvºBë¥cÕº","@@zdÛJm","@@°³","@@a yAª¸ËJIxØ@ĀHÉÕZofo
o","@@sŗÃÔėAƁZÄ ~°ČPºb","@@¶ÝÌvmĞh¹Ĺ","@@HdSjĒ¢D}war
u«ZqadY{K","@@el\\LqqO","@@~rMmX","@@f^E","@@øPªoj÷ÍÝħXČx°Q¨ıXJp","@@gÇƳmxatfu","@@EÆC½","@@¸B_¶ekWvSivc}p}Ăº¾NĎyj¦Èm th_®Ä}»âUzL˲Aā¡ßH©Ùñ}wkNÕ¹ÇO½¿£ēUlaUìIǪ`uTÅxYĒÖ¼kÖµMjJÚwn\\hĒv]îh|ÈƄøèg¸Ķß ĉĈWb¹ƀdéĘNTtP[öSvrCZaGubo´ŖÒÇĐ~¡zCI
özx¢PnÈñ @ĥÒ¦]ƜX³ăĔñiiÄÓVépKG½ÄÓávYoC·sitiaÀyŧΡÈYDÑům}ý|m[węõĉZÅxUO}÷N¹³ĉo_qtăqwµŁYÙǝŕ¹tïÛUïmRCº
ĭ|µÕÊK½Rē ó]GªęAxNqSF|ām¡diď×YïYWªʼnOeÚtĐ«zđ¹T
āúEáÎÁWwíHcòßÎſ¿Çdğ·ùT×Çūʄ¡XgWÀLJğ·¿ÃOj YÇ÷Sğ³kzőõmĝ[³¡VÙæÅöM̳¹pÁaËýý©D©ÜJŹƕģGą¤{Ùū
ÇO²«BƱéAÒĥ¡«BhlmtÃPµyU¯ucd·w_bŝcīímGOGBȅŹãĻFŷŽŕ@Óoo¿ē±ß}}ÓF÷tIJWÈCőâUâǙIğʼn©IijE×
Á³AĥDĈ±ÌÜÓĨ£L]ĈÙƺZǾĆĖMĸĤfÎĵlŨnÈĐtFFĤêk¶^k°f¶g}®Faf`vXŲxl¦ÔÁ²¬Ð¦pqÊ̲iXØRDÎ}Ä@ZĠsx®AR~®ETtĄZƈfŠŠHâÒÐAµ\\S¸^wĖkRzalŜ|E¨ÈNĀňZTpBh£\\ĎƀuXĖtKL¶G|»ĺEļĞ~ÜĢÛĊrOÙîvd]n¬VÊĜ°RÖpMƀ¬HbwEÀ©\\
¤]ŸI®¥D³|Ë]CúAЦ
æ´¥¸Lv¼¢ĽBaôF~®²GÌÒEYzk¤°ahlVÕI^CxĈPsBƒºVÀB¶¨R²´D","@@OR"]],"encodeOffsets":[[[117381,22988],[116552,22934],[116790,22617],[116973,22545],[116444,22536],[116931,22515],[116496,22490],[116453,22449],[113301,21439],[118726,21604],[118709,21486],[113210,20816],[115482,22082],[113171,21585],[113199,21590],[115232,22102],[115739,22373],[115134,22184],[113056,21175],[119573,21271],[119957,24020],[115859,22356],[116680,26053],[116561,22649]]]},"properties":{"cp":[113.5,23],"name":"广东","childNum":24}},{"id":"450000","geometry":{"type":"MultiPolygon","coordinates":[["@@H TI¡U","@@Ɣ_LÊFZg
čPkini«qÇczÍY®¬Ů»qR×ō©DÕ§ƙǃŵTÉĩ±ıdÑnYYIJvNĆĆØÜ Öp}e³¦m©iÓ|¹ħņ|ª¦QF¢Â¬ʖovg¿em^ucäāmÇÖåB¡Õçĝ}FϼĹ{µHKsLSđƃrč¤[AgoSŇYMÿ§Ç{FśbkylQxĕ]T·¶[B
ÑÏGáşşƇe
ăYSsFQ}BwtYğÃ@~
CÍQ ×Wj˱rÉ¥oÏ ±«ÓÂ¥kwWűue_bE~µh¯ecl¯Ïr¯EģJğ}w³Ƈē`ãògK_ÛsUʝćğ¶höO¤Ǜn³c`¡yię[ďĵűMę§]XÎ_íÛ]éÛUćİÕBƣ±
dy¹T^dûÅÑŦ·PĻþÙ`K¦
¢ÍeĥR¿³£[~äu¼dltW¸oRM¢ď\\z}Æzdvň{ÎXF¶°Â_ÒÂÏL©ÖTmu¼ãlīkiqéfA·Êµ\\őDc¥ÝFyÔćcűH_hLÜêĺШc}rn`½Ì@¸¶ªVLhŒ\\Ţĺk~Ġið°|gtTĭĸ^xvKVGréAébUuMJVÃO¡
qĂXËSģãlýà_juYÛÒBG^éÖ¶§EGÅzěƯ¤EkN[kdåucé¬dnYpAyČ{`]þ±X\\ÞÈk¡ĬjàhÂƄ¢Hè ŔâªLĒ^Öm¶ħĊAǦė¸zÚGn£¾rªŀÜt¬@ÖÚSx~øOŒŶÐÂæȠ\\ÈÜObĖw^oÞLf¬°bI lTØBÌF£Ć¹gñĤaYt¿¤VSñK¸¤nM¼JE±½¸ñoÜCƆæĪ^ĚQÖ¦^f´QüÜÊz¯lzUĺš@ìp¶n]sxtx¶@~ÒĂJb©gk{°~c°`Ô¬rV\\la¼¤ôá`¯¹LCÆbxEræOv[H[~|aB£ÖsºdAĐzNÂðsÞÆ
Ĥªbab`ho¡³F«èVZs\\\\ÔRzpp®SĪº¨ÖºN
ijd`a¦¤F³¢@`¢ĨĀìhYvlĆº¦Ċ~nS|gźv^kGÆÀè·"]],"encodeOffsets":[[[111707,21520],[113706,26955]]]},"properties":{"cp":[108.5,23.5],"name":"广西","childNum":2}},{"id":"460000","geometry":{"type":"Polygon","coordinates":["@@¦Ŝil¢XƦƞòïè§ŞCêɕrŧůÇąĻõ·ĉ³œ̅kÇm@ċȧŧĥĽʉƅſȓÒ˦ŝE}ºƑ[ÍĜȋ gÎfǐÏĤ¨êƺ\\Ɔ¸ĠĎvʄȀоjNðĀÒRZdžzÐĊ¢DÀɘZ"],"encodeOffsets":[[112750,20508]]},"properties":{"cp":[110,19.5],"name":"海南","childNum":1}},{"id":"510000","geometry":{"type":"MultiPolygon","coordinates":[["@@LqSn","@@ĆOìÛÐ@ĞǔNY{¤Á§d
i´ezÝúØãwIþËQǦÃqÉSJ»ĂéʔõÔƁİlƞ¹§ĬqtÀƄmÀêErĒtD®ċæcQE®³^ĭ¥©l}äQtoŖÜqÆkµªÔĻĴ¡@Ċ°B²Èw^^RsºT£ڿQPJvÄz^Đ¹Æ¯fLà´GC²dtĀRt¼¤ĦOðğfÔðDŨŁĞƘïPÈ®âbMüÀXZ ¸£@Å»»QÉ]dsÖ×_Í_ÌêŮPrĔĐÕGĂeZÜîĘqBhtO ¤tE[h|YÔZśÎs´xº±Uñt|OĩĠºNbgþJy^dÂY Į]Řz¦gC³R`Āz¢Aj¸CL¤RÆ»@Ŏk\\Ç´£YW}z@Z}öoû¶]´^NÒ}èNªPÍy¹`S°´ATeVamdUĐwʄvĮÕ\\uÆŗ¨Yp¹àZÂmWh{á}WØǍÉüwga§ßAYrÅÂQĀÕ¬LŐý®Xøxª½Ű¦¦[þ`ÜUÖ´òrÙŠ°²ÄkijnDX{U~ET{ļº¦PZcjF²Ė@pg¨B{u¨ŦyhoÚD®¯¢ WòàFΤ¨GDäz¦kŮPġqË¥À]eâÚ´ªKxīPÖ|æ[xäJÞĥsNÖ½I¬nĨY´®ÐƐmDŝuäđđEb
ee_v¡}ìęNJē}qÉåT¯µRs¡M@}ůaa¯wvƉåZw\\Z{åû`[±oiJDŦ]ĕãïrG réÏ·~ąSfy×Í·ºſƽĵȁŗūmHQ¡Y¡®ÁÃ×t«T¤JJJyJÈ`Ohߦ¡uËhIyCjmÿw
ZG
TiSsOB²fNmsPa{M{õE^Hj}gYpaeu¯oáwHjÁ½M¡pMuåmni{fk\\oÎqCwEZ¼KĝAy{m÷LwO×SimRI¯rKõBS«sFe]fµ¢óY_ÆPRcue°Cbo×bd£ŌIHgtrnyPt¦foaXďxlBowz_{ÊéWiêEGhܸºuFĈIxf®Y½ĀǙ]¤EyF²ċw¸¿@g¢§RGv»áW`ÃĵJwi]t¥wO½a[×]`ÃiüL¦LabbTÀåc}ÍhÆh®BHî|îºÉk¤Sy£ia©taį·Ɖ`ō¥UhO
ĝLk}©Fos´JmµlŁu
ønÑJWΪYÀïAetTŅÓGË«bo{ıwodƟ½OġܵxàNÖ¾P²§HKv¾]|BÆåoZ`¡Ø`ÀmºĠ~ÌЧnÇ
¿¤]wğ@srğu~Io[é±¹ ¿ſđÓ@qg¹zƱřaí°KtǤV»Ã[ĩǭƑ^ÇÓ@áťsZÏÅĭƋěpwDóÖáŻneQËq·GCœýS]x·ýq³OÕ¶Qzßti{řáÍÇWŝŭñzÇWpç¿JXĩè½cFÂLiVjx}\\NŇĖ¥GeJA¼ÄHfÈu~¸Æ«dE³ÉMA|bÒ
ćhG¬CMõƤąAvüVéŀ_V̳ĐwQj´·ZeÈÁ¨X´Æ¡Qu·»ÕZ³ġqDoy`L¬gdp°şp¦ėìÅĮZ°Iähzĵf²å ĚÑKpIN|Ñz]ń
·FU×é»R³MÉ»GM«kiér}Ã`¹ăÞmÈnÁîRǀ³ĜoİzŔwǶVÚ£À]ɜ»ĆlƂ²Ġ
þTº·àUȞÏʦ¶I«dĽĢdĬ¿»Ĕ×h\\c¬ä²GêëĤł¥ÀǿżÃÆMº}BÕĢyFVvwxBèĻĒ©Ĉt@Ğû¸£B¯¨ˋäßkķ½ªôNÔ~t¼Ŵu^s¼{TA¼ø°¢İªDè¾Ň¶ÝJ®Z´ğ~Sn|ªWÚ©òzPOȸbð¢|øĞA"]],"encodeOffsets":[[[108815,30935],[100197,35028]]]},"properties":{"cp":[103.5,30.6],"name":"四川","childNum":2}},{"id":"520000","geometry":{"type":"MultiPolygon","coordinates":[["@@G\\lY£cj","@@q|mc¯vÏV","@@hÑ£IsNgßHHªķÃh_¹¡ĝħń¦uÙùgS¯JH|sÝÅtÁïyMDč»eÕtA¤{b\\}G®u\\åPFqwÅaD
K°ºâ_£ùbµmÁÛĹM[q|hlaªāI}ѵ@swtwm^oµD鼊yVky°ÉûÛR
³e¥]RÕěħ[ƅåÛDpJiVÂF²I
»mN·£LbÒYbWsÀbpkiTZĄă¶Hq`
ĥ_J¯ae«KpÝx]aĕÛPÇȟ[ÁåŵÏő÷Pw}TÙ@Õs«ĿÛq©½m¤ÙH·yǥĘĉBµĨÕnđ]K©œáGçş§ÕßgǗĦTèƤƺ{¶ÉHÎd¾ŚÊ·OÐjXWrãLyzÉAL¾ę¢bĶėy_qMĔąro¼hĊw¶øV¤w²Ĉ]ÊKx|`ź¦ÂÈdrcÈbe¸`I¼čTF´¼Óýȃr¹ÍJ©k_șl³´_pĐ`oÒh¶pa^ÓĔ}D»^Xy`d[Kv
JPhèhCrĂĚÂ^Êƌ wZLĠ£ÁbrzOIlMMĪŐžËr×ÎeŦtw|¢mKjSǘňĂStÎŦEtqFT¾E쬬ôxÌO¢ K³ŀºäYPVgŎ¦Ŋm޼VZwVlz¤
£Tl®ctĽÚó{GAÇge~Îd¿æaSba¥KKûj®_Ä^\\ؾbP®¦x^sxjĶI_Ä Xâ¼Hu¨Qh¡À@Ëô}±GNìĎlT¸
`V~R°tbÕĊ`¸úÛtÏFDu[MfqGH·¥yAztMFe|R_GkChZeÚ°tov`xbDnÐ{E}ZèxNEÞREn[Pv@{~rĆAB§EO¿|UZ~ìUf¨J²ĂÝÆsªB`s¶fvö¦Õ~dÔq¨¸º»uù[[§´sb¤¢zþF¢Æ
ÀhÂW\\ıËIÝo±ĭŠ£þÊs}¡R]ěDg´VG¢j±®èºÃmpU[Á뺰rÜbNu¸}º¼`niºÔXĄ¤¼ÔdaµÁ_Ã
ftQQgR·Ǔv}Ý×ĵ]µWc¤F²OĩųãW½¯K©
]{LóµCIµ±Mß¿h©āq¬o½~@i~TUxð´ĐhwÀEîôuĶb[§nWuMÆJl½]vuıµb"]],"encodeOffsets":[[[112158,27383],[112105,27474],[112095,27476]]]},"properties":{"cp":[106.7,26.6],"name":"贵州","childNum":3}},{"id":"530000","geometry":{"type":"Polygon","coordinates":["@@[ùx½}ÑRHYīĺûsÍniEoã½Ya²ė{c¬ĝgĂsAØÅwďõzFjw}«Dx¿}Uũlê@HÅF¨ÇoJ´Ónũuą¡Ã¢pÒÅØ TF²xa²ËXcÊlHîAßËŁkŻƑŷÉ©hWæßUËs¡¦}teèÆ¶StÇÇ}Fd£jĈZĆÆ¤Tč\\D}O÷£U§~ŃGåŃDĝ¸Tsd¶¶Bª¤u¢ŌĎo~t¾ÍŶÒtD¦ÚiôözØX²ghįh½Û±¯ÿm·zR¦Ɵ`ªŊÃh¢rOÔ´£Ym¼èêf¯ŪĽncÚbw\\zlvWªâ ¦gmĿBĹ£¢ƹřbĥkǫßeeZkÙIKueT»sVesbaĕ ¶®dNĄÄpªy¼³BE®lGŭCǶwêżĔÂepÍÀQƞpC¼ŲÈAÎô¶RäQ^Øu¬°_Èôc´¹ò¨P΢hlϦ´ĦÆ´sâÇŲPnÊD^¯°Upv}®BP̪jǬxSöwlfòªvqĸ|`HviļndĜĆhňem·FyÞqóSᝳX_ĞçêtryvL¤§z¦c¦¥jnŞklD¤øz½ĜàĂŧMÅ|áƆàÊcðÂFÜáŢ¥\\\\ºİøÒÐJĴîD¦zK²ǏÎEh~CDhMn^ÌöÄ©ČZÀaüfɭyœpį´ěFűk]Ôě¢qlÅĆÙa¶~ÄqêljN¬¼HÊNQ´ê¼VظE^ŃÒyM{JLoÒęæe±Ķygã¯JYÆĭĘëo¥Šo¯hcK«z_prC´ĢÖY¼ v¸¢RÅW³Â§fǸYi³xR´ďUË`êĿUûuĆBƣöNDH«ĈgÑaB{ÊNF´¬c·Åv}eÇÃGB»If¦HňĕM
~[iwjUÁKE¾dĪçWIèÀoÈXòyŞŮÈXâÎŚj|àsRyµÖPr´þ ¸^wþTDŔHr¸RÌmfżÕâCôoxĜƌÆĮÐYtâŦÔ@]ÈǮƒ\\μģUsȯLbîƲŚºyhr@ĒÔƀÀ²º\\êpJ}ĠvqtĠ@^xÀ£È¨mËÏğ}n¹_¿¢×Y_æpÅA^{½Lu¨GO±Õ½ßM¶wÁĢÛPƢ¼pcIJx|ap̬HÐŊSfsðBZ¿©XÏÒKk÷Eû¿S
rEFsÕūkóVǥʼniTL¡n{uxţÏhôŝ¬ğōNNJkyPaqÂğ¤K®YxÉƋÁ]āęDqçgOgILu\\_gz]W¼~CÔē]bµogpÑ_oď`´³Țkl`IªºÎȄqÔþ»E³ĎSJ»_f·adÇqÇc¥Á_Źw{L^ɱćxU£µ÷xgĉp»ĆqNē`rĘzaĵĚ¡K½ÊBzyäKXqiWPÏɸ½řÍcÊG|µƕƣGË÷k°_^ý|_zċBZocmø¯hhcæ\\lMFlư£ĜÆyHF¨µêÕ]HA
àÓ^it `þßäkĤÎT~Wlÿ¨ÔPzUCNVv [jâôDôď[}z¿msSh¯{jïğl}šĹ[őgK©U·µË@¾m_~q¡f¹
ÅË^»f³ø}Q¡Ö˳gͱ^Ç
\\ëÃA_¿bWÏ[¶ƛé£F{īZgm@|kHǭƁć¦UĔť×ëǟ
eċ¼ȡȘÏíBÉ£āĘPªij¶ʼnÿy©nď£G¹¡I±LÉĺÑdĉÜW¥}gÁ{aqÃ¥aıęÏZÁ`"],"encodeOffsets":[[104636,22969]]},"properties":{"cp":[102,24.7],"name":"云南","childNum":1}},{"id":"540000","geometry":{"type":"Polygon","coordinates":["@@ÂhľxŖxÒVºÅâAĪÝȆµę¯Ňa±r_w~uSÕňqOj]ɄQ
£Z
UDûoY»©M[L¼qãË{VÍçWVi]ë©Ä÷àyƛhÚU°adcQ~Mx¥caÛcSyFÖkuRýq¿ÔµQĽ³aG{¿FµëªéĜÿª@¬·K·àariĕĀ«V»ŶĴūgèLǴŇƶaftèBŚ£^âǐÝ®M¦ÁǞÿ¬LhJ¾óƾƺcxwf]Y
´¦|QLn°adĊ
\\¨oǀÍŎ´ĩĀd`tÊQŞŕ|¨C^©Ĉ¦¦ÎJĊ{ëĎjª²rÐl`¼Ą[t|¦Stè¾PÜK¸dƄı]s¤î_v¹ÎVòŦj£Əsc¬_Ğ´|٦Av¦w`ăaÝaa¢e¤ı²©ªSªÈMĄwÉØŔì@T¤Ę\\õª@þo´xA sÂtŎKzó²Çȵ¢r^nĊƬ×üG¢³ {âĊ]G~bÀgVjzlhǶfOfdªB]pjTOtĊn¤}®¦Č¥d¢¼»ddY¼t¢eȤJ¤}Ǿ¡°§¤AÐlc@ĝsªćļđAçwxUuzEÖġ~AN¹ÄÅȀݦ¿ģŁéì±H
ãd«g[ؼēÀcīľġ¬cJµ
ÐʥVȝ¸ßS¹ý±ğkƁ¼ą^ɛ¤Ûÿb[}¬ōõÃ]ËNm®g@Bg}ÍF±ǐyL¥íCIijÏ÷Ñį[¹¦[âšEÛïÁÉdƅß{âNÆāŨß¾ě÷yC£k´ÓH@¹TZ¥¢į·ÌAЧ®Zc
v½Z¹|ÅWZqgW|ieZÅYVÓqdqbc²R@c¥Rã»GeeƃīQ}J[ÒK
¬Ə|oėjġĠÑN¡ð¯EBčnwôɍėª²CλŹġǝʅįĭạ̃ūȹ]ΓͧgšsgȽóϧµǛęgſ¶ҍć`ĘąŌJÞä¤rÅň¥ÖÁUětęuůÞiĊÄÀ\\Æs¦ÓRb|Â^řÌkÄŷ¶½÷f±iMÝ@ĥ°G¬ÃM¥n£Øąğ¯ß§aëbéüÑOčk£{\\eµª×MÉfm«Ƒ{Å×Gŏǩãy³©WÑăû··Qòı}¯ãIéÕÂZ¨īès¶ZÈsæĔTŘvgÌsN@îá¾ó@ÙwU±ÉT廣TđWxq¹Zobs[ׯcĩvėŧ³BM|¹kªħ¥TzNYnÝßpęrñĠĉRS~½ěVVµõ«M££µBĉ¥áºae~³AuĐh`ܳç@BÛïĿa©|z²Ý¼D£àč²ŸIûI āóK¥}rÝ_Á´éMaň¨~ªSĈ½½KÙóĿeƃÆB·¬ën×W|Uº}LJrƳlŒµ`bÔ`QÐÓ@s¬ñIÍ@ûws¡åQÑßÁ`ŋĴ{ĪTÚÅTSijYo|Ç[ǾµMW¢ĭiÕØ¿@Mh
pÕ]jéò¿OƇĆƇpêĉâlØwěsǩĵ¸c
bU¹ř¨WavquSMzeo_^gsÏ·¥Ó@~¯¿RiīB\\qTGªÇĜçPoÿfñòą¦óQīÈáPābß{ZŗĸIæÅhnszÁCËìñÏ·ąĚÝUm®óL·ăUÈíoù´Êj°ŁŤ_uµ^°ìÇ@tĶĒ¡ÆM³Ģ«İĨÅ®ğRāðggheÆ¢zÊ©Ô\\°ÝĎz~ź¤PnMĪÖB£kné§żćĆKǰ¼L¶èâz¨u¦¥LDĘz¬ýÎmĘd¾ßFzhg²Fy¦ĝ¤ċņbÎ@yĄæm°NĮZRÖíJ²öLĸÒ¨Y®ƌÐVàtt_ÚÂyĠz]ŢhzĎ{ÂĢXc|ÐqfO¢¤ögÌHNPKŖUú´xx[xvĐCûĀìÖT¬¸^}Ìsòd´_KgžLĴ
ÀBon|H@Êx¦BpŰŌ¿fµƌA¾zLjRx¶FkĄźRzŀ~¶[´HnªVƞuĒȨƎcƽÌm¸ÁÈM¦x͊ëÀxdžBú^´W£dkɾĬpw˂ØɦļĬIŚÊnŔa¸~J°îlɌxĤÊÈðhÌ®gT´øàCÀ^ªerrƘd¢İP|Ė ŸWªĦ^¶´ÂLaT±üWƜǀRÂŶUńĖ[QhlLüAÜ\\qRĄ©"],"encodeOffsets":[[90849,37210]]},"properties":{"cp":[91,30.5],"name":"西藏","childNum":1}},{"id":"610000","geometry":{"type":"Polygon","coordinates":["@@¸ÂW¢xRFq§uF@N¢XLRMº[ğȣſï|¥Jkc`sʼnǷ£Y³WN«ùMëï³ÛIg÷±mTșÚÒķø©þ¥yÓğęmWµÎumZyOŅƟĥÓ~sÑL¤µaÅ
Y¦ocyZ{y c]{Ta©`U_Ěē£ωÊƍKùK¶ȱÝƷ§{û»ÅÁȹÍéuij|¹cÑdìUYOuFÕÈYvÁCqÓTǢí§·S¹NgV¬ë÷Át°DدC´ʼnƒópģ}ąiEË
FéGU¥×K
§¶³BČ}C¿åċ`wġB·¤őcƭ²ő[Å^axwQO
ñJÙïŚĤNĔwƇÄńwĪo[_KÓª³ÙnKÇěÿ]ďă_d©·©Ýŏ°Ù®g]±ß×¥¬÷m\\iaǑkěX{¢|ZKlçhLtŇîŵœè[É@ƉĄEtƇϳħZ«mJ
×¾MtÝĦ£IwÄå\\Õ{OwĬ©LÙ³ÙTª¿^¦rÌĢŭO¥lãyC§HÍ£ßEñX¡°ÙCgpťzb`wIvA|¥hoĕ@E±iYd¥OÿµÇvPW|mCĴŜǂÒW¶¸AĜh^Wx{@¬F¸¡ķn£P|ªĴ@^ĠĈæbÔc¶lYi
^MicϰÂ[ävï¶gv@ÀĬ·lJ¸sn|¼u~a]ÆÈtŌºJpþ£KKf~¦UbyäIĺãnÔ¿^ŵMThĠܤko¼Ŏìąǜh`[tRd²IJ_XPrɲlXiL§à¹H°Ȧqº®QCbAŌJ¸ĕÚ³ĺ§ `d¨YjiZvRĺ±öVKkjGȊÄePĞZmļKÀ[`ösìhïÎoĬdtKÞ{¬èÒÒBÔpIJÇĬJŊ¦±J«[©ārHµàåVKe§|P²ÇÓ·vUzgnN¾yI@oHĆÛķhxen¡QQ±ƝJǖRbzy¸ËÐl¼EºpĤ¼x¼½~Ğà@ÚüdK^mÌSjp²ȮµûGĦ}Ħðǚ¶òƄjɂz°{ºØkÈęâ¦jªBg\\ċ°s¬]jú EȌdž¬stRÆdĠİwܸôW¾ƮłÒ_{Ìû¼jº¹¢GǪÒ¯ĘZ`ºŊecņą~BÂgzpâēòYƲȐĎ"],"encodeOffsets":[[113634,40474]]},"properties":{"cp":[108.9,34.26],"name":"陕西","childNum":1}},{"id":"620000","geometry":{"type":"MultiPolygon","coordinates":[["@@Vu_^","@@ųEĠtt~nkh`Q¦ÅÄÜdwAb×ĠąJ¤DüègĺqBqj°lI¡Ĩ¶ĖIHdjÎB°aZ¢KJO[|A£Dx}NìHUnrk kp¼Y kMJn[aGáÚÏ[½rc}aQxOgsPMnUsncZ
sKúvAtÞġ£®ĀYKdnFw¢JE°Latf`¼h¬we|Æbj}GA·~W`¢MC¤tL©IJ°qdfObÞĬ¹ttu`^ZúE`[@Æsîz®¡CƳƜG²R¢RmfwĸgÜą G@pzJM½mhVy¸uÈÔO±¨{LfæU¶ßGĂq\\ª¬²I¥IʼnÈīoıÓÑAçÑ|«LÝcspīðÍg
të_õ\\ĉñLYnĝgRǡÁiHLlõUĹ²uQjYi§Z_c¨´ĹĖÙ·ŋI
aBDR¹ȥr¯GºßK¨jWkɱOqWij\\aQ\\sg_ĆǛōëp»£lğÛgSŶN®À]ÓämĹãJaz¥V}Le¤Lýo¹IsŋÅÇ^bz
³tmEÁ´a¹cčecÇNĊãÁ\\č¯dNj]jZµkÓdaćå]ğij@ ©O{¤ĸm¢E·®«|@Xwg]A챝XǁÑdzªcwQÚŝñsÕ³ÛV_ý¥\\ů¥©¾÷w©WÕÊĩhÿÖÁRo¸V¬âDb¨hûxÊ×nj~Zâg|XÁnßYoº§ZÅŘv[ĭÖʃuďxcVbnUSf
B¯³_TzºÎO©çMÑ~M³]µ^püµÄY~y@X~¤Z³[Èōl@®Å¼£QK·Di¡ByÿQ_´D¥hŗy^ĭÁZ]cIzýah¹MĪğPs{ò²Vw¹t³ŜË[Ñ}X\\gsF£sPAgěp×ëfYHāďÖqēŭOÏëdLü\\it^c®Rʺ¶¢H°mrY£B¹čIoľu¶uI]vģSQ{UŻÅ}QÂ|̰ƅ¤ĩŪU ęĄÌZÒ\\v²PĔ»ƢNHĂyAmƂwVm`]ÈbH`Ì¢²ILvĜH®¤Dlt_¢JJÄämèÔDëþgºƫaʎÌrêYi~ ÎݤNpÀA¾Ĕ¼b
ð÷®üszMzÖĖQdȨýv§Tè|ªHþa¸|Ð ƒwKĢx¦ivr^ÿ ¸l öæfƟĴ·PJv}n\\h¹¶v·À|\\ƁĚN´ĜçèÁz]ġ¤²¨QÒŨTIlªťØ}¼˗ƦvÄùØE«FïËIqōTvāÜŏíÛßÛVj³âwGăÂíNOPìyV³ʼnĖýZso§HÑiYw[ß\\X¦¥c]ÔƩÜ·«jÐqvÁ¦m^ċ±R¦ƈťĚgÀ»IïĨʗƮ°ƝĻþÍAƉſ±tÍEÕÞāNUÍ¡\\ſčåÒʻĘm ƭÌŹöʥëQ¤µÇcƕªoIýIÉ_mkl³ăƓ¦j¡YzŇi}Msßõīʋ }ÁVm_[n}eıUĥ¼ªI{ΧDÓƻėojqYhĹT©oūĶ£]ďxĩǑMĝq`B´ƃ˺Чç~²ņj@¥@đ´ί}ĥtPńǾV¬ufÓÉCtÓ̻
¹£G³]ƖƾŎĪŪĘ̖¨ʈĢƂlɘ۪üºňUðǜȢƢż̌ȦǼĤŊɲĖÂKqĘʼn¼ĔDzņɾªǀÞĈĂD½ĄĎÌŗĞrôñnN¼â¾ʄľԆ|DŽ֦ज़ȗlj̘̭ɺƅêgV̍ʆĠ·ÌĊv|ýĖÕWĊǎÞ´õ¼cÒÒBĢ͢UĜð͒s¨ňƃLĉÕÝ@ɛƯ÷¿ĽĹeȏijëCȚDŲyê×Ŗyò¯ļcÂßY
tÁƤyAã˾J@ǝrý@¤
rz¸oP¹ɐÚyáHĀ[Jw
cVeȴÏ»ÈĖ}ƒŰŐèȭǢόĀƪÈŶë;Ñ̆ȤМľĮEŔĹŊũ~ËUă{ĻƹɁύȩþĽvĽƓÉ@ēĽɲßǐƫʾǗĒpäWÐxnsÀ^ƆwW©¦cÅ¡Ji§vúF¶¨c~c¼īeXǚ\\đ¾JwÀďksãAfÕ¦L}waoZD½Ml«]eÒÅaɲáo½FõÛ]ĻÒ¡wYR£¢rvÓ®y®LFLzĈôe]gx}|KK}xklL]c¦£fRtív¦PŨ£","@@M T¥"]],"encodeOffsets":[[[108619,36299],[108594,36341],[108600,36306]]]},"properties":{"cp":[104,35.5],"name":"甘肃","childNum":3}},{"id":"630000","geometry":{"type":"MultiPolygon","coordinates":[["@@InJo","@@CƽOŃĦsΰ~dz¦@@Ņi±è}ШƄ˹A³r_ĞǒNĪĐw¤^ŬĵªpĺSZgrpiƼĘÔ¨C|ÍJ©Ħ»®VIJ~f\\m `UnÂ~ʌĬàöNt~ňjy¢ZiƔ¥Ąk´nl`JÊJþ©pdƖ®È£¶ìRʦźõƮËnʼėæÑƀĎ[¢VÎĂMÖÝÎF²sƊƀÎBļýƞ¯ʘƭðħ¼Jh¿ŦęΌƇ¥²Q]Č¥nuÂÏri¸¬ƪÛ^Ó¦d¥[Wà
x\\ZjÒ¨GtpþYŊĕ´zUOëPîMĄÁxH´áiÜUàîÜŐĂÛSuŎrJð̬EFÁú×uÃÎkrĒ{V}İ«O_ÌËĬ©ÓŧSRѱ§Ģ£^ÂyèçěM³Ƃę{[¸¿u
ºµ[gt£¸OƤĿéYõ·kĀq]juw¥DĩƍõÇPéĽG©ã¤G
uȧþRcÕĕNyyûtøï»a½ē¿BMoį£Íj}éZËqbʍƬh¹ìÿÓAçãnIáI`ks£CGěUy×Cy
@¶ʡÊBnāzGơMē¼±O÷õJËĚăVĪũƆ£¯{ËL½ÌzżVR|ĠTbuvJvµhĻĖHAëáa
OÇðñęNw
œľ·LmI±íĠĩPÉ×®ÿscB³±JKßĊ«`
ađ»·QAmOVţéÿ¤¹SQt]]Çx±¯A@ĉij¢Óļ©l¶ÅÛrŕspãRk~¦ª]Į´FRådČsCqđéFn¿ÅƃmÉx{W©ºƝºįkÕƂƑ¸wWūЩÈF£\\tÈ¥ÄRÈýÌJ lGr^×äùyÞ³fjc¨£ÂZ|ǓMĝÏ@ëÜőRĝ÷¡{aïȷPu°ËXÙ{©TmĠ}Y³ÞIňµç½©C¡į÷¯B»|St»]vųs»}MÓ ÿʪƟǭA¡fs»PY¼c¡»¦cċ¥£~msĉPSi^o©AecPeǵkgyUi¿h}aHĉ^|á´¡HØûÅ«ĉ®]m¡qċ¶±ÈyôōLÁstB®wn±ă¥HSòė£Së@לÊăxÇN©©T±ª£IJ¡fb®Þbb_Ą¥xu¥B{łĝ³«`dƐt¤ťiñÍUuºí`£^tƃIJc·ÛLO½sç¥Ts{ă\\_»kϱq©čiìĉ|ÍI¥ć¥]ª§D{ŝŖÉR_sÿc³ĪōƿΧp[ĉc¯bKmR¥{³Ze^wx¹dƽŽôIg §Mĕ ƹĴ¿ǣÜÍ]Ý]snåA{eƭ`ǻŊĿ\\ijŬűYÂÿ¬jĖqßb¸L«¸©@ěĀ©ê¶ìÀEH|´bRľÓ¶rÀQþvl®ÕETzÜdb hw¤{LRdcb¯ÙVgƜßzÃôì®^jUèXÎ|UäÌ»rK\\ªN¼pZCüVY¤ɃRi^rPŇTÖ}|br°qňb̰ªiƶGQ¾²x¦PmlŜ[Ĥ¡ΞsĦÔÏâ\\ªÚŒU\\f
¢N²§x|¤§xĔsZPòʛ²SÐqF`ªVÞŜĶƨVZÌL`¢dŐIqr\\oäõF礻Ŷ×h¹]ClÙ\\¦ďÌį¬řtTӺƙgQÇÓHţĒ´ÃbEÄlbʔC|CŮkƮ[ʼ¬ň´KŮÈΰÌζƶlðļATUvdTGº̼ÔsÊDÔveMg"]],"encodeOffsets":[[[105308,37219],[95370,40081]]]},"properties":{"cp":[97,36],"name":"青海","childNum":2}},{"id":"640000","geometry":{"type":"Polygon","coordinates":["@@KëÀęĞ«Oęȿȕı]ʼn¡åįÕÔ«ǴõƪĚQÐZhv K°öqÀÑS[ÃÖHƖčËnL]ûc
Ùß@ĝ¾}w»»oģF¹»kÌÏ·{zP§B¢íyÅt@@á]Yv_ssģ¼ißĻL¾ġsKD£¡N_
X¸}B~HaiÅf{«x»ge_bsKF¯¡IxmELcÿZ¤ĢÝsuBLùtYdmVtNmtOPhRw~bd
¾qÐ\\âÙH\\bImlNZ»loqlVmGā§~QCw¤{A\\PKNY¯bFkC¥sks_Ã\\ă«¢ħkJi¯rrAhĹûç£CUĕĊ_ÔBixÅÙĄnªÑaM~ħpOu¥sîeQ¥¤^dkKwlL~{L~hw^ófćKyEKzuÔ¡qQ¤xZÑ¢^ļöܾEp±âbÊÑÆ^fk¬
NC¾YpxbK~¥eÖäBlt¿Đx½I[ĒǙWf»Ĭ}d§dµùEuj¨IÆ¢¥dXªƅx¿]mtÏwßRĶX¢͎vÆzƂZò®ǢÌʆCrâºMÞzÆMÒÊÓŊZľr°Î®Ȉmª²ĈUªĚîøºĮ¦ÌĘk^FłĬhĚiĀ˾iİbjË"],"encodeOffsets":[[109366,40242]]},"properties":{"cp":[106.1,37.5],"name":"宁夏","childNum":1}},{"id":"650000","geometry":{"type":"Polygon","coordinates":["@@QØĔ²X¨~ǘBºjʐߨvKƔX¨vĊO÷¢i@~cĝe_«E}QxgɪëÏÃ@sÅyXoŖ{ô«ŸuX
êÎf`C¹ÂÿÐGĮÕĞXŪōŸMźÈƺQèĽôe|¿ƸJR¤ĘEjcUóº¯Ĩ_ŘÁMª÷Ð¥OéÈ¿ÖğǤǷÂFÒzÉx[]Ĥĝœ¦EP}ûƥé¿İƷTėƫœŕƅƱB»Đ±ēO
¦E}`cȺrĦáŖuÒª«IJπdƺÏØZƴwʄ¤ĖGĐǂZĶèH¶}ÚZצʥĪï|ÇĦMŔ»İĝLjì¥Βba¯¥ǕǚkĆŵĦɑĺƯxūД̵nơʃĽá½M»òmqóŘĝč˾ăC
ćāƿÝɽ©DZŅ»ēėŊLrÁ®ɱĕģʼnǻ̋ȥơŻǛȡVï¹Ň۩ûkɗġƁ§ʇė̕ĩũƽō^ƕUv£ƁQïƵkŏ½ΉÃŭdzLŇʻ«ƭ\\lŭD{ʓDkaFÃÄa³ŤđÔGRÈƚhSӹŚsİ«ĐË[¥ÚDkº^Øg¼ŵ¸£EÍöůʼnT¡c_ËKYƧUśĵÝU_©rETÏʜ±OñtYwē¨{£¨uM³x½şL©Ùá[ÓÐĥ Νtģ¢\\śnkOw¥±T»ƷFɯàĩÞáB¹Æ
ÑUwŕĽw]kE½Èå~Æ÷QyěCFmĭZīŵVÁƿQƛûXS²b½KϽĉS©ŷXĕ{ĕK·¥Ɨcqq©f¿]ßDõU³hgËÇïģÉɋwk¯í}I·œbmÉřīJɥĻˁ×xoɹīlc
¤³Xù]DžA¿w͉ì¥wÇN·ÂËnƾƍdǧđ®ƝvUm©³G\\}µĿQyŹlăµEwLJQ½yƋBe¶ŋÀůo¥AÉw@{Gpm¿AijŽKLh³`ñcËtW±»ÕSëüÿďDu\\wwwù³VLŕOMËGh£õP¡erÏd{ġWÁ
č|yšg^ğyÁzÙs`s|ÉåªÇ}m¢Ń¨`x¥ù^}Ì¥H«YªƅAйn~ź¯f¤áÀzgÇDIÔ´AňĀÒ¶ûEYospõD[{ù°]uJqU|Soċxţ[õÔĥkŋÞŭZ˺óYËüċrw ÞkrťË¿XGÉbřaDü·Ē÷Aê[ÄäI®BÕĐÞ_¢āĠpÛÄȉĖġDKwbmÄNôfƫVÉvidzHQµâFùœ³¦{YGd¢ĚÜO {Ö¦ÞÍÀP^bƾl[vt×ĈÍE˨¡Đ~´î¸ùÎhuè`¸HÕŔVºwĠââWò@{ÙNÝ´ə²ȕn{¿¥{l÷eé^eďXj©î\\ªÑòÜìc\\üqÕ[Č¡xoÂċªbØø|¶ȴZdÆÂońéG\\¼C°ÌÆn´nxÊOĨŪƴĸ¢¸òTxÊǪMīĞÖŲÃɎOvʦƢ~FRěò¿ġ~åŊúN¸qĘ[Ĕ¶ÂćnÒPĒÜvúĀÊbÖ{Äî¸~Ŕünp¤ÂH¾ĄYÒ©ÊfºmÔĘcDoĬMŬS¤s²ʘÚžȂVŦ èW°ªB|IJXŔþÈJĦÆæFĚêYĂªĂ]øªŖNÞüAfɨJ¯ÎrDDĤ`mz\\§~D¬{vJ«lµĂb¤pŌŰNĄ¨ĊXW|ų ¿¾ɄĦƐMTòP÷fØĶK¢ȝ˔Sô¹òEð`Ɩ½ǒÂň×äı§ĤƝ§C~¡hlåǺŦŞkâ~}FøàIJaĞfƠ¥Ŕd®U¸źXv¢aƆúŪtŠųƠjdƺƺÅìnrh\\ĺ¯äɝĦ]èpĄ¦´LƞĬ´ƤǬ˼Ēɸ¤rºǼ²¨zÌPðŀbþ¹ļD¢¹\\ĜÑŚ¶ZƄ³âjĦoâȴLÊȮĐĚăÀêZǚŐ¤qȂ\\L¢ŌİfÆs|zºeªÙæ§{Ā´ƐÚ¬¨Ĵà²łhʺKÞºÖTiƢ¾ªì°`öøu®Ê¾ãÖ"],"encodeOffsets":[[88824,50096]]},"properties":{"cp":[87,41],"name":"新疆","childNum":1}},{"id":"110000","geometry":{"type":"Polygon","coordinates":["@@RºaYÕQaúÍÔiþĩȨWĢü|Ėu[qb[swP@ÅğP¿{\\¯Y²·Ñ¨j¯X\\¯MSvU¯YIŕY{[fkVÁûtŷmiÍt_H»Ĩ±d`¹{bw
Yr³S]§§o¹qGtm_SŧoaFLgQN_dV@Zom_ć\\ßW´ÕiœRcfi
o§ËgToÛJíĔóu
|wP¤XnO¢ÉŦ¯pNÄā¤zâŖÈRpŢZÚ{GrFt¦Òx§ø¹RóäV¤XdżâºWbwڍUd®bêņ¾jnŎGŃŶnzÚScîĚZen¬"],"encodeOffsets":[[119421,42013]]},"properties":{"cp":[116.4,40.24],"name":"北京","childNum":1}},{"id":"120000","geometry":{"type":"Polygon","coordinates":["@@ŬgX§Ü«E
¶F̬O_ïlÁgz±AXeµÄĵ{¶]gitgIj·¥ì_iU¨ÐƎk}ĕ{gBqGf{¿aU^fIư³õ{YıëNĿk©ïËZukāAīlĕĥs¡bġ«@dekąI[nlPqCnp{ō³°`{PNdƗqSÄĻNNâyj]äÒD ĬH°Æ]~¡HO¾X}ÐxgpgWrDGpù^LrzWxZ^¨´T\\|~@IzbĤjeĊªz£®ĔvěLmV¾Ô_ÈNW~zbĬvG²ZmDM~~"],"encodeOffsets":[[120237,41215]]},"properties":{"cp":[116.87,39.5],"name":"天津","childNum":1}},{"id":"310000","geometry":{"type":"MultiPolygon","coordinates":[["@@ɧư¬EpƸÁx]","@@©²","@@MA","@@QpªKWT
§¨","@@bŝÕÕEȣÚƥêImɇǦèÜĠÚÄÓŴ·ʌÇ","@@Sô¤r]ìƬįǜûȬɋŭ×^sYɍDŋŽąñCG²«ªč@h_p¯A{oloY¬j@IJ`gQÚpptǀ^MIJvtbe´Rh@oj¨","@@ÆLH{a}Eo¦"]],"encodeOffsets":[[[124702,32062],[124547,32200],[124808,31991],[124726,32110],[124903,32376],[124065,32166],[124870,31965]]]},"properties":{"cp":[121.4,31.1],"name":"上海","childNum":7}},{"id":"500000","geometry":{"type":"Polygon","coordinates":["@@TÂÛ`Ùƅően½SêqDu[Rå͹÷eXÍy¸_ĺę}÷`M¯ċfCVµqʼn÷Zgg^d½pDOÎCn^uf²ènh¼WtƏxRGg¦
pVFI±G^Ic´ecGĹÞ½sëÆNä̤KÓe¯|R¸§LÜkPoïƭNï¶}Gywdiù©nkĈzj@Óc£»Wă¹Óf§c[µo·Ó|MvÛaq½«è\\ÂoVnÓØÍ²«bq¿ehCĜ^Q~ Évýş¤²ĮpEĶyhsŊwH½¿gÅ¡ýE¡ya£³t\\¨\\vú¹¼©·Ñr_oÒý¥et³]Et©uÖ¥±ă©KVeë]}wVPÀFA¨ąB}qTjgRemfFmQFÝ
MyùnÑAmÑCawu_p¯sfÛ_gI_pNysB¦zG¸rHeN\\CvEsÐñÚkcDÖĉsaQ¯}_UzÁē}^R Äd^ÍĸZ¾·¶`wećJE¹vÛ·HgéFXjÉê`|ypxkAwWĐpb¥eOsmzwqChóUQl¥F^lafanòsrEvfQdÁUVfÎvÜ^eftET¬ôA\\¢sJnQTjPØxøK|nBzĞ»LY
FDxÓvr[ehľvN¢o¾NiÂxGpâ¬zbfZo~hGi]öF||NbtOMn eA±tPTLjpYQ|SHYĀxinzDJÌg¢và¥Pg_ÇzIIII£®S¬Øs쥨^LnGIJļIJƤjÎƀƾ¹¸ØÎezĆT¸}êÐqHðqĖä¥^CÆIj²p
\\_ æüY|[YxƊæu°xb®
Űb@~¢NQt°¶Sæ Ê~rljĔëĚ¢~uf`faĔJåĊnÔ]jƎćÊ@£¾a®£Ű{ŶĕFègLk{Y|¡ĜWƔtƬJÑxq±ĢN´òKLÈüD|s`ŋć]Ã`đMùƱ¿~Y°ħ`ƏíW½eI½{aOIrÏ¡ĕŇapµÜƃġ²"],"encodeOffsets":[[111728,31311]]},"properties":{"cp":[107.5,29.7],"name":"重庆","childNum":1}},{"id":"810000","geometry":{"type":"MultiPolygon","coordinates":[["@@AlFi","@@mp","@@EpHo","@@rMUwAS¬]","@@ea¢pl¸Eõ¹hj[]ÔCÎ@lj¡uBX
´AI¹
[yDU]W`çwZkmc
MpÅv}IoJlcafŃK°ä¬XJmÐ đhI®æÔtSHnEÒrÄc"]],"encodeOffsets":[[[117111,23002],[117072,22876],[117045,22887],[116882,22747],[116975,23082]]]},"properties":{"cp":[115.2,22.75],"name":"香港","childNum":5}},{"id":"820000","geometry":{"type":"Polygon","coordinates":["@@áw{Îr"],"encodeOffsets":[[116285,22746]]},"properties":{"cp":[114.52,22.86],"name":"澳门","childNum":1}}],"UTF8Encoding":true});
-}));
\ No newline at end of file
diff --git a/bigscreen/js/echarts.min.js b/bigscreen/js/echarts.min.js
deleted file mode 100644
index 394e7ef..0000000
--- a/bigscreen/js/echarts.min.js
+++ /dev/null
@@ -1,81525 +0,0 @@
-(function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (factory((global.echarts = {})));
-}(this, (function (exports) { 'use strict';
-
-// (1) The code `if (__DEV__) ...` can be removed by build tool.
-// (2) If intend to use `__DEV__`, this module should be imported. Use a global
-// variable `__DEV__` may cause that miss the declaration (see #6535), or the
-// declaration is behind of the using position (for example in `Model.extent`,
-// And tools like rollup can not analysis the dependency if not import).
-
-var dev;
-
-// In browser
-if (typeof window !== 'undefined') {
- dev = window.__DEV__;
-}
-// In node
-else if (typeof global !== 'undefined') {
- dev = global.__DEV__;
-}
-
-if (typeof dev === 'undefined') {
- dev = true;
-}
-
-var __DEV__ = dev;
-
-/**
- * zrender: 生成唯一id
- *
- * @author errorrik (errorrik@gmail.com)
- */
-
-var idStart = 0x0907;
-
-var guid = function () {
- return idStart++;
-};
-
-/**
- * echarts设备环境识别
- *
- * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
- * @author firede[firede@firede.us]
- * @desc thanks zepto.
- */
-
-var env = {};
-
-if (typeof wx !== 'undefined') {
- // In Weixin Application
- env = {
- browser: {},
- os: {},
- node: false,
- wxa: true, // Weixin Application
- canvasSupported: true,
- svgSupported: false,
- touchEventsSupported: true
- };
-}
-else if (typeof document === 'undefined' && typeof self !== 'undefined') {
- // In worker
- env = {
- browser: {},
- os: {},
- node: false,
- worker: true,
- canvasSupported: true
- };
-}
-else if (typeof navigator === 'undefined') {
- // In node
- env = {
- browser: {},
- os: {},
- node: true,
- worker: false,
- // Assume canvas is supported
- canvasSupported: true,
- svgSupported: true
- };
-}
-else {
- env = detect(navigator.userAgent);
-}
-
-var env$1 = env;
-
-// Zepto.js
-// (c) 2010-2013 Thomas Fuchs
-// Zepto.js may be freely distributed under the MIT license.
-
-function detect(ua) {
- var os = {};
- var browser = {};
- // var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/);
- // var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
- // var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
- // var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
- // var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
- // var webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/);
- // var touchpad = webos && ua.match(/TouchPad/);
- // var kindle = ua.match(/Kindle\/([\d.]+)/);
- // var silk = ua.match(/Silk\/([\d._]+)/);
- // var blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/);
- // var bb10 = ua.match(/(BB10).*Version\/([\d.]+)/);
- // var rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/);
- // var playbook = ua.match(/PlayBook/);
- // var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
- var firefox = ua.match(/Firefox\/([\d.]+)/);
- // var safari = webkit && ua.match(/Mobile\//) && !chrome;
- // var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome;
- var ie = ua.match(/MSIE\s([\d.]+)/)
- // IE 11 Trident/7.0; rv:11.0
- || ua.match(/Trident\/.+?rv:(([\d.]+))/);
- var edge = ua.match(/Edge\/([\d.]+)/); // IE 12 and 12+
-
- var weChat = (/micromessenger/i).test(ua);
-
- // Todo: clean this up with a better OS/browser seperation:
- // - discern (more) between multiple browsers on android
- // - decide if kindle fire in silk mode is android or not
- // - Firefox on Android doesn't specify the Android version
- // - possibly devide in os, device and browser hashes
-
- // if (browser.webkit = !!webkit) browser.version = webkit[1];
-
- // if (android) os.android = true, os.version = android[2];
- // if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.');
- // if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.');
- // if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
- // if (webos) os.webos = true, os.version = webos[2];
- // if (touchpad) os.touchpad = true;
- // if (blackberry) os.blackberry = true, os.version = blackberry[2];
- // if (bb10) os.bb10 = true, os.version = bb10[2];
- // if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2];
- // if (playbook) browser.playbook = true;
- // if (kindle) os.kindle = true, os.version = kindle[1];
- // if (silk) browser.silk = true, browser.version = silk[1];
- // if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true;
- // if (chrome) browser.chrome = true, browser.version = chrome[1];
- if (firefox) {
- browser.firefox = true;
- browser.version = firefox[1];
- }
- // if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true;
- // if (webview) browser.webview = true;
-
- if (ie) {
- browser.ie = true;
- browser.version = ie[1];
- }
-
- if (edge) {
- browser.edge = true;
- browser.version = edge[1];
- }
-
- // It is difficult to detect WeChat in Win Phone precisely, because ua can
- // not be set on win phone. So we do not consider Win Phone.
- if (weChat) {
- browser.weChat = true;
- }
-
- // os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
- // (firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)));
- // os.phone = !!(!os.tablet && !os.ipod && (android || iphone || webos ||
- // (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
- // (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))));
-
- return {
- browser: browser,
- os: os,
- node: false,
- // 原生canvas支持,改极端点了
- // canvasSupported : !(browser.ie && parseFloat(browser.version) < 9)
- canvasSupported: !!document.createElement('canvas').getContext,
- svgSupported: typeof SVGRect !== 'undefined',
- // works on most browsers
- // IE10/11 does not support touch event, and MS Edge supports them but not by
- // default, so we dont check navigator.maxTouchPoints for them here.
- touchEventsSupported: 'ontouchstart' in window && !browser.ie && !browser.edge,
- // .
- pointerEventsSupported: 'onpointerdown' in window
- // Firefox supports pointer but not by default, only MS browsers are reliable on pointer
- // events currently. So we dont use that on other browsers unless tested sufficiently.
- // Although IE 10 supports pointer event, it use old style and is different from the
- // standard. So we exclude that. (IE 10 is hardly used on touch device)
- && (browser.edge || (browser.ie && browser.version >= 11))
- // passiveSupported: detectPassiveSupport()
- };
-}
-
-// See https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection
-// function detectPassiveSupport() {
-// // Test via a getter in the options object to see if the passive property is accessed
-// var supportsPassive = false;
-// try {
-// var opts = Object.defineProperty({}, 'passive', {
-// get: function() {
-// supportsPassive = true;
-// }
-// });
-// window.addEventListener('testPassive', function() {}, opts);
-// } catch (e) {
-// }
-// return supportsPassive;
-// }
-
-/**
- * @module zrender/core/util
- */
-
-// 用于处理merge时无法遍历Date等对象的问题
-var BUILTIN_OBJECT = {
- '[object Function]': 1,
- '[object RegExp]': 1,
- '[object Date]': 1,
- '[object Error]': 1,
- '[object CanvasGradient]': 1,
- '[object CanvasPattern]': 1,
- // For node-canvas
- '[object Image]': 1,
- '[object Canvas]': 1
-};
-
-var TYPED_ARRAY = {
- '[object Int8Array]': 1,
- '[object Uint8Array]': 1,
- '[object Uint8ClampedArray]': 1,
- '[object Int16Array]': 1,
- '[object Uint16Array]': 1,
- '[object Int32Array]': 1,
- '[object Uint32Array]': 1,
- '[object Float32Array]': 1,
- '[object Float64Array]': 1
-};
-
-var objToString = Object.prototype.toString;
-
-var arrayProto = Array.prototype;
-var nativeForEach = arrayProto.forEach;
-var nativeFilter = arrayProto.filter;
-var nativeSlice = arrayProto.slice;
-var nativeMap = arrayProto.map;
-var nativeReduce = arrayProto.reduce;
-
-// Avoid assign to an exported variable, for transforming to cjs.
-var methods = {};
-
-function $override(name, fn) {
- // Clear ctx instance for different environment
- if (name === 'createCanvas') {
- _ctx = null;
- }
-
- methods[name] = fn;
-}
-
-/**
- * Those data types can be cloned:
- * Plain object, Array, TypedArray, number, string, null, undefined.
- * Those data types will be assgined using the orginal data:
- * BUILTIN_OBJECT
- * Instance of user defined class will be cloned to a plain object, without
- * properties in prototype.
- * Other data types is not supported (not sure what will happen).
- *
- * Caution: do not support clone Date, for performance consideration.
- * (There might be a large number of date in `series.data`).
- * So date should not be modified in and out of echarts.
- *
- * @param {*} source
- * @return {*} new
- */
-function clone(source) {
- if (source == null || typeof source != 'object') {
- return source;
- }
-
- var result = source;
- var typeStr = objToString.call(source);
-
- if (typeStr === '[object Array]') {
- if (!isPrimitive(source)) {
- result = [];
- for (var i = 0, len = source.length; i < len; i++) {
- result[i] = clone(source[i]);
- }
- }
- }
- else if (TYPED_ARRAY[typeStr]) {
- if (!isPrimitive(source)) {
- var Ctor = source.constructor;
- if (source.constructor.from) {
- result = Ctor.from(source);
- }
- else {
- result = new Ctor(source.length);
- for (var i = 0, len = source.length; i < len; i++) {
- result[i] = clone(source[i]);
- }
- }
- }
- }
- else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) {
- result = {};
- for (var key in source) {
- if (source.hasOwnProperty(key)) {
- result[key] = clone(source[key]);
- }
- }
- }
-
- return result;
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {*} target
- * @param {*} source
- * @param {boolean} [overwrite=false]
- */
-function merge(target, source, overwrite) {
- // We should escapse that source is string
- // and enter for ... in ...
- if (!isObject$1(source) || !isObject$1(target)) {
- return overwrite ? clone(source) : target;
- }
-
- for (var key in source) {
- if (source.hasOwnProperty(key)) {
- var targetProp = target[key];
- var sourceProp = source[key];
-
- if (isObject$1(sourceProp)
- && isObject$1(targetProp)
- && !isArray(sourceProp)
- && !isArray(targetProp)
- && !isDom(sourceProp)
- && !isDom(targetProp)
- && !isBuiltInObject(sourceProp)
- && !isBuiltInObject(targetProp)
- && !isPrimitive(sourceProp)
- && !isPrimitive(targetProp)
- ) {
- // 如果需要递归覆盖,就递归调用merge
- merge(targetProp, sourceProp, overwrite);
- }
- else if (overwrite || !(key in target)) {
- // 否则只处理overwrite为true,或者在目标对象中没有此属性的情况
- // NOTE,在 target[key] 不存在的时候也是直接覆盖
- target[key] = clone(source[key], true);
- }
- }
- }
-
- return target;
-}
-
-/**
- * @param {Array} targetAndSources The first item is target, and the rests are source.
- * @param {boolean} [overwrite=false]
- * @return {*} target
- */
-function mergeAll(targetAndSources, overwrite) {
- var result = targetAndSources[0];
- for (var i = 1, len = targetAndSources.length; i < len; i++) {
- result = merge(result, targetAndSources[i], overwrite);
- }
- return result;
-}
-
-/**
- * @param {*} target
- * @param {*} source
- * @memberOf module:zrender/core/util
- */
-function extend(target, source) {
- for (var key in source) {
- if (source.hasOwnProperty(key)) {
- target[key] = source[key];
- }
- }
- return target;
-}
-
-/**
- * @param {*} target
- * @param {*} source
- * @param {boolean} [overlay=false]
- * @memberOf module:zrender/core/util
- */
-function defaults(target, source, overlay) {
- for (var key in source) {
- if (source.hasOwnProperty(key)
- && (overlay ? source[key] != null : target[key] == null)
- ) {
- target[key] = source[key];
- }
- }
- return target;
-}
-
-var createCanvas = function () {
- return methods.createCanvas();
-};
-
-methods.createCanvas = function () {
- return document.createElement('canvas');
-};
-
-// FIXME
-var _ctx;
-
-function getContext() {
- if (!_ctx) {
- // Use util.createCanvas instead of createCanvas
- // because createCanvas may be overwritten in different environment
- _ctx = createCanvas().getContext('2d');
- }
- return _ctx;
-}
-
-/**
- * 查询数组中元素的index
- * @memberOf module:zrender/core/util
- */
-function indexOf(array, value) {
- if (array) {
- if (array.indexOf) {
- return array.indexOf(value);
- }
- for (var i = 0, len = array.length; i < len; i++) {
- if (array[i] === value) {
- return i;
- }
- }
- }
- return -1;
-}
-
-/**
- * 构造类继承关系
- *
- * @memberOf module:zrender/core/util
- * @param {Function} clazz 源类
- * @param {Function} baseClazz 基类
- */
-function inherits(clazz, baseClazz) {
- var clazzPrototype = clazz.prototype;
- function F() {}
- F.prototype = baseClazz.prototype;
- clazz.prototype = new F();
-
- for (var prop in clazzPrototype) {
- clazz.prototype[prop] = clazzPrototype[prop];
- }
- clazz.prototype.constructor = clazz;
- clazz.superClass = baseClazz;
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {Object|Function} target
- * @param {Object|Function} sorce
- * @param {boolean} overlay
- */
-function mixin(target, source, overlay) {
- target = 'prototype' in target ? target.prototype : target;
- source = 'prototype' in source ? source.prototype : source;
-
- defaults(target, source, overlay);
-}
-
-/**
- * Consider typed array.
- * @param {Array|TypedArray} data
- */
-function isArrayLike(data) {
- if (! data) {
- return;
- }
- if (typeof data == 'string') {
- return false;
- }
- return typeof data.length == 'number';
-}
-
-/**
- * 数组或对象遍历
- * @memberOf module:zrender/core/util
- * @param {Object|Array} obj
- * @param {Function} cb
- * @param {*} [context]
- */
-function each$1(obj, cb, context) {
- if (!(obj && cb)) {
- return;
- }
- if (obj.forEach && obj.forEach === nativeForEach) {
- obj.forEach(cb, context);
- }
- else if (obj.length === +obj.length) {
- for (var i = 0, len = obj.length; i < len; i++) {
- cb.call(context, obj[i], i, obj);
- }
- }
- else {
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- cb.call(context, obj[key], key, obj);
- }
- }
- }
-}
-
-/**
- * 数组映射
- * @memberOf module:zrender/core/util
- * @param {Array} obj
- * @param {Function} cb
- * @param {*} [context]
- * @return {Array}
- */
-function map(obj, cb, context) {
- if (!(obj && cb)) {
- return;
- }
- if (obj.map && obj.map === nativeMap) {
- return obj.map(cb, context);
- }
- else {
- var result = [];
- for (var i = 0, len = obj.length; i < len; i++) {
- result.push(cb.call(context, obj[i], i, obj));
- }
- return result;
- }
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {Array} obj
- * @param {Function} cb
- * @param {Object} [memo]
- * @param {*} [context]
- * @return {Array}
- */
-function reduce(obj, cb, memo, context) {
- if (!(obj && cb)) {
- return;
- }
- if (obj.reduce && obj.reduce === nativeReduce) {
- return obj.reduce(cb, memo, context);
- }
- else {
- for (var i = 0, len = obj.length; i < len; i++) {
- memo = cb.call(context, memo, obj[i], i, obj);
- }
- return memo;
- }
-}
-
-/**
- * 数组过滤
- * @memberOf module:zrender/core/util
- * @param {Array} obj
- * @param {Function} cb
- * @param {*} [context]
- * @return {Array}
- */
-function filter(obj, cb, context) {
- if (!(obj && cb)) {
- return;
- }
- if (obj.filter && obj.filter === nativeFilter) {
- return obj.filter(cb, context);
- }
- else {
- var result = [];
- for (var i = 0, len = obj.length; i < len; i++) {
- if (cb.call(context, obj[i], i, obj)) {
- result.push(obj[i]);
- }
- }
- return result;
- }
-}
-
-/**
- * 数组项查找
- * @memberOf module:zrender/core/util
- * @param {Array} obj
- * @param {Function} cb
- * @param {*} [context]
- * @return {*}
- */
-function find(obj, cb, context) {
- if (!(obj && cb)) {
- return;
- }
- for (var i = 0, len = obj.length; i < len; i++) {
- if (cb.call(context, obj[i], i, obj)) {
- return obj[i];
- }
- }
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {Function} func
- * @param {*} context
- * @return {Function}
- */
-function bind(func, context) {
- var args = nativeSlice.call(arguments, 2);
- return function () {
- return func.apply(context, args.concat(nativeSlice.call(arguments)));
- };
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {Function} func
- * @return {Function}
- */
-function curry(func) {
- var args = nativeSlice.call(arguments, 1);
- return function () {
- return func.apply(this, args.concat(nativeSlice.call(arguments)));
- };
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {*} value
- * @return {boolean}
- */
-function isArray(value) {
- return objToString.call(value) === '[object Array]';
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {*} value
- * @return {boolean}
- */
-function isFunction$1(value) {
- return typeof value === 'function';
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {*} value
- * @return {boolean}
- */
-function isString(value) {
- return objToString.call(value) === '[object String]';
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {*} value
- * @return {boolean}
- */
-function isObject$1(value) {
- // Avoid a V8 JIT bug in Chrome 19-20.
- // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
- var type = typeof value;
- return type === 'function' || (!!value && type == 'object');
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {*} value
- * @return {boolean}
- */
-function isBuiltInObject(value) {
- return !!BUILTIN_OBJECT[objToString.call(value)];
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {*} value
- * @return {boolean}
- */
-function isTypedArray(value) {
- return !!TYPED_ARRAY[objToString.call(value)];
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {*} value
- * @return {boolean}
- */
-function isDom(value) {
- return typeof value === 'object'
- && typeof value.nodeType === 'number'
- && typeof value.ownerDocument === 'object';
-}
-
-/**
- * Whether is exactly NaN. Notice isNaN('a') returns true.
- * @param {*} value
- * @return {boolean}
- */
-function eqNaN(value) {
- return value !== value;
-}
-
-/**
- * If value1 is not null, then return value1, otherwise judget rest of values.
- * Low performance.
- * @memberOf module:zrender/core/util
- * @return {*} Final value
- */
-function retrieve(values) {
- for (var i = 0, len = arguments.length; i < len; i++) {
- if (arguments[i] != null) {
- return arguments[i];
- }
- }
-}
-
-function retrieve2(value0, value1) {
- return value0 != null
- ? value0
- : value1;
-}
-
-function retrieve3(value0, value1, value2) {
- return value0 != null
- ? value0
- : value1 != null
- ? value1
- : value2;
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {Array} arr
- * @param {number} startIndex
- * @param {number} endIndex
- * @return {Array}
- */
-function slice() {
- return Function.call.apply(nativeSlice, arguments);
-}
-
-/**
- * Normalize css liked array configuration
- * e.g.
- * 3 => [3, 3, 3, 3]
- * [4, 2] => [4, 2, 4, 2]
- * [4, 3, 2] => [4, 3, 2, 3]
- * @param {number|Array.} val
- * @return {Array.}
- */
-function normalizeCssArray(val) {
- if (typeof (val) === 'number') {
- return [val, val, val, val];
- }
- var len = val.length;
- if (len === 2) {
- // vertical | horizontal
- return [val[0], val[1], val[0], val[1]];
- }
- else if (len === 3) {
- // top | horizontal | bottom
- return [val[0], val[1], val[2], val[1]];
- }
- return val;
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {boolean} condition
- * @param {string} message
- */
-function assert$1(condition, message) {
- if (!condition) {
- throw new Error(message);
- }
-}
-
-/**
- * @memberOf module:zrender/core/util
- * @param {string} str string to be trimed
- * @return {string} trimed string
- */
-function trim(str) {
- if (str == null) {
- return null;
- }
- else if (typeof str.trim === 'function') {
- return str.trim();
- }
- else {
- return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
- }
-}
-
-var primitiveKey = '__ec_primitive__';
-/**
- * Set an object as primitive to be ignored traversing children in clone or merge
- */
-function setAsPrimitive(obj) {
- obj[primitiveKey] = true;
-}
-
-function isPrimitive(obj) {
- return obj[primitiveKey];
-}
-
-/**
- * @constructor
- * @param {Object} obj Only apply `ownProperty`.
- */
-function HashMap(obj) {
- var isArr = isArray(obj);
- var thisMap = this;
-
- (obj instanceof HashMap)
- ? obj.each(visit)
- : (obj && each$1(obj, visit));
-
- function visit(value, key) {
- isArr ? thisMap.set(value, key) : thisMap.set(key, value);
- }
-}
-
-// Add prefix to avoid conflict with Object.prototype.
-
-HashMap.prototype = {
- constructor: HashMap,
- // Do not provide `has` method to avoid defining what is `has`.
- // (We usually treat `null` and `undefined` as the same, different
- // from ES6 Map).
- get: function (key) {
- return this.hasOwnProperty(key) ? this[key] : null;
- },
- set: function (key, value) {
- // Comparing with invocation chaining, `return value` is more commonly
- // used in this case: `var someVal = map.set('a', genVal());`
- return (this[key] = value);
- },
- // Although util.each can be performed on this hashMap directly, user
- // should not use the exposed keys, who are prefixed.
- each: function (cb, context) {
- context !== void 0 && (cb = bind(cb, context));
- for (var key in this) {
- this.hasOwnProperty(key) && cb(this[key], key);
- }
- },
- // Do not use this method if performance sensitive.
- removeKey: function (key) {
- delete this[key];
- }
-};
-
-function createHashMap(obj) {
- return new HashMap(obj);
-}
-
-function concatArray(a, b) {
- var newArray = new a.constructor(a.length + b.length);
- for (var i = 0; i < a.length; i++) {
- newArray[i] = a[i];
- }
- var offset = a.length;
- for (i = 0; i < b.length; i++) {
- newArray[i + offset] = b[i];
- }
- return newArray;
-}
-
-
-function noop() {}
-
-
-var zrUtil = (Object.freeze || Object)({
- $override: $override,
- clone: clone,
- merge: merge,
- mergeAll: mergeAll,
- extend: extend,
- defaults: defaults,
- createCanvas: createCanvas,
- getContext: getContext,
- indexOf: indexOf,
- inherits: inherits,
- mixin: mixin,
- isArrayLike: isArrayLike,
- each: each$1,
- map: map,
- reduce: reduce,
- filter: filter,
- find: find,
- bind: bind,
- curry: curry,
- isArray: isArray,
- isFunction: isFunction$1,
- isString: isString,
- isObject: isObject$1,
- isBuiltInObject: isBuiltInObject,
- isTypedArray: isTypedArray,
- isDom: isDom,
- eqNaN: eqNaN,
- retrieve: retrieve,
- retrieve2: retrieve2,
- retrieve3: retrieve3,
- slice: slice,
- normalizeCssArray: normalizeCssArray,
- assert: assert$1,
- trim: trim,
- setAsPrimitive: setAsPrimitive,
- isPrimitive: isPrimitive,
- createHashMap: createHashMap,
- concatArray: concatArray,
- noop: noop
-});
-
-var ArrayCtor = typeof Float32Array === 'undefined'
- ? Array
- : Float32Array;
-
-/**
- * 创建一个向量
- * @param {number} [x=0]
- * @param {number} [y=0]
- * @return {Vector2}
- */
-function create(x, y) {
- var out = new ArrayCtor(2);
- if (x == null) {
- x = 0;
- }
- if (y == null) {
- y = 0;
- }
- out[0] = x;
- out[1] = y;
- return out;
-}
-
-/**
- * 复制向量数据
- * @param {Vector2} out
- * @param {Vector2} v
- * @return {Vector2}
- */
-function copy(out, v) {
- out[0] = v[0];
- out[1] = v[1];
- return out;
-}
-
-/**
- * 克隆一个向量
- * @param {Vector2} v
- * @return {Vector2}
- */
-function clone$1(v) {
- var out = new ArrayCtor(2);
- out[0] = v[0];
- out[1] = v[1];
- return out;
-}
-
-/**
- * 设置向量的两个项
- * @param {Vector2} out
- * @param {number} a
- * @param {number} b
- * @return {Vector2} 结果
- */
-function set(out, a, b) {
- out[0] = a;
- out[1] = b;
- return out;
-}
-
-/**
- * 向量相加
- * @param {Vector2} out
- * @param {Vector2} v1
- * @param {Vector2} v2
- */
-function add(out, v1, v2) {
- out[0] = v1[0] + v2[0];
- out[1] = v1[1] + v2[1];
- return out;
-}
-
-/**
- * 向量缩放后相加
- * @param {Vector2} out
- * @param {Vector2} v1
- * @param {Vector2} v2
- * @param {number} a
- */
-function scaleAndAdd(out, v1, v2, a) {
- out[0] = v1[0] + v2[0] * a;
- out[1] = v1[1] + v2[1] * a;
- return out;
-}
-
-/**
- * 向量相减
- * @param {Vector2} out
- * @param {Vector2} v1
- * @param {Vector2} v2
- */
-function sub(out, v1, v2) {
- out[0] = v1[0] - v2[0];
- out[1] = v1[1] - v2[1];
- return out;
-}
-
-/**
- * 向量长度
- * @param {Vector2} v
- * @return {number}
- */
-function len(v) {
- return Math.sqrt(lenSquare(v));
-}
-var length = len; // jshint ignore:line
-
-/**
- * 向量长度平方
- * @param {Vector2} v
- * @return {number}
- */
-function lenSquare(v) {
- return v[0] * v[0] + v[1] * v[1];
-}
-var lengthSquare = lenSquare;
-
-/**
- * 向量乘法
- * @param {Vector2} out
- * @param {Vector2} v1
- * @param {Vector2} v2
- */
-function mul(out, v1, v2) {
- out[0] = v1[0] * v2[0];
- out[1] = v1[1] * v2[1];
- return out;
-}
-
-/**
- * 向量除法
- * @param {Vector2} out
- * @param {Vector2} v1
- * @param {Vector2} v2
- */
-function div(out, v1, v2) {
- out[0] = v1[0] / v2[0];
- out[1] = v1[1] / v2[1];
- return out;
-}
-
-/**
- * 向量点乘
- * @param {Vector2} v1
- * @param {Vector2} v2
- * @return {number}
- */
-function dot(v1, v2) {
- return v1[0] * v2[0] + v1[1] * v2[1];
-}
-
-/**
- * 向量缩放
- * @param {Vector2} out
- * @param {Vector2} v
- * @param {number} s
- */
-function scale(out, v, s) {
- out[0] = v[0] * s;
- out[1] = v[1] * s;
- return out;
-}
-
-/**
- * 向量归一化
- * @param {Vector2} out
- * @param {Vector2} v
- */
-function normalize(out, v) {
- var d = len(v);
- if (d === 0) {
- out[0] = 0;
- out[1] = 0;
- }
- else {
- out[0] = v[0] / d;
- out[1] = v[1] / d;
- }
- return out;
-}
-
-/**
- * 计算向量间距离
- * @param {Vector2} v1
- * @param {Vector2} v2
- * @return {number}
- */
-function distance(v1, v2) {
- return Math.sqrt(
- (v1[0] - v2[0]) * (v1[0] - v2[0])
- + (v1[1] - v2[1]) * (v1[1] - v2[1])
- );
-}
-var dist = distance;
-
-/**
- * 向量距离平方
- * @param {Vector2} v1
- * @param {Vector2} v2
- * @return {number}
- */
-function distanceSquare(v1, v2) {
- return (v1[0] - v2[0]) * (v1[0] - v2[0])
- + (v1[1] - v2[1]) * (v1[1] - v2[1]);
-}
-var distSquare = distanceSquare;
-
-/**
- * 求负向量
- * @param {Vector2} out
- * @param {Vector2} v
- */
-function negate(out, v) {
- out[0] = -v[0];
- out[1] = -v[1];
- return out;
-}
-
-/**
- * 插值两个点
- * @param {Vector2} out
- * @param {Vector2} v1
- * @param {Vector2} v2
- * @param {number} t
- */
-function lerp(out, v1, v2, t) {
- out[0] = v1[0] + t * (v2[0] - v1[0]);
- out[1] = v1[1] + t * (v2[1] - v1[1]);
- return out;
-}
-
-/**
- * 矩阵左乘向量
- * @param {Vector2} out
- * @param {Vector2} v
- * @param {Vector2} m
- */
-function applyTransform(out, v, m) {
- var x = v[0];
- var y = v[1];
- out[0] = m[0] * x + m[2] * y + m[4];
- out[1] = m[1] * x + m[3] * y + m[5];
- return out;
-}
-
-/**
- * 求两个向量最小值
- * @param {Vector2} out
- * @param {Vector2} v1
- * @param {Vector2} v2
- */
-function min(out, v1, v2) {
- out[0] = Math.min(v1[0], v2[0]);
- out[1] = Math.min(v1[1], v2[1]);
- return out;
-}
-
-/**
- * 求两个向量最大值
- * @param {Vector2} out
- * @param {Vector2} v1
- * @param {Vector2} v2
- */
-function max(out, v1, v2) {
- out[0] = Math.max(v1[0], v2[0]);
- out[1] = Math.max(v1[1], v2[1]);
- return out;
-}
-
-
-var vector = (Object.freeze || Object)({
- create: create,
- copy: copy,
- clone: clone$1,
- set: set,
- add: add,
- scaleAndAdd: scaleAndAdd,
- sub: sub,
- len: len,
- length: length,
- lenSquare: lenSquare,
- lengthSquare: lengthSquare,
- mul: mul,
- div: div,
- dot: dot,
- scale: scale,
- normalize: normalize,
- distance: distance,
- dist: dist,
- distanceSquare: distanceSquare,
- distSquare: distSquare,
- negate: negate,
- lerp: lerp,
- applyTransform: applyTransform,
- min: min,
- max: max
-});
-
-// TODO Draggable for group
-// FIXME Draggable on element which has parent rotation or scale
-function Draggable() {
-
- this.on('mousedown', this._dragStart, this);
- this.on('mousemove', this._drag, this);
- this.on('mouseup', this._dragEnd, this);
- this.on('globalout', this._dragEnd, this);
- // this._dropTarget = null;
- // this._draggingTarget = null;
-
- // this._x = 0;
- // this._y = 0;
-}
-
-Draggable.prototype = {
-
- constructor: Draggable,
-
- _dragStart: function (e) {
- var draggingTarget = e.target;
- if (draggingTarget && draggingTarget.draggable) {
- this._draggingTarget = draggingTarget;
- draggingTarget.dragging = true;
- this._x = e.offsetX;
- this._y = e.offsetY;
-
- this.dispatchToElement(param(draggingTarget, e), 'dragstart', e.event);
- }
- },
-
- _drag: function (e) {
- var draggingTarget = this._draggingTarget;
- if (draggingTarget) {
-
- var x = e.offsetX;
- var y = e.offsetY;
-
- var dx = x - this._x;
- var dy = y - this._y;
- this._x = x;
- this._y = y;
-
- draggingTarget.drift(dx, dy, e);
- this.dispatchToElement(param(draggingTarget, e), 'drag', e.event);
-
- var dropTarget = this.findHover(x, y, draggingTarget).target;
- var lastDropTarget = this._dropTarget;
- this._dropTarget = dropTarget;
-
- if (draggingTarget !== dropTarget) {
- if (lastDropTarget && dropTarget !== lastDropTarget) {
- this.dispatchToElement(param(lastDropTarget, e), 'dragleave', e.event);
- }
- if (dropTarget && dropTarget !== lastDropTarget) {
- this.dispatchToElement(param(dropTarget, e), 'dragenter', e.event);
- }
- }
- }
- },
-
- _dragEnd: function (e) {
- var draggingTarget = this._draggingTarget;
-
- if (draggingTarget) {
- draggingTarget.dragging = false;
- }
-
- this.dispatchToElement(param(draggingTarget, e), 'dragend', e.event);
-
- if (this._dropTarget) {
- this.dispatchToElement(param(this._dropTarget, e), 'drop', e.event);
- }
-
- this._draggingTarget = null;
- this._dropTarget = null;
- }
-
-};
-
-function param(target, e) {
- return {target: target, topTarget: e && e.topTarget};
-}
-
-/**
- * 事件扩展
- * @module zrender/mixin/Eventful
- * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
- * pissang (https://www.github.com/pissang)
- */
-
-var arrySlice = Array.prototype.slice;
-
-/**
- * 事件分发器
- * @alias module:zrender/mixin/Eventful
- * @constructor
- */
-var Eventful = function () {
- this._$handlers = {};
-};
-
-Eventful.prototype = {
-
- constructor: Eventful,
-
- /**
- * 单次触发绑定,trigger后销毁
- *
- * @param {string} event 事件名
- * @param {Function} handler 响应函数
- * @param {Object} context
- */
- one: function (event, handler, context) {
- var _h = this._$handlers;
-
- if (!handler || !event) {
- return this;
- }
-
- if (!_h[event]) {
- _h[event] = [];
- }
-
- for (var i = 0; i < _h[event].length; i++) {
- if (_h[event][i].h === handler) {
- return this;
- }
- }
-
- _h[event].push({
- h: handler,
- one: true,
- ctx: context || this
- });
-
- return this;
- },
-
- /**
- * 绑定事件
- * @param {string} event 事件名
- * @param {Function} handler 事件处理函数
- * @param {Object} [context]
- */
- on: function (event, handler, context) {
- var _h = this._$handlers;
-
- if (!handler || !event) {
- return this;
- }
-
- if (!_h[event]) {
- _h[event] = [];
- }
-
- for (var i = 0; i < _h[event].length; i++) {
- if (_h[event][i].h === handler) {
- return this;
- }
- }
-
- _h[event].push({
- h: handler,
- one: false,
- ctx: context || this
- });
-
- return this;
- },
-
- /**
- * 是否绑定了事件
- * @param {string} event
- * @return {boolean}
- */
- isSilent: function (event) {
- var _h = this._$handlers;
- return _h[event] && _h[event].length;
- },
-
- /**
- * 解绑事件
- * @param {string} event 事件名
- * @param {Function} [handler] 事件处理函数
- */
- off: function (event, handler) {
- var _h = this._$handlers;
-
- if (!event) {
- this._$handlers = {};
- return this;
- }
-
- if (handler) {
- if (_h[event]) {
- var newList = [];
- for (var i = 0, l = _h[event].length; i < l; i++) {
- if (_h[event][i]['h'] != handler) {
- newList.push(_h[event][i]);
- }
- }
- _h[event] = newList;
- }
-
- if (_h[event] && _h[event].length === 0) {
- delete _h[event];
- }
- }
- else {
- delete _h[event];
- }
-
- return this;
- },
-
- /**
- * 事件分发
- *
- * @param {string} type 事件类型
- */
- trigger: function (type) {
- if (this._$handlers[type]) {
- var args = arguments;
- var argLen = args.length;
-
- if (argLen > 3) {
- args = arrySlice.call(args, 1);
- }
-
- var _h = this._$handlers[type];
- var len = _h.length;
- for (var i = 0; i < len;) {
- // Optimize advise from backbone
- switch (argLen) {
- case 1:
- _h[i]['h'].call(_h[i]['ctx']);
- break;
- case 2:
- _h[i]['h'].call(_h[i]['ctx'], args[1]);
- break;
- case 3:
- _h[i]['h'].call(_h[i]['ctx'], args[1], args[2]);
- break;
- default:
- // have more than 2 given arguments
- _h[i]['h'].apply(_h[i]['ctx'], args);
- break;
- }
-
- if (_h[i]['one']) {
- _h.splice(i, 1);
- len--;
- }
- else {
- i++;
- }
- }
- }
-
- return this;
- },
-
- /**
- * 带有context的事件分发, 最后一个参数是事件回调的context
- * @param {string} type 事件类型
- */
- triggerWithContext: function (type) {
- if (this._$handlers[type]) {
- var args = arguments;
- var argLen = args.length;
-
- if (argLen > 4) {
- args = arrySlice.call(args, 1, args.length - 1);
- }
- var ctx = args[args.length - 1];
-
- var _h = this._$handlers[type];
- var len = _h.length;
- for (var i = 0; i < len;) {
- // Optimize advise from backbone
- switch (argLen) {
- case 1:
- _h[i]['h'].call(ctx);
- break;
- case 2:
- _h[i]['h'].call(ctx, args[1]);
- break;
- case 3:
- _h[i]['h'].call(ctx, args[1], args[2]);
- break;
- default:
- // have more than 2 given arguments
- _h[i]['h'].apply(ctx, args);
- break;
- }
-
- if (_h[i]['one']) {
- _h.splice(i, 1);
- len--;
- }
- else {
- i++;
- }
- }
- }
-
- return this;
- }
-};
-
-var SILENT = 'silent';
-
-function makeEventPacket(eveType, targetInfo, event) {
- return {
- type: eveType,
- event: event,
- // target can only be an element that is not silent.
- target: targetInfo.target,
- // topTarget can be a silent element.
- topTarget: targetInfo.topTarget,
- cancelBubble: false,
- offsetX: event.zrX,
- offsetY: event.zrY,
- gestureEvent: event.gestureEvent,
- pinchX: event.pinchX,
- pinchY: event.pinchY,
- pinchScale: event.pinchScale,
- wheelDelta: event.zrDelta,
- zrByTouch: event.zrByTouch,
- which: event.which
- };
-}
-
-function EmptyProxy () {}
-EmptyProxy.prototype.dispose = function () {};
-
-var handlerNames = [
- 'click', 'dblclick', 'mousewheel', 'mouseout',
- 'mouseup', 'mousedown', 'mousemove', 'contextmenu'
-];
-/**
- * @alias module:zrender/Handler
- * @constructor
- * @extends module:zrender/mixin/Eventful
- * @param {module:zrender/Storage} storage Storage instance.
- * @param {module:zrender/Painter} painter Painter instance.
- * @param {module:zrender/dom/HandlerProxy} proxy HandlerProxy instance.
- * @param {HTMLElement} painterRoot painter.root (not painter.getViewportRoot()).
- */
-var Handler = function(storage, painter, proxy, painterRoot) {
- Eventful.call(this);
-
- this.storage = storage;
-
- this.painter = painter;
-
- this.painterRoot = painterRoot;
-
- proxy = proxy || new EmptyProxy();
-
- /**
- * Proxy of event. can be Dom, WebGLSurface, etc.
- */
- this.proxy = null;
-
- /**
- * {target, topTarget, x, y}
- * @private
- * @type {Object}
- */
- this._hovered = {};
-
- /**
- * @private
- * @type {Date}
- */
- this._lastTouchMoment;
-
- /**
- * @private
- * @type {number}
- */
- this._lastX;
-
- /**
- * @private
- * @type {number}
- */
- this._lastY;
-
-
- Draggable.call(this);
-
- this.setHandlerProxy(proxy);
-};
-
-Handler.prototype = {
-
- constructor: Handler,
-
- setHandlerProxy: function (proxy) {
- if (this.proxy) {
- this.proxy.dispose();
- }
-
- if (proxy) {
- each$1(handlerNames, function (name) {
- proxy.on && proxy.on(name, this[name], this);
- }, this);
- // Attach handler
- proxy.handler = this;
- }
- this.proxy = proxy;
- },
-
- mousemove: function (event) {
- var x = event.zrX;
- var y = event.zrY;
-
- var lastHovered = this._hovered;
- var lastHoveredTarget = lastHovered.target;
-
- // If lastHoveredTarget is removed from zr (detected by '__zr') by some API call
- // (like 'setOption' or 'dispatchAction') in event handlers, we should find
- // lastHovered again here. Otherwise 'mouseout' can not be triggered normally.
- // See #6198.
- if (lastHoveredTarget && !lastHoveredTarget.__zr) {
- lastHovered = this.findHover(lastHovered.x, lastHovered.y);
- lastHoveredTarget = lastHovered.target;
- }
-
- var hovered = this._hovered = this.findHover(x, y);
- var hoveredTarget = hovered.target;
-
- var proxy = this.proxy;
- proxy.setCursor && proxy.setCursor(hoveredTarget ? hoveredTarget.cursor : 'default');
-
- // Mouse out on previous hovered element
- if (lastHoveredTarget && hoveredTarget !== lastHoveredTarget) {
- this.dispatchToElement(lastHovered, 'mouseout', event);
- }
-
- // Mouse moving on one element
- this.dispatchToElement(hovered, 'mousemove', event);
-
- // Mouse over on a new element
- if (hoveredTarget && hoveredTarget !== lastHoveredTarget) {
- this.dispatchToElement(hovered, 'mouseover', event);
- }
- },
-
- mouseout: function (event) {
- this.dispatchToElement(this._hovered, 'mouseout', event);
-
- // There might be some doms created by upper layer application
- // at the same level of painter.getViewportRoot() (e.g., tooltip
- // dom created by echarts), where 'globalout' event should not
- // be triggered when mouse enters these doms. (But 'mouseout'
- // should be triggered at the original hovered element as usual).
- var element = event.toElement || event.relatedTarget;
- var innerDom;
- do {
- element = element && element.parentNode;
- }
- while (element && element.nodeType != 9 && !(
- innerDom = element === this.painterRoot
- ));
-
- !innerDom && this.trigger('globalout', {event: event});
- },
-
- /**
- * Resize
- */
- resize: function (event) {
- this._hovered = {};
- },
-
- /**
- * Dispatch event
- * @param {string} eventName
- * @param {event=} eventArgs
- */
- dispatch: function (eventName, eventArgs) {
- var handler = this[eventName];
- handler && handler.call(this, eventArgs);
- },
-
- /**
- * Dispose
- */
- dispose: function () {
-
- this.proxy.dispose();
-
- this.storage =
- this.proxy =
- this.painter = null;
- },
-
- /**
- * 设置默认的cursor style
- * @param {string} [cursorStyle='default'] 例如 crosshair
- */
- setCursorStyle: function (cursorStyle) {
- var proxy = this.proxy;
- proxy.setCursor && proxy.setCursor(cursorStyle);
- },
-
- /**
- * 事件分发代理
- *
- * @private
- * @param {Object} targetInfo {target, topTarget} 目标图形元素
- * @param {string} eventName 事件名称
- * @param {Object} event 事件对象
- */
- dispatchToElement: function (targetInfo, eventName, event) {
- targetInfo = targetInfo || {};
- var el = targetInfo.target;
- if (el && el.silent) {
- return;
- }
- var eventHandler = 'on' + eventName;
- var eventPacket = makeEventPacket(eventName, targetInfo, event);
-
- while (el) {
- el[eventHandler]
- && (eventPacket.cancelBubble = el[eventHandler].call(el, eventPacket));
-
- el.trigger(eventName, eventPacket);
-
- el = el.parent;
-
- if (eventPacket.cancelBubble) {
- break;
- }
- }
-
- if (!eventPacket.cancelBubble) {
- // 冒泡到顶级 zrender 对象
- this.trigger(eventName, eventPacket);
- // 分发事件到用户自定义层
- // 用户有可能在全局 click 事件中 dispose,所以需要判断下 painter 是否存在
- this.painter && this.painter.eachOtherLayer(function (layer) {
- if (typeof(layer[eventHandler]) == 'function') {
- layer[eventHandler].call(layer, eventPacket);
- }
- if (layer.trigger) {
- layer.trigger(eventName, eventPacket);
- }
- });
- }
- },
-
- /**
- * @private
- * @param {number} x
- * @param {number} y
- * @param {module:zrender/graphic/Displayable} exclude
- * @return {model:zrender/Element}
- * @method
- */
- findHover: function(x, y, exclude) {
- var list = this.storage.getDisplayList();
- var out = {x: x, y: y};
-
- for (var i = list.length - 1; i >= 0 ; i--) {
- var hoverCheckResult;
- if (list[i] !== exclude
- // getDisplayList may include ignored item in VML mode
- && !list[i].ignore
- && (hoverCheckResult = isHover(list[i], x, y))
- ) {
- !out.topTarget && (out.topTarget = list[i]);
- if (hoverCheckResult !== SILENT) {
- out.target = list[i];
- break;
- }
- }
- }
-
- return out;
- }
-};
-
-// Common handlers
-each$1(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
- Handler.prototype[name] = function (event) {
- // Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover
- var hovered = this.findHover(event.zrX, event.zrY);
- var hoveredTarget = hovered.target;
-
- if (name === 'mousedown') {
- this._downEl = hoveredTarget;
- this._downPoint = [event.zrX, event.zrY];
- // In case click triggered before mouseup
- this._upEl = hoveredTarget;
- }
- else if (name === 'mouseup') {
- this._upEl = hoveredTarget;
- }
- else if (name === 'click') {
- if (this._downEl !== this._upEl
- // Original click event is triggered on the whole canvas element,
- // including the case that `mousedown` - `mousemove` - `mouseup`,
- // which should be filtered, otherwise it will bring trouble to
- // pan and zoom.
- || !this._downPoint
- // Arbitrary value
- || dist(this._downPoint, [event.zrX, event.zrY]) > 4
- ) {
- return;
- }
- this._downPoint = null;
- }
-
- this.dispatchToElement(hovered, name, event);
- };
-});
-
-function isHover(displayable, x, y) {
- if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) {
- var el = displayable;
- var isSilent;
- while (el) {
- // If clipped by ancestor.
- // FIXME: If clipPath has neither stroke nor fill,
- // el.clipPath.contain(x, y) will always return false.
- if (el.clipPath && !el.clipPath.contain(x, y)) {
- return false;
- }
- if (el.silent) {
- isSilent = true;
- }
- el = el.parent;
- }
- return isSilent ? SILENT : true;
- }
-
- return false;
-}
-
-mixin(Handler, Eventful);
-mixin(Handler, Draggable);
-
-/**
- * 3x2矩阵操作类
- * @exports zrender/tool/matrix
- */
-
-var ArrayCtor$1 = typeof Float32Array === 'undefined'
- ? Array
- : Float32Array;
-
-/**
- * Create a identity matrix.
- * @return {Float32Array|Array.}
- */
-function create$1() {
- var out = new ArrayCtor$1(6);
- identity(out);
-
- return out;
-}
-
-/**
- * 设置矩阵为单位矩阵
- * @param {Float32Array|Array.} out
- */
-function identity(out) {
- out[0] = 1;
- out[1] = 0;
- out[2] = 0;
- out[3] = 1;
- out[4] = 0;
- out[5] = 0;
- return out;
-}
-
-/**
- * 复制矩阵
- * @param {Float32Array|Array.} out
- * @param {Float32Array|Array.} m
- */
-function copy$1(out, m) {
- out[0] = m[0];
- out[1] = m[1];
- out[2] = m[2];
- out[3] = m[3];
- out[4] = m[4];
- out[5] = m[5];
- return out;
-}
-
-/**
- * 矩阵相乘
- * @param {Float32Array|Array.} out
- * @param {Float32Array|Array.} m1
- * @param {Float32Array|Array.} m2
- */
-function mul$1(out, m1, m2) {
- // Consider matrix.mul(m, m2, m);
- // where out is the same as m2.
- // So use temp variable to escape error.
- var out0 = m1[0] * m2[0] + m1[2] * m2[1];
- var out1 = m1[1] * m2[0] + m1[3] * m2[1];
- var out2 = m1[0] * m2[2] + m1[2] * m2[3];
- var out3 = m1[1] * m2[2] + m1[3] * m2[3];
- var out4 = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
- var out5 = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
- out[0] = out0;
- out[1] = out1;
- out[2] = out2;
- out[3] = out3;
- out[4] = out4;
- out[5] = out5;
- return out;
-}
-
-/**
- * 平移变换
- * @param {Float32Array|Array.} out
- * @param {Float32Array|Array.} a
- * @param {Float32Array|Array.} v
- */
-function translate(out, a, v) {
- out[0] = a[0];
- out[1] = a[1];
- out[2] = a[2];
- out[3] = a[3];
- out[4] = a[4] + v[0];
- out[5] = a[5] + v[1];
- return out;
-}
-
-/**
- * 旋转变换
- * @param {Float32Array|Array.} out
- * @param {Float32Array|Array.} a
- * @param {number} rad
- */
-function rotate(out, a, rad) {
- var aa = a[0];
- var ac = a[2];
- var atx = a[4];
- var ab = a[1];
- var ad = a[3];
- var aty = a[5];
- var st = Math.sin(rad);
- var ct = Math.cos(rad);
-
- out[0] = aa * ct + ab * st;
- out[1] = -aa * st + ab * ct;
- out[2] = ac * ct + ad * st;
- out[3] = -ac * st + ct * ad;
- out[4] = ct * atx + st * aty;
- out[5] = ct * aty - st * atx;
- return out;
-}
-
-/**
- * 缩放变换
- * @param {Float32Array|Array.} out
- * @param {Float32Array|Array.} a
- * @param {Float32Array|Array.} v
- */
-function scale$1(out, a, v) {
- var vx = v[0];
- var vy = v[1];
- out[0] = a[0] * vx;
- out[1] = a[1] * vy;
- out[2] = a[2] * vx;
- out[3] = a[3] * vy;
- out[4] = a[4] * vx;
- out[5] = a[5] * vy;
- return out;
-}
-
-/**
- * 求逆矩阵
- * @param {Float32Array|Array.} out
- * @param {Float32Array|Array.} a
- */
-function invert(out, a) {
-
- var aa = a[0];
- var ac = a[2];
- var atx = a[4];
- var ab = a[1];
- var ad = a[3];
- var aty = a[5];
-
- var det = aa * ad - ab * ac;
- if (!det) {
- return null;
- }
- det = 1.0 / det;
-
- out[0] = ad * det;
- out[1] = -ab * det;
- out[2] = -ac * det;
- out[3] = aa * det;
- out[4] = (ac * aty - ad * atx) * det;
- out[5] = (ab * atx - aa * aty) * det;
- return out;
-}
-
-/**
- * Clone a new matrix.
- * @param {Float32Array|Array.} a
- */
-function clone$2(a) {
- var b = create$1();
- copy$1(b, a);
- return b;
-}
-
-var matrix = (Object.freeze || Object)({
- create: create$1,
- identity: identity,
- copy: copy$1,
- mul: mul$1,
- translate: translate,
- rotate: rotate,
- scale: scale$1,
- invert: invert,
- clone: clone$2
-});
-
-/**
- * 提供变换扩展
- * @module zrender/mixin/Transformable
- * @author pissang (https://www.github.com/pissang)
- */
-
-var mIdentity = identity;
-
-var EPSILON = 5e-5;
-
-function isNotAroundZero(val) {
- return val > EPSILON || val < -EPSILON;
-}
-
-/**
- * @alias module:zrender/mixin/Transformable
- * @constructor
- */
-var Transformable = function (opts) {
- opts = opts || {};
- // If there are no given position, rotation, scale
- if (!opts.position) {
- /**
- * 平移
- * @type {Array.}
- * @default [0, 0]
- */
- this.position = [0, 0];
- }
- if (opts.rotation == null) {
- /**
- * 旋转
- * @type {Array.}
- * @default 0
- */
- this.rotation = 0;
- }
- if (!opts.scale) {
- /**
- * 缩放
- * @type {Array.}
- * @default [1, 1]
- */
- this.scale = [1, 1];
- }
- /**
- * 旋转和缩放的原点
- * @type {Array.}
- * @default null
- */
- this.origin = this.origin || null;
-};
-
-var transformableProto = Transformable.prototype;
-transformableProto.transform = null;
-
-/**
- * 判断是否需要有坐标变换
- * 如果有坐标变换, 则从position, rotation, scale以及父节点的transform计算出自身的transform矩阵
- */
-transformableProto.needLocalTransform = function () {
- return isNotAroundZero(this.rotation)
- || isNotAroundZero(this.position[0])
- || isNotAroundZero(this.position[1])
- || isNotAroundZero(this.scale[0] - 1)
- || isNotAroundZero(this.scale[1] - 1);
-};
-
-transformableProto.updateTransform = function () {
- var parent = this.parent;
- var parentHasTransform = parent && parent.transform;
- var needLocalTransform = this.needLocalTransform();
-
- var m = this.transform;
- if (!(needLocalTransform || parentHasTransform)) {
- m && mIdentity(m);
- return;
- }
-
- m = m || create$1();
-
- if (needLocalTransform) {
- this.getLocalTransform(m);
- }
- else {
- mIdentity(m);
- }
-
- // 应用父节点变换
- if (parentHasTransform) {
- if (needLocalTransform) {
- mul$1(m, parent.transform, m);
- }
- else {
- copy$1(m, parent.transform);
- }
- }
- // 保存这个变换矩阵
- this.transform = m;
-
- this.invTransform = this.invTransform || create$1();
- invert(this.invTransform, m);
-};
-
-transformableProto.getLocalTransform = function (m) {
- return Transformable.getLocalTransform(this, m);
-};
-
-/**
- * 将自己的transform应用到context上
- * @param {CanvasRenderingContext2D} ctx
- */
-transformableProto.setTransform = function (ctx) {
- var m = this.transform;
- var dpr = ctx.dpr || 1;
- if (m) {
- ctx.setTransform(dpr * m[0], dpr * m[1], dpr * m[2], dpr * m[3], dpr * m[4], dpr * m[5]);
- }
- else {
- ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
- }
-};
-
-transformableProto.restoreTransform = function (ctx) {
- var dpr = ctx.dpr || 1;
- ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
-};
-
-var tmpTransform = [];
-
-/**
- * 分解`transform`矩阵到`position`, `rotation`, `scale`
- */
-transformableProto.decomposeTransform = function () {
- if (!this.transform) {
- return;
- }
- var parent = this.parent;
- var m = this.transform;
- if (parent && parent.transform) {
- // Get local transform and decompose them to position, scale, rotation
- mul$1(tmpTransform, parent.invTransform, m);
- m = tmpTransform;
- }
- var sx = m[0] * m[0] + m[1] * m[1];
- var sy = m[2] * m[2] + m[3] * m[3];
- var position = this.position;
- var scale$$1 = this.scale;
- if (isNotAroundZero(sx - 1)) {
- sx = Math.sqrt(sx);
- }
- if (isNotAroundZero(sy - 1)) {
- sy = Math.sqrt(sy);
- }
- if (m[0] < 0) {
- sx = -sx;
- }
- if (m[3] < 0) {
- sy = -sy;
- }
- position[0] = m[4];
- position[1] = m[5];
- scale$$1[0] = sx;
- scale$$1[1] = sy;
- this.rotation = Math.atan2(-m[1] / sy, m[0] / sx);
-};
-
-/**
- * Get global scale
- * @return {Array.}
- */
-transformableProto.getGlobalScale = function () {
- var m = this.transform;
- if (!m) {
- return [1, 1];
- }
- var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
- var sy = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
- if (m[0] < 0) {
- sx = -sx;
- }
- if (m[3] < 0) {
- sy = -sy;
- }
- return [sx, sy];
-};
-/**
- * 变换坐标位置到 shape 的局部坐标空间
- * @method
- * @param {number} x
- * @param {number} y
- * @return {Array.}
- */
-transformableProto.transformCoordToLocal = function (x, y) {
- var v2 = [x, y];
- var invTransform = this.invTransform;
- if (invTransform) {
- applyTransform(v2, v2, invTransform);
- }
- return v2;
-};
-
-/**
- * 变换局部坐标位置到全局坐标空间
- * @method
- * @param {number} x
- * @param {number} y
- * @return {Array.}
- */
-transformableProto.transformCoordToGlobal = function (x, y) {
- var v2 = [x, y];
- var transform = this.transform;
- if (transform) {
- applyTransform(v2, v2, transform);
- }
- return v2;
-};
-
-/**
- * @static
- * @param {Object} target
- * @param {Array.} target.origin
- * @param {number} target.rotation
- * @param {Array.} target.position
- * @param {Array.} [m]
- */
-Transformable.getLocalTransform = function (target, m) {
- m = m || [];
- mIdentity(m);
-
- var origin = target.origin;
- var scale$$1 = target.scale || [1, 1];
- var rotation = target.rotation || 0;
- var position = target.position || [0, 0];
-
- if (origin) {
- // Translate to origin
- m[4] -= origin[0];
- m[5] -= origin[1];
- }
- scale$1(m, m, scale$$1);
- if (rotation) {
- rotate(m, m, rotation);
- }
- if (origin) {
- // Translate back from origin
- m[4] += origin[0];
- m[5] += origin[1];
- }
-
- m[4] += position[0];
- m[5] += position[1];
-
- return m;
-};
-
-/**
- * 缓动代码来自 https://github.com/sole/tween.js/blob/master/src/Tween.js
- * @see http://sole.github.io/tween.js/examples/03_graphs.html
- * @exports zrender/animation/easing
- */
-var easing = {
- /**
- * @param {number} k
- * @return {number}
- */
- linear: function (k) {
- return k;
- },
-
- /**
- * @param {number} k
- * @return {number}
- */
- quadraticIn: function (k) {
- return k * k;
- },
- /**
- * @param {number} k
- * @return {number}
- */
- quadraticOut: function (k) {
- return k * (2 - k);
- },
- /**
- * @param {number} k
- * @return {number}
- */
- quadraticInOut: function (k) {
- if ((k *= 2) < 1) {
- return 0.5 * k * k;
- }
- return -0.5 * (--k * (k - 2) - 1);
- },
-
- // 三次方的缓动(t^3)
- /**
- * @param {number} k
- * @return {number}
- */
- cubicIn: function (k) {
- return k * k * k;
- },
- /**
- * @param {number} k
- * @return {number}
- */
- cubicOut: function (k) {
- return --k * k * k + 1;
- },
- /**
- * @param {number} k
- * @return {number}
- */
- cubicInOut: function (k) {
- if ((k *= 2) < 1) {
- return 0.5 * k * k * k;
- }
- return 0.5 * ((k -= 2) * k * k + 2);
- },
-
- // 四次方的缓动(t^4)
- /**
- * @param {number} k
- * @return {number}
- */
- quarticIn: function (k) {
- return k * k * k * k;
- },
- /**
- * @param {number} k
- * @return {number}
- */
- quarticOut: function (k) {
- return 1 - (--k * k * k * k);
- },
- /**
- * @param {number} k
- * @return {number}
- */
- quarticInOut: function (k) {
- if ((k *= 2) < 1) {
- return 0.5 * k * k * k * k;
- }
- return -0.5 * ((k -= 2) * k * k * k - 2);
- },
-
- // 五次方的缓动(t^5)
- /**
- * @param {number} k
- * @return {number}
- */
- quinticIn: function (k) {
- return k * k * k * k * k;
- },
- /**
- * @param {number} k
- * @return {number}
- */
- quinticOut: function (k) {
- return --k * k * k * k * k + 1;
- },
- /**
- * @param {number} k
- * @return {number}
- */
- quinticInOut: function (k) {
- if ((k *= 2) < 1) {
- return 0.5 * k * k * k * k * k;
- }
- return 0.5 * ((k -= 2) * k * k * k * k + 2);
- },
-
- // 正弦曲线的缓动(sin(t))
- /**
- * @param {number} k
- * @return {number}
- */
- sinusoidalIn: function (k) {
- return 1 - Math.cos(k * Math.PI / 2);
- },
- /**
- * @param {number} k
- * @return {number}
- */
- sinusoidalOut: function (k) {
- return Math.sin(k * Math.PI / 2);
- },
- /**
- * @param {number} k
- * @return {number}
- */
- sinusoidalInOut: function (k) {
- return 0.5 * (1 - Math.cos(Math.PI * k));
- },
-
- // 指数曲线的缓动(2^t)
- /**
- * @param {number} k
- * @return {number}
- */
- exponentialIn: function (k) {
- return k === 0 ? 0 : Math.pow(1024, k - 1);
- },
- /**
- * @param {number} k
- * @return {number}
- */
- exponentialOut: function (k) {
- return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
- },
- /**
- * @param {number} k
- * @return {number}
- */
- exponentialInOut: function (k) {
- if (k === 0) {
- return 0;
- }
- if (k === 1) {
- return 1;
- }
- if ((k *= 2) < 1) {
- return 0.5 * Math.pow(1024, k - 1);
- }
- return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
- },
-
- // 圆形曲线的缓动(sqrt(1-t^2))
- /**
- * @param {number} k
- * @return {number}
- */
- circularIn: function (k) {
- return 1 - Math.sqrt(1 - k * k);
- },
- /**
- * @param {number} k
- * @return {number}
- */
- circularOut: function (k) {
- return Math.sqrt(1 - (--k * k));
- },
- /**
- * @param {number} k
- * @return {number}
- */
- circularInOut: function (k) {
- if ((k *= 2) < 1) {
- return -0.5 * (Math.sqrt(1 - k * k) - 1);
- }
- return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
- },
-
- // 创建类似于弹簧在停止前来回振荡的动画
- /**
- * @param {number} k
- * @return {number}
- */
- elasticIn: function (k) {
- var s;
- var a = 0.1;
- var p = 0.4;
- if (k === 0) {
- return 0;
- }
- if (k === 1) {
- return 1;
- }
- if (!a || a < 1) {
- a = 1; s = p / 4;
- }
- else {
- s = p * Math.asin(1 / a) / (2 * Math.PI);
- }
- return -(a * Math.pow(2, 10 * (k -= 1)) *
- Math.sin((k - s) * (2 * Math.PI) / p));
- },
- /**
- * @param {number} k
- * @return {number}
- */
- elasticOut: function (k) {
- var s;
- var a = 0.1;
- var p = 0.4;
- if (k === 0) {
- return 0;
- }
- if (k === 1) {
- return 1;
- }
- if (!a || a < 1) {
- a = 1; s = p / 4;
- }
- else {
- s = p * Math.asin(1 / a) / (2 * Math.PI);
- }
- return (a * Math.pow(2, -10 * k) *
- Math.sin((k - s) * (2 * Math.PI) / p) + 1);
- },
- /**
- * @param {number} k
- * @return {number}
- */
- elasticInOut: function (k) {
- var s;
- var a = 0.1;
- var p = 0.4;
- if (k === 0) {
- return 0;
- }
- if (k === 1) {
- return 1;
- }
- if (!a || a < 1) {
- a = 1; s = p / 4;
- }
- else {
- s = p * Math.asin(1 / a) / (2 * Math.PI);
- }
- if ((k *= 2) < 1) {
- return -0.5 * (a * Math.pow(2, 10 * (k -= 1))
- * Math.sin((k - s) * (2 * Math.PI) / p));
- }
- return a * Math.pow(2, -10 * (k -= 1))
- * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
-
- },
-
- // 在某一动画开始沿指示的路径进行动画处理前稍稍收回该动画的移动
- /**
- * @param {number} k
- * @return {number}
- */
- backIn: function (k) {
- var s = 1.70158;
- return k * k * ((s + 1) * k - s);
- },
- /**
- * @param {number} k
- * @return {number}
- */
- backOut: function (k) {
- var s = 1.70158;
- return --k * k * ((s + 1) * k + s) + 1;
- },
- /**
- * @param {number} k
- * @return {number}
- */
- backInOut: function (k) {
- var s = 1.70158 * 1.525;
- if ((k *= 2) < 1) {
- return 0.5 * (k * k * ((s + 1) * k - s));
- }
- return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
- },
-
- // 创建弹跳效果
- /**
- * @param {number} k
- * @return {number}
- */
- bounceIn: function (k) {
- return 1 - easing.bounceOut(1 - k);
- },
- /**
- * @param {number} k
- * @return {number}
- */
- bounceOut: function (k) {
- if (k < (1 / 2.75)) {
- return 7.5625 * k * k;
- }
- else if (k < (2 / 2.75)) {
- return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
- }
- else if (k < (2.5 / 2.75)) {
- return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
- }
- else {
- return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
- }
- },
- /**
- * @param {number} k
- * @return {number}
- */
- bounceInOut: function (k) {
- if (k < 0.5) {
- return easing.bounceIn(k * 2) * 0.5;
- }
- return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5;
- }
-};
-
-/**
- * 动画主控制器
- * @config target 动画对象,可以是数组,如果是数组的话会批量分发onframe等事件
- * @config life(1000) 动画时长
- * @config delay(0) 动画延迟时间
- * @config loop(true)
- * @config gap(0) 循环的间隔时间
- * @config onframe
- * @config easing(optional)
- * @config ondestroy(optional)
- * @config onrestart(optional)
- *
- * TODO pause
- */
-
-function Clip(options) {
-
- this._target = options.target;
-
- // 生命周期
- this._life = options.life || 1000;
- // 延时
- this._delay = options.delay || 0;
- // 开始时间
- // this._startTime = new Date().getTime() + this._delay;// 单位毫秒
- this._initialized = false;
-
- // 是否循环
- this.loop = options.loop == null ? false : options.loop;
-
- this.gap = options.gap || 0;
-
- this.easing = options.easing || 'Linear';
-
- this.onframe = options.onframe;
- this.ondestroy = options.ondestroy;
- this.onrestart = options.onrestart;
-
- this._pausedTime = 0;
- this._paused = false;
-}
-
-Clip.prototype = {
-
- constructor: Clip,
-
- step: function (globalTime, deltaTime) {
- // Set startTime on first step, or _startTime may has milleseconds different between clips
- // PENDING
- if (!this._initialized) {
- this._startTime = globalTime + this._delay;
- this._initialized = true;
- }
-
- if (this._paused) {
- this._pausedTime += deltaTime;
- return;
- }
-
- var percent = (globalTime - this._startTime - this._pausedTime) / this._life;
-
- // 还没开始
- if (percent < 0) {
- return;
- }
-
- percent = Math.min(percent, 1);
-
- var easing$$1 = this.easing;
- var easingFunc = typeof easing$$1 == 'string' ? easing[easing$$1] : easing$$1;
- var schedule = typeof easingFunc === 'function'
- ? easingFunc(percent)
- : percent;
-
- this.fire('frame', schedule);
-
- // 结束
- if (percent == 1) {
- if (this.loop) {
- this.restart (globalTime);
- // 重新开始周期
- // 抛出而不是直接调用事件直到 stage.update 后再统一调用这些事件
- return 'restart';
- }
-
- // 动画完成将这个控制器标识为待删除
- // 在Animation.update中进行批量删除
- this._needsRemove = true;
- return 'destroy';
- }
-
- return null;
- },
-
- restart: function (globalTime) {
- var remainder = (globalTime - this._startTime - this._pausedTime) % this._life;
- this._startTime = globalTime - remainder + this.gap;
- this._pausedTime = 0;
-
- this._needsRemove = false;
- },
-
- fire: function (eventType, arg) {
- eventType = 'on' + eventType;
- if (this[eventType]) {
- this[eventType](this._target, arg);
- }
- },
-
- pause: function () {
- this._paused = true;
- },
-
- resume: function () {
- this._paused = false;
- }
-};
-
-// Simple LRU cache use doubly linked list
-// @module zrender/core/LRU
-
-/**
- * Simple double linked list. Compared with array, it has O(1) remove operation.
- * @constructor
- */
-var LinkedList = function () {
-
- /**
- * @type {module:zrender/core/LRU~Entry}
- */
- this.head = null;
-
- /**
- * @type {module:zrender/core/LRU~Entry}
- */
- this.tail = null;
-
- this._len = 0;
-};
-
-var linkedListProto = LinkedList.prototype;
-/**
- * Insert a new value at the tail
- * @param {} val
- * @return {module:zrender/core/LRU~Entry}
- */
-linkedListProto.insert = function (val) {
- var entry = new Entry(val);
- this.insertEntry(entry);
- return entry;
-};
-
-/**
- * Insert an entry at the tail
- * @param {module:zrender/core/LRU~Entry} entry
- */
-linkedListProto.insertEntry = function (entry) {
- if (!this.head) {
- this.head = this.tail = entry;
- }
- else {
- this.tail.next = entry;
- entry.prev = this.tail;
- entry.next = null;
- this.tail = entry;
- }
- this._len++;
-};
-
-/**
- * Remove entry.
- * @param {module:zrender/core/LRU~Entry} entry
- */
-linkedListProto.remove = function (entry) {
- var prev = entry.prev;
- var next = entry.next;
- if (prev) {
- prev.next = next;
- }
- else {
- // Is head
- this.head = next;
- }
- if (next) {
- next.prev = prev;
- }
- else {
- // Is tail
- this.tail = prev;
- }
- entry.next = entry.prev = null;
- this._len--;
-};
-
-/**
- * @return {number}
- */
-linkedListProto.len = function () {
- return this._len;
-};
-
-/**
- * Clear list
- */
-linkedListProto.clear = function () {
- this.head = this.tail = null;
- this._len = 0;
-};
-
-/**
- * @constructor
- * @param {} val
- */
-var Entry = function (val) {
- /**
- * @type {}
- */
- this.value = val;
-
- /**
- * @type {module:zrender/core/LRU~Entry}
- */
- this.next;
-
- /**
- * @type {module:zrender/core/LRU~Entry}
- */
- this.prev;
-};
-
-/**
- * LRU Cache
- * @constructor
- * @alias module:zrender/core/LRU
- */
-var LRU = function (maxSize) {
-
- this._list = new LinkedList();
-
- this._map = {};
-
- this._maxSize = maxSize || 10;
-
- this._lastRemovedEntry = null;
-};
-
-var LRUProto = LRU.prototype;
-
-/**
- * @param {string} key
- * @param {} value
- * @return {} Removed value
- */
-LRUProto.put = function (key, value) {
- var list = this._list;
- var map = this._map;
- var removed = null;
- if (map[key] == null) {
- var len = list.len();
- // Reuse last removed entry
- var entry = this._lastRemovedEntry;
-
- if (len >= this._maxSize && len > 0) {
- // Remove the least recently used
- var leastUsedEntry = list.head;
- list.remove(leastUsedEntry);
- delete map[leastUsedEntry.key];
-
- removed = leastUsedEntry.value;
- this._lastRemovedEntry = leastUsedEntry;
- }
-
- if (entry) {
- entry.value = value;
- }
- else {
- entry = new Entry(value);
- }
- entry.key = key;
- list.insertEntry(entry);
- map[key] = entry;
- }
-
- return removed;
-};
-
-/**
- * @param {string} key
- * @return {}
- */
-LRUProto.get = function (key) {
- var entry = this._map[key];
- var list = this._list;
- if (entry != null) {
- // Put the latest used entry in the tail
- if (entry !== list.tail) {
- list.remove(entry);
- list.insertEntry(entry);
- }
-
- return entry.value;
- }
-};
-
-/**
- * Clear the cache
- */
-LRUProto.clear = function () {
- this._list.clear();
- this._map = {};
-};
-
-var kCSSColorTable = {
- 'transparent': [0,0,0,0], 'aliceblue': [240,248,255,1],
- 'antiquewhite': [250,235,215,1], 'aqua': [0,255,255,1],
- 'aquamarine': [127,255,212,1], 'azure': [240,255,255,1],
- 'beige': [245,245,220,1], 'bisque': [255,228,196,1],
- 'black': [0,0,0,1], 'blanchedalmond': [255,235,205,1],
- 'blue': [0,0,255,1], 'blueviolet': [138,43,226,1],
- 'brown': [165,42,42,1], 'burlywood': [222,184,135,1],
- 'cadetblue': [95,158,160,1], 'chartreuse': [127,255,0,1],
- 'chocolate': [210,105,30,1], 'coral': [255,127,80,1],
- 'cornflowerblue': [100,149,237,1], 'cornsilk': [255,248,220,1],
- 'crimson': [220,20,60,1], 'cyan': [0,255,255,1],
- 'darkblue': [0,0,139,1], 'darkcyan': [0,139,139,1],
- 'darkgoldenrod': [184,134,11,1], 'darkgray': [169,169,169,1],
- 'darkgreen': [0,100,0,1], 'darkgrey': [169,169,169,1],
- 'darkkhaki': [189,183,107,1], 'darkmagenta': [139,0,139,1],
- 'darkolivegreen': [85,107,47,1], 'darkorange': [255,140,0,1],
- 'darkorchid': [153,50,204,1], 'darkred': [139,0,0,1],
- 'darksalmon': [233,150,122,1], 'darkseagreen': [143,188,143,1],
- 'darkslateblue': [72,61,139,1], 'darkslategray': [47,79,79,1],
- 'darkslategrey': [47,79,79,1], 'darkturquoise': [0,206,209,1],
- 'darkviolet': [148,0,211,1], 'deeppink': [255,20,147,1],
- 'deepskyblue': [0,191,255,1], 'dimgray': [105,105,105,1],
- 'dimgrey': [105,105,105,1], 'dodgerblue': [30,144,255,1],
- 'firebrick': [178,34,34,1], 'floralwhite': [255,250,240,1],
- 'forestgreen': [34,139,34,1], 'fuchsia': [255,0,255,1],
- 'gainsboro': [220,220,220,1], 'ghostwhite': [248,248,255,1],
- 'gold': [255,215,0,1], 'goldenrod': [218,165,32,1],
- 'gray': [128,128,128,1], 'green': [0,128,0,1],
- 'greenyellow': [173,255,47,1], 'grey': [128,128,128,1],
- 'honeydew': [240,255,240,1], 'hotpink': [255,105,180,1],
- 'indianred': [205,92,92,1], 'indigo': [75,0,130,1],
- 'ivory': [255,255,240,1], 'khaki': [240,230,140,1],
- 'lavender': [230,230,250,1], 'lavenderblush': [255,240,245,1],
- 'lawngreen': [124,252,0,1], 'lemonchiffon': [255,250,205,1],
- 'lightblue': [173,216,230,1], 'lightcoral': [240,128,128,1],
- 'lightcyan': [224,255,255,1], 'lightgoldenrodyellow': [250,250,210,1],
- 'lightgray': [211,211,211,1], 'lightgreen': [144,238,144,1],
- 'lightgrey': [211,211,211,1], 'lightpink': [255,182,193,1],
- 'lightsalmon': [255,160,122,1], 'lightseagreen': [32,178,170,1],
- 'lightskyblue': [135,206,250,1], 'lightslategray': [119,136,153,1],
- 'lightslategrey': [119,136,153,1], 'lightsteelblue': [176,196,222,1],
- 'lightyellow': [255,255,224,1], 'lime': [0,255,0,1],
- 'limegreen': [50,205,50,1], 'linen': [250,240,230,1],
- 'magenta': [255,0,255,1], 'maroon': [128,0,0,1],
- 'mediumaquamarine': [102,205,170,1], 'mediumblue': [0,0,205,1],
- 'mediumorchid': [186,85,211,1], 'mediumpurple': [147,112,219,1],
- 'mediumseagreen': [60,179,113,1], 'mediumslateblue': [123,104,238,1],
- 'mediumspringgreen': [0,250,154,1], 'mediumturquoise': [72,209,204,1],
- 'mediumvioletred': [199,21,133,1], 'midnightblue': [25,25,112,1],
- 'mintcream': [245,255,250,1], 'mistyrose': [255,228,225,1],
- 'moccasin': [255,228,181,1], 'navajowhite': [255,222,173,1],
- 'navy': [0,0,128,1], 'oldlace': [253,245,230,1],
- 'olive': [128,128,0,1], 'olivedrab': [107,142,35,1],
- 'orange': [255,165,0,1], 'orangered': [255,69,0,1],
- 'orchid': [218,112,214,1], 'palegoldenrod': [238,232,170,1],
- 'palegreen': [152,251,152,1], 'paleturquoise': [175,238,238,1],
- 'palevioletred': [219,112,147,1], 'papayawhip': [255,239,213,1],
- 'peachpuff': [255,218,185,1], 'peru': [205,133,63,1],
- 'pink': [255,192,203,1], 'plum': [221,160,221,1],
- 'powderblue': [176,224,230,1], 'purple': [128,0,128,1],
- 'red': [255,0,0,1], 'rosybrown': [188,143,143,1],
- 'royalblue': [65,105,225,1], 'saddlebrown': [139,69,19,1],
- 'salmon': [250,128,114,1], 'sandybrown': [244,164,96,1],
- 'seagreen': [46,139,87,1], 'seashell': [255,245,238,1],
- 'sienna': [160,82,45,1], 'silver': [192,192,192,1],
- 'skyblue': [135,206,235,1], 'slateblue': [106,90,205,1],
- 'slategray': [112,128,144,1], 'slategrey': [112,128,144,1],
- 'snow': [255,250,250,1], 'springgreen': [0,255,127,1],
- 'steelblue': [70,130,180,1], 'tan': [210,180,140,1],
- 'teal': [0,128,128,1], 'thistle': [216,191,216,1],
- 'tomato': [255,99,71,1], 'turquoise': [64,224,208,1],
- 'violet': [238,130,238,1], 'wheat': [245,222,179,1],
- 'white': [255,255,255,1], 'whitesmoke': [245,245,245,1],
- 'yellow': [255,255,0,1], 'yellowgreen': [154,205,50,1]
-};
-
-function clampCssByte(i) { // Clamp to integer 0 .. 255.
- i = Math.round(i); // Seems to be what Chrome does (vs truncation).
- return i < 0 ? 0 : i > 255 ? 255 : i;
-}
-
-function clampCssAngle(i) { // Clamp to integer 0 .. 360.
- i = Math.round(i); // Seems to be what Chrome does (vs truncation).
- return i < 0 ? 0 : i > 360 ? 360 : i;
-}
-
-function clampCssFloat(f) { // Clamp to float 0.0 .. 1.0.
- return f < 0 ? 0 : f > 1 ? 1 : f;
-}
-
-function parseCssInt(str) { // int or percentage.
- if (str.length && str.charAt(str.length - 1) === '%') {
- return clampCssByte(parseFloat(str) / 100 * 255);
- }
- return clampCssByte(parseInt(str, 10));
-}
-
-function parseCssFloat(str) { // float or percentage.
- if (str.length && str.charAt(str.length - 1) === '%') {
- return clampCssFloat(parseFloat(str) / 100);
- }
- return clampCssFloat(parseFloat(str));
-}
-
-function cssHueToRgb(m1, m2, h) {
- if (h < 0) {
- h += 1;
- }
- else if (h > 1) {
- h -= 1;
- }
-
- if (h * 6 < 1) {
- return m1 + (m2 - m1) * h * 6;
- }
- if (h * 2 < 1) {
- return m2;
- }
- if (h * 3 < 2) {
- return m1 + (m2 - m1) * (2/3 - h) * 6;
- }
- return m1;
-}
-
-function lerpNumber(a, b, p) {
- return a + (b - a) * p;
-}
-
-function setRgba(out, r, g, b, a) {
- out[0] = r; out[1] = g; out[2] = b; out[3] = a;
- return out;
-}
-function copyRgba(out, a) {
- out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3];
- return out;
-}
-
-var colorCache = new LRU(20);
-var lastRemovedArr = null;
-
-function putToCache(colorStr, rgbaArr) {
- // Reuse removed array
- if (lastRemovedArr) {
- copyRgba(lastRemovedArr, rgbaArr);
- }
- lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice()));
-}
-
-/**
- * @param {string} colorStr
- * @param {Array.} out
- * @return {Array.}
- * @memberOf module:zrender/util/color
- */
-function parse(colorStr, rgbaArr) {
- if (!colorStr) {
- return;
- }
- rgbaArr = rgbaArr || [];
-
- var cached = colorCache.get(colorStr);
- if (cached) {
- return copyRgba(rgbaArr, cached);
- }
-
- // colorStr may be not string
- colorStr = colorStr + '';
- // Remove all whitespace, not compliant, but should just be more accepting.
- var str = colorStr.replace(/ /g, '').toLowerCase();
-
- // Color keywords (and transparent) lookup.
- if (str in kCSSColorTable) {
- copyRgba(rgbaArr, kCSSColorTable[str]);
- putToCache(colorStr, rgbaArr);
- return rgbaArr;
- }
-
- // #abc and #abc123 syntax.
- if (str.charAt(0) === '#') {
- if (str.length === 4) {
- var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
- if (!(iv >= 0 && iv <= 0xfff)) {
- setRgba(rgbaArr, 0, 0, 0, 1);
- return; // Covers NaN.
- }
- setRgba(rgbaArr,
- ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),
- (iv & 0xf0) | ((iv & 0xf0) >> 4),
- (iv & 0xf) | ((iv & 0xf) << 4),
- 1
- );
- putToCache(colorStr, rgbaArr);
- return rgbaArr;
- }
- else if (str.length === 7) {
- var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
- if (!(iv >= 0 && iv <= 0xffffff)) {
- setRgba(rgbaArr, 0, 0, 0, 1);
- return; // Covers NaN.
- }
- setRgba(rgbaArr,
- (iv & 0xff0000) >> 16,
- (iv & 0xff00) >> 8,
- iv & 0xff,
- 1
- );
- putToCache(colorStr, rgbaArr);
- return rgbaArr;
- }
-
- return;
- }
- var op = str.indexOf('('), ep = str.indexOf(')');
- if (op !== -1 && ep + 1 === str.length) {
- var fname = str.substr(0, op);
- var params = str.substr(op + 1, ep - (op + 1)).split(',');
- var alpha = 1; // To allow case fallthrough.
- switch (fname) {
- case 'rgba':
- if (params.length !== 4) {
- setRgba(rgbaArr, 0, 0, 0, 1);
- return;
- }
- alpha = parseCssFloat(params.pop()); // jshint ignore:line
- // Fall through.
- case 'rgb':
- if (params.length !== 3) {
- setRgba(rgbaArr, 0, 0, 0, 1);
- return;
- }
- setRgba(rgbaArr,
- parseCssInt(params[0]),
- parseCssInt(params[1]),
- parseCssInt(params[2]),
- alpha
- );
- putToCache(colorStr, rgbaArr);
- return rgbaArr;
- case 'hsla':
- if (params.length !== 4) {
- setRgba(rgbaArr, 0, 0, 0, 1);
- return;
- }
- params[3] = parseCssFloat(params[3]);
- hsla2rgba(params, rgbaArr);
- putToCache(colorStr, rgbaArr);
- return rgbaArr;
- case 'hsl':
- if (params.length !== 3) {
- setRgba(rgbaArr, 0, 0, 0, 1);
- return;
- }
- hsla2rgba(params, rgbaArr);
- putToCache(colorStr, rgbaArr);
- return rgbaArr;
- default:
- return;
- }
- }
-
- setRgba(rgbaArr, 0, 0, 0, 1);
- return;
-}
-
-/**
- * @param {Array.} hsla
- * @param {Array.} rgba
- * @return {Array.} rgba
- */
-function hsla2rgba(hsla, rgba) {
- var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360; // 0 .. 1
- // NOTE(deanm): According to the CSS spec s/l should only be
- // percentages, but we don't bother and let float or percentage.
- var s = parseCssFloat(hsla[1]);
- var l = parseCssFloat(hsla[2]);
- var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
- var m1 = l * 2 - m2;
-
- rgba = rgba || [];
- setRgba(rgba,
- clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255),
- clampCssByte(cssHueToRgb(m1, m2, h) * 255),
- clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255),
- 1
- );
-
- if (hsla.length === 4) {
- rgba[3] = hsla[3];
- }
-
- return rgba;
-}
-
-/**
- * @param {Array.} rgba
- * @return {Array.} hsla
- */
-function rgba2hsla(rgba) {
- if (!rgba) {
- return;
- }
-
- // RGB from 0 to 255
- var R = rgba[0] / 255;
- var G = rgba[1] / 255;
- var B = rgba[2] / 255;
-
- var vMin = Math.min(R, G, B); // Min. value of RGB
- var vMax = Math.max(R, G, B); // Max. value of RGB
- var delta = vMax - vMin; // Delta RGB value
-
- var L = (vMax + vMin) / 2;
- var H;
- var S;
- // HSL results from 0 to 1
- if (delta === 0) {
- H = 0;
- S = 0;
- }
- else {
- if (L < 0.5) {
- S = delta / (vMax + vMin);
- }
- else {
- S = delta / (2 - vMax - vMin);
- }
-
- var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta;
- var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta;
- var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta;
-
- if (R === vMax) {
- H = deltaB - deltaG;
- }
- else if (G === vMax) {
- H = (1 / 3) + deltaR - deltaB;
- }
- else if (B === vMax) {
- H = (2 / 3) + deltaG - deltaR;
- }
-
- if (H < 0) {
- H += 1;
- }
-
- if (H > 1) {
- H -= 1;
- }
- }
-
- var hsla = [H * 360, S, L];
-
- if (rgba[3] != null) {
- hsla.push(rgba[3]);
- }
-
- return hsla;
-}
-
-/**
- * @param {string} color
- * @param {number} level
- * @return {string}
- * @memberOf module:zrender/util/color
- */
-function lift(color, level) {
- var colorArr = parse(color);
- if (colorArr) {
- for (var i = 0; i < 3; i++) {
- if (level < 0) {
- colorArr[i] = colorArr[i] * (1 - level) | 0;
- }
- else {
- colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0;
- }
- if (colorArr[i] > 255) {
- colorArr[i] = 255;
- }
- else if (color[i] < 0) {
- colorArr[i] = 0;
- }
- }
- return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
- }
-}
-
-/**
- * @param {string} color
- * @return {string}
- * @memberOf module:zrender/util/color
- */
-function toHex(color) {
- var colorArr = parse(color);
- if (colorArr) {
- return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1);
- }
-}
-
-/**
- * Map value to color. Faster than lerp methods because color is represented by rgba array.
- * @param {number} normalizedValue A float between 0 and 1.
- * @param {Array.>} colors List of rgba color array
- * @param {Array.} [out] Mapped gba color array
- * @return {Array.} will be null/undefined if input illegal.
- */
-function fastLerp(normalizedValue, colors, out) {
- if (!(colors && colors.length)
- || !(normalizedValue >= 0 && normalizedValue <= 1)
- ) {
- return;
- }
-
- out = out || [];
-
- var value = normalizedValue * (colors.length - 1);
- var leftIndex = Math.floor(value);
- var rightIndex = Math.ceil(value);
- var leftColor = colors[leftIndex];
- var rightColor = colors[rightIndex];
- var dv = value - leftIndex;
- out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv));
- out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv));
- out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv));
- out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));
-
- return out;
-}
-
-/**
- * @deprecated
- */
-var fastMapToColor = fastLerp;
-
-/**
- * @param {number} normalizedValue A float between 0 and 1.
- * @param {Array.} colors Color list.
- * @param {boolean=} fullOutput Default false.
- * @return {(string|Object)} Result color. If fullOutput,
- * return {color: ..., leftIndex: ..., rightIndex: ..., value: ...},
- * @memberOf module:zrender/util/color
- */
-function lerp$1(normalizedValue, colors, fullOutput) {
- if (!(colors && colors.length)
- || !(normalizedValue >= 0 && normalizedValue <= 1)
- ) {
- return;
- }
-
- var value = normalizedValue * (colors.length - 1);
- var leftIndex = Math.floor(value);
- var rightIndex = Math.ceil(value);
- var leftColor = parse(colors[leftIndex]);
- var rightColor = parse(colors[rightIndex]);
- var dv = value - leftIndex;
-
- var color = stringify(
- [
- clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)),
- clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)),
- clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)),
- clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv))
- ],
- 'rgba'
- );
-
- return fullOutput
- ? {
- color: color,
- leftIndex: leftIndex,
- rightIndex: rightIndex,
- value: value
- }
- : color;
-}
-
-/**
- * @deprecated
- */
-var mapToColor = lerp$1;
-
-/**
- * @param {string} color
- * @param {number=} h 0 ~ 360, ignore when null.
- * @param {number=} s 0 ~ 1, ignore when null.
- * @param {number=} l 0 ~ 1, ignore when null.
- * @return {string} Color string in rgba format.
- * @memberOf module:zrender/util/color
- */
-function modifyHSL(color, h, s, l) {
- color = parse(color);
-
- if (color) {
- color = rgba2hsla(color);
- h != null && (color[0] = clampCssAngle(h));
- s != null && (color[1] = parseCssFloat(s));
- l != null && (color[2] = parseCssFloat(l));
-
- return stringify(hsla2rgba(color), 'rgba');
- }
-}
-
-/**
- * @param {string} color
- * @param {number=} alpha 0 ~ 1
- * @return {string} Color string in rgba format.
- * @memberOf module:zrender/util/color
- */
-function modifyAlpha(color, alpha) {
- color = parse(color);
-
- if (color && alpha != null) {
- color[3] = clampCssFloat(alpha);
- return stringify(color, 'rgba');
- }
-}
-
-/**
- * @param {Array.} arrColor like [12,33,44,0.4]
- * @param {string} type 'rgba', 'hsva', ...
- * @return {string} Result color. (If input illegal, return undefined).
- */
-function stringify(arrColor, type) {
- if (!arrColor || !arrColor.length) {
- return;
- }
- var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
- if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
- colorStr += ',' + arrColor[3];
- }
- return type + '(' + colorStr + ')';
-}
-
-
-var color = (Object.freeze || Object)({
- parse: parse,
- lift: lift,
- toHex: toHex,
- fastLerp: fastLerp,
- fastMapToColor: fastMapToColor,
- lerp: lerp$1,
- mapToColor: mapToColor,
- modifyHSL: modifyHSL,
- modifyAlpha: modifyAlpha,
- stringify: stringify
-});
-
-/**
- * @module echarts/animation/Animator
- */
-
-var arraySlice = Array.prototype.slice;
-
-function defaultGetter(target, key) {
- return target[key];
-}
-
-function defaultSetter(target, key, value) {
- target[key] = value;
-}
-
-/**
- * @param {number} p0
- * @param {number} p1
- * @param {number} percent
- * @return {number}
- */
-function interpolateNumber(p0, p1, percent) {
- return (p1 - p0) * percent + p0;
-}
-
-/**
- * @param {string} p0
- * @param {string} p1
- * @param {number} percent
- * @return {string}
- */
-function interpolateString(p0, p1, percent) {
- return percent > 0.5 ? p1 : p0;
-}
-
-/**
- * @param {Array} p0
- * @param {Array} p1
- * @param {number} percent
- * @param {Array} out
- * @param {number} arrDim
- */
-function interpolateArray(p0, p1, percent, out, arrDim) {
- var len = p0.length;
- if (arrDim == 1) {
- for (var i = 0; i < len; i++) {
- out[i] = interpolateNumber(p0[i], p1[i], percent);
- }
- }
- else {
- var len2 = len && p0[0].length;
- for (var i = 0; i < len; i++) {
- for (var j = 0; j < len2; j++) {
- out[i][j] = interpolateNumber(
- p0[i][j], p1[i][j], percent
- );
- }
- }
- }
-}
-
-// arr0 is source array, arr1 is target array.
-// Do some preprocess to avoid error happened when interpolating from arr0 to arr1
-function fillArr(arr0, arr1, arrDim) {
- var arr0Len = arr0.length;
- var arr1Len = arr1.length;
- if (arr0Len !== arr1Len) {
- // FIXME Not work for TypedArray
- var isPreviousLarger = arr0Len > arr1Len;
- if (isPreviousLarger) {
- // Cut the previous
- arr0.length = arr1Len;
- }
- else {
- // Fill the previous
- for (var i = arr0Len; i < arr1Len; i++) {
- arr0.push(
- arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i])
- );
- }
- }
- }
- // Handling NaN value
- var len2 = arr0[0] && arr0[0].length;
- for (var i = 0; i < arr0.length; i++) {
- if (arrDim === 1) {
- if (isNaN(arr0[i])) {
- arr0[i] = arr1[i];
- }
- }
- else {
- for (var j = 0; j < len2; j++) {
- if (isNaN(arr0[i][j])) {
- arr0[i][j] = arr1[i][j];
- }
- }
- }
- }
-}
-
-/**
- * @param {Array} arr0
- * @param {Array} arr1
- * @param {number} arrDim
- * @return {boolean}
- */
-function isArraySame(arr0, arr1, arrDim) {
- if (arr0 === arr1) {
- return true;
- }
- var len = arr0.length;
- if (len !== arr1.length) {
- return false;
- }
- if (arrDim === 1) {
- for (var i = 0; i < len; i++) {
- if (arr0[i] !== arr1[i]) {
- return false;
- }
- }
- }
- else {
- var len2 = arr0[0].length;
- for (var i = 0; i < len; i++) {
- for (var j = 0; j < len2; j++) {
- if (arr0[i][j] !== arr1[i][j]) {
- return false;
- }
- }
- }
- }
- return true;
-}
-
-/**
- * Catmull Rom interpolate array
- * @param {Array} p0
- * @param {Array} p1
- * @param {Array} p2
- * @param {Array} p3
- * @param {number} t
- * @param {number} t2
- * @param {number} t3
- * @param {Array} out
- * @param {number} arrDim
- */
-function catmullRomInterpolateArray(
- p0, p1, p2, p3, t, t2, t3, out, arrDim
-) {
- var len = p0.length;
- if (arrDim == 1) {
- for (var i = 0; i < len; i++) {
- out[i] = catmullRomInterpolate(
- p0[i], p1[i], p2[i], p3[i], t, t2, t3
- );
- }
- }
- else {
- var len2 = p0[0].length;
- for (var i = 0; i < len; i++) {
- for (var j = 0; j < len2; j++) {
- out[i][j] = catmullRomInterpolate(
- p0[i][j], p1[i][j], p2[i][j], p3[i][j],
- t, t2, t3
- );
- }
- }
- }
-}
-
-/**
- * Catmull Rom interpolate number
- * @param {number} p0
- * @param {number} p1
- * @param {number} p2
- * @param {number} p3
- * @param {number} t
- * @param {number} t2
- * @param {number} t3
- * @return {number}
- */
-function catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) {
- var v0 = (p2 - p0) * 0.5;
- var v1 = (p3 - p1) * 0.5;
- return (2 * (p1 - p2) + v0 + v1) * t3
- + (-3 * (p1 - p2) - 2 * v0 - v1) * t2
- + v0 * t + p1;
-}
-
-function cloneValue(value) {
- if (isArrayLike(value)) {
- var len = value.length;
- if (isArrayLike(value[0])) {
- var ret = [];
- for (var i = 0; i < len; i++) {
- ret.push(arraySlice.call(value[i]));
- }
- return ret;
- }
-
- return arraySlice.call(value);
- }
-
- return value;
-}
-
-function rgba2String(rgba) {
- rgba[0] = Math.floor(rgba[0]);
- rgba[1] = Math.floor(rgba[1]);
- rgba[2] = Math.floor(rgba[2]);
-
- return 'rgba(' + rgba.join(',') + ')';
-}
-
-function getArrayDim(keyframes) {
- var lastValue = keyframes[keyframes.length - 1].value;
- return isArrayLike(lastValue && lastValue[0]) ? 2 : 1;
-}
-
-function createTrackClip(animator, easing, oneTrackDone, keyframes, propName, forceAnimate) {
- var getter = animator._getter;
- var setter = animator._setter;
- var useSpline = easing === 'spline';
-
- var trackLen = keyframes.length;
- if (!trackLen) {
- return;
- }
- // Guess data type
- var firstVal = keyframes[0].value;
- var isValueArray = isArrayLike(firstVal);
- var isValueColor = false;
- var isValueString = false;
-
- // For vertices morphing
- var arrDim = isValueArray ? getArrayDim(keyframes) : 0;
-
- var trackMaxTime;
- // Sort keyframe as ascending
- keyframes.sort(function(a, b) {
- return a.time - b.time;
- });
-
- trackMaxTime = keyframes[trackLen - 1].time;
- // Percents of each keyframe
- var kfPercents = [];
- // Value of each keyframe
- var kfValues = [];
- var prevValue = keyframes[0].value;
- var isAllValueEqual = true;
- for (var i = 0; i < trackLen; i++) {
- kfPercents.push(keyframes[i].time / trackMaxTime);
- // Assume value is a color when it is a string
- var value = keyframes[i].value;
-
- // Check if value is equal, deep check if value is array
- if (!((isValueArray && isArraySame(value, prevValue, arrDim))
- || (!isValueArray && value === prevValue))) {
- isAllValueEqual = false;
- }
- prevValue = value;
-
- // Try converting a string to a color array
- if (typeof value == 'string') {
- var colorArray = parse(value);
- if (colorArray) {
- value = colorArray;
- isValueColor = true;
- }
- else {
- isValueString = true;
- }
- }
- kfValues.push(value);
- }
- if (!forceAnimate && isAllValueEqual) {
- return;
- }
-
- var lastValue = kfValues[trackLen - 1];
- // Polyfill array and NaN value
- for (var i = 0; i < trackLen - 1; i++) {
- if (isValueArray) {
- fillArr(kfValues[i], lastValue, arrDim);
- }
- else {
- if (isNaN(kfValues[i]) && !isNaN(lastValue) && !isValueString && !isValueColor) {
- kfValues[i] = lastValue;
- }
- }
- }
- isValueArray && fillArr(getter(animator._target, propName), lastValue, arrDim);
-
- // Cache the key of last frame to speed up when
- // animation playback is sequency
- var lastFrame = 0;
- var lastFramePercent = 0;
- var start;
- var w;
- var p0;
- var p1;
- var p2;
- var p3;
-
- if (isValueColor) {
- var rgba = [0, 0, 0, 0];
- }
-
- var onframe = function (target, percent) {
- // Find the range keyframes
- // kf1-----kf2---------current--------kf3
- // find kf2 and kf3 and do interpolation
- var frame;
- // In the easing function like elasticOut, percent may less than 0
- if (percent < 0) {
- frame = 0;
- }
- else if (percent < lastFramePercent) {
- // Start from next key
- // PENDING start from lastFrame ?
- start = Math.min(lastFrame + 1, trackLen - 1);
- for (frame = start; frame >= 0; frame--) {
- if (kfPercents[frame] <= percent) {
- break;
- }
- }
- // PENDING really need to do this ?
- frame = Math.min(frame, trackLen - 2);
- }
- else {
- for (frame = lastFrame; frame < trackLen; frame++) {
- if (kfPercents[frame] > percent) {
- break;
- }
- }
- frame = Math.min(frame - 1, trackLen - 2);
- }
- lastFrame = frame;
- lastFramePercent = percent;
-
- var range = (kfPercents[frame + 1] - kfPercents[frame]);
- if (range === 0) {
- return;
- }
- else {
- w = (percent - kfPercents[frame]) / range;
- }
- if (useSpline) {
- p1 = kfValues[frame];
- p0 = kfValues[frame === 0 ? frame : frame - 1];
- p2 = kfValues[frame > trackLen - 2 ? trackLen - 1 : frame + 1];
- p3 = kfValues[frame > trackLen - 3 ? trackLen - 1 : frame + 2];
- if (isValueArray) {
- catmullRomInterpolateArray(
- p0, p1, p2, p3, w, w * w, w * w * w,
- getter(target, propName),
- arrDim
- );
- }
- else {
- var value;
- if (isValueColor) {
- value = catmullRomInterpolateArray(
- p0, p1, p2, p3, w, w * w, w * w * w,
- rgba, 1
- );
- value = rgba2String(rgba);
- }
- else if (isValueString) {
- // String is step(0.5)
- return interpolateString(p1, p2, w);
- }
- else {
- value = catmullRomInterpolate(
- p0, p1, p2, p3, w, w * w, w * w * w
- );
- }
- setter(
- target,
- propName,
- value
- );
- }
- }
- else {
- if (isValueArray) {
- interpolateArray(
- kfValues[frame], kfValues[frame + 1], w,
- getter(target, propName),
- arrDim
- );
- }
- else {
- var value;
- if (isValueColor) {
- interpolateArray(
- kfValues[frame], kfValues[frame + 1], w,
- rgba, 1
- );
- value = rgba2String(rgba);
- }
- else if (isValueString) {
- // String is step(0.5)
- return interpolateString(kfValues[frame], kfValues[frame + 1], w);
- }
- else {
- value = interpolateNumber(kfValues[frame], kfValues[frame + 1], w);
- }
- setter(
- target,
- propName,
- value
- );
- }
- }
- };
-
- var clip = new Clip({
- target: animator._target,
- life: trackMaxTime,
- loop: animator._loop,
- delay: animator._delay,
- onframe: onframe,
- ondestroy: oneTrackDone
- });
-
- if (easing && easing !== 'spline') {
- clip.easing = easing;
- }
-
- return clip;
-}
-
-/**
- * @alias module:zrender/animation/Animator
- * @constructor
- * @param {Object} target
- * @param {boolean} loop
- * @param {Function} getter
- * @param {Function} setter
- */
-var Animator = function(target, loop, getter, setter) {
- this._tracks = {};
- this._target = target;
-
- this._loop = loop || false;
-
- this._getter = getter || defaultGetter;
- this._setter = setter || defaultSetter;
-
- this._clipCount = 0;
-
- this._delay = 0;
-
- this._doneList = [];
-
- this._onframeList = [];
-
- this._clipList = [];
-};
-
-Animator.prototype = {
- /**
- * 设置动画关键帧
- * @param {number} time 关键帧时间,单位是ms
- * @param {Object} props 关键帧的属性值,key-value表示
- * @return {module:zrender/animation/Animator}
- */
- when: function(time /* ms */, props) {
- var tracks = this._tracks;
- for (var propName in props) {
- if (!props.hasOwnProperty(propName)) {
- continue;
- }
-
- if (!tracks[propName]) {
- tracks[propName] = [];
- // Invalid value
- var value = this._getter(this._target, propName);
- if (value == null) {
- // zrLog('Invalid property ' + propName);
- continue;
- }
- // If time is 0
- // Then props is given initialize value
- // Else
- // Initialize value from current prop value
- if (time !== 0) {
- tracks[propName].push({
- time: 0,
- value: cloneValue(value)
- });
- }
- }
- tracks[propName].push({
- time: time,
- value: props[propName]
- });
- }
- return this;
- },
- /**
- * 添加动画每一帧的回调函数
- * @param {Function} callback
- * @return {module:zrender/animation/Animator}
- */
- during: function (callback) {
- this._onframeList.push(callback);
- return this;
- },
-
- pause: function () {
- for (var i = 0; i < this._clipList.length; i++) {
- this._clipList[i].pause();
- }
- this._paused = true;
- },
-
- resume: function () {
- for (var i = 0; i < this._clipList.length; i++) {
- this._clipList[i].resume();
- }
- this._paused = false;
- },
-
- isPaused: function () {
- return !!this._paused;
- },
-
- _doneCallback: function () {
- // Clear all tracks
- this._tracks = {};
- // Clear all clips
- this._clipList.length = 0;
-
- var doneList = this._doneList;
- var len = doneList.length;
- for (var i = 0; i < len; i++) {
- doneList[i].call(this);
- }
- },
- /**
- * 开始执行动画
- * @param {string|Function} [easing]
- * 动画缓动函数,详见{@link module:zrender/animation/easing}
- * @param {boolean} forceAnimate
- * @return {module:zrender/animation/Animator}
- */
- start: function (easing, forceAnimate) {
-
- var self = this;
- var clipCount = 0;
-
- var oneTrackDone = function() {
- clipCount--;
- if (!clipCount) {
- self._doneCallback();
- }
- };
-
- var lastClip;
- for (var propName in this._tracks) {
- if (!this._tracks.hasOwnProperty(propName)) {
- continue;
- }
- var clip = createTrackClip(
- this, easing, oneTrackDone,
- this._tracks[propName], propName, forceAnimate
- );
- if (clip) {
- this._clipList.push(clip);
- clipCount++;
-
- // If start after added to animation
- if (this.animation) {
- this.animation.addClip(clip);
- }
-
- lastClip = clip;
- }
- }
-
- // Add during callback on the last clip
- if (lastClip) {
- var oldOnFrame = lastClip.onframe;
- lastClip.onframe = function (target, percent) {
- oldOnFrame(target, percent);
-
- for (var i = 0; i < self._onframeList.length; i++) {
- self._onframeList[i](target, percent);
- }
- };
- }
-
- // This optimization will help the case that in the upper application
- // the view may be refreshed frequently, where animation will be
- // called repeatly but nothing changed.
- if (!clipCount) {
- this._doneCallback();
- }
- return this;
- },
- /**
- * 停止动画
- * @param {boolean} forwardToLast If move to last frame before stop
- */
- stop: function (forwardToLast) {
- var clipList = this._clipList;
- var animation = this.animation;
- for (var i = 0; i < clipList.length; i++) {
- var clip = clipList[i];
- if (forwardToLast) {
- // Move to last frame before stop
- clip.onframe(this._target, 1);
- }
- animation && animation.removeClip(clip);
- }
- clipList.length = 0;
- },
- /**
- * 设置动画延迟开始的时间
- * @param {number} time 单位ms
- * @return {module:zrender/animation/Animator}
- */
- delay: function (time) {
- this._delay = time;
- return this;
- },
- /**
- * 添加动画结束的回调
- * @param {Function} cb
- * @return {module:zrender/animation/Animator}
- */
- done: function(cb) {
- if (cb) {
- this._doneList.push(cb);
- }
- return this;
- },
-
- /**
- * @return {Array.}
- */
- getClips: function () {
- return this._clipList;
- }
-};
-
-var dpr = 1;
-
-// If in browser environment
-if (typeof window !== 'undefined') {
- dpr = Math.max(window.devicePixelRatio || 1, 1);
-}
-
-/**
- * config默认配置项
- * @exports zrender/config
- * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
- */
-
-/**
- * debug日志选项:catchBrushException为true下有效
- * 0 : 不生成debug数据,发布用
- * 1 : 异常抛出,调试用
- * 2 : 控制台输出,调试用
- */
-var debugMode = 0;
-
-// retina 屏幕优化
-var devicePixelRatio = dpr;
-
-var log = function () {
-};
-
-if (debugMode === 1) {
- log = function () {
- for (var k in arguments) {
- throw new Error(arguments[k]);
- }
- };
-}
-else if (debugMode > 1) {
- log = function () {
- for (var k in arguments) {
- console.log(arguments[k]);
- }
- };
-}
-
-var zrLog = log;
-
-/**
- * @alias modue:zrender/mixin/Animatable
- * @constructor
- */
-var Animatable = function () {
-
- /**
- * @type {Array.}
- * @readOnly
- */
- this.animators = [];
-};
-
-Animatable.prototype = {
-
- constructor: Animatable,
-
- /**
- * 动画
- *
- * @param {string} path The path to fetch value from object, like 'a.b.c'.
- * @param {boolean} [loop] Whether to loop animation.
- * @return {module:zrender/animation/Animator}
- * @example:
- * el.animate('style', false)
- * .when(1000, {x: 10} )
- * .done(function(){ // Animation done })
- * .start()
- */
- animate: function (path, loop) {
- var target;
- var animatingShape = false;
- var el = this;
- var zr = this.__zr;
- if (path) {
- var pathSplitted = path.split('.');
- var prop = el;
- // If animating shape
- animatingShape = pathSplitted[0] === 'shape';
- for (var i = 0, l = pathSplitted.length; i < l; i++) {
- if (!prop) {
- continue;
- }
- prop = prop[pathSplitted[i]];
- }
- if (prop) {
- target = prop;
- }
- }
- else {
- target = el;
- }
-
- if (!target) {
- zrLog(
- 'Property "'
- + path
- + '" is not existed in element '
- + el.id
- );
- return;
- }
-
- var animators = el.animators;
-
- var animator = new Animator(target, loop);
-
- animator.during(function (target) {
- el.dirty(animatingShape);
- })
- .done(function () {
- // FIXME Animator will not be removed if use `Animator#stop` to stop animation
- animators.splice(indexOf(animators, animator), 1);
- });
-
- animators.push(animator);
-
- // If animate after added to the zrender
- if (zr) {
- zr.animation.addAnimator(animator);
- }
-
- return animator;
- },
-
- /**
- * 停止动画
- * @param {boolean} forwardToLast If move to last frame before stop
- */
- stopAnimation: function (forwardToLast) {
- var animators = this.animators;
- var len = animators.length;
- for (var i = 0; i < len; i++) {
- animators[i].stop(forwardToLast);
- }
- animators.length = 0;
-
- return this;
- },
-
- /**
- * Caution: this method will stop previous animation.
- * So do not use this method to one element twice before
- * animation starts, unless you know what you are doing.
- * @param {Object} target
- * @param {number} [time=500] Time in ms
- * @param {string} [easing='linear']
- * @param {number} [delay=0]
- * @param {Function} [callback]
- * @param {Function} [forceAnimate] Prevent stop animation and callback
- * immediently when target values are the same as current values.
- *
- * @example
- * // Animate position
- * el.animateTo({
- * position: [10, 10]
- * }, function () { // done })
- *
- * // Animate shape, style and position in 100ms, delayed 100ms, with cubicOut easing
- * el.animateTo({
- * shape: {
- * width: 500
- * },
- * style: {
- * fill: 'red'
- * }
- * position: [10, 10]
- * }, 100, 100, 'cubicOut', function () { // done })
- */
- // TODO Return animation key
- animateTo: function (target, time, delay, easing, callback, forceAnimate) {
- // animateTo(target, time, easing, callback);
- if (isString(delay)) {
- callback = easing;
- easing = delay;
- delay = 0;
- }
- // animateTo(target, time, delay, callback);
- else if (isFunction$1(easing)) {
- callback = easing;
- easing = 'linear';
- delay = 0;
- }
- // animateTo(target, time, callback);
- else if (isFunction$1(delay)) {
- callback = delay;
- delay = 0;
- }
- // animateTo(target, callback)
- else if (isFunction$1(time)) {
- callback = time;
- time = 500;
- }
- // animateTo(target)
- else if (!time) {
- time = 500;
- }
- // Stop all previous animations
- this.stopAnimation();
- this._animateToShallow('', this, target, time, delay);
-
- // Animators may be removed immediately after start
- // if there is nothing to animate
- var animators = this.animators.slice();
- var count = animators.length;
- function done() {
- count--;
- if (!count) {
- callback && callback();
- }
- }
-
- // No animators. This should be checked before animators[i].start(),
- // because 'done' may be executed immediately if no need to animate.
- if (!count) {
- callback && callback();
- }
- // Start after all animators created
- // Incase any animator is done immediately when all animation properties are not changed
- for (var i = 0; i < animators.length; i++) {
- animators[i]
- .done(done)
- .start(easing, forceAnimate);
- }
- },
-
- /**
- * @private
- * @param {string} path=''
- * @param {Object} source=this
- * @param {Object} target
- * @param {number} [time=500]
- * @param {number} [delay=0]
- *
- * @example
- * // Animate position
- * el._animateToShallow({
- * position: [10, 10]
- * })
- *
- * // Animate shape, style and position in 100ms, delayed 100ms
- * el._animateToShallow({
- * shape: {
- * width: 500
- * },
- * style: {
- * fill: 'red'
- * }
- * position: [10, 10]
- * }, 100, 100)
- */
- _animateToShallow: function (path, source, target, time, delay) {
- var objShallow = {};
- var propertyCount = 0;
- for (var name in target) {
- if (!target.hasOwnProperty(name)) {
- continue;
- }
-
- if (source[name] != null) {
- if (isObject$1(target[name]) && !isArrayLike(target[name])) {
- this._animateToShallow(
- path ? path + '.' + name : name,
- source[name],
- target[name],
- time,
- delay
- );
- }
- else {
- objShallow[name] = target[name];
- propertyCount++;
- }
- }
- else if (target[name] != null) {
- // Attr directly if not has property
- // FIXME, if some property not needed for element ?
- if (!path) {
- this.attr(name, target[name]);
- }
- else { // Shape or style
- var props = {};
- props[path] = {};
- props[path][name] = target[name];
- this.attr(props);
- }
- }
- }
-
- if (propertyCount > 0) {
- this.animate(path, false)
- .when(time == null ? 500 : time, objShallow)
- .delay(delay || 0);
- }
-
- return this;
- }
-};
-
-/**
- * @alias module:zrender/Element
- * @constructor
- * @extends {module:zrender/mixin/Animatable}
- * @extends {module:zrender/mixin/Transformable}
- * @extends {module:zrender/mixin/Eventful}
- */
-var Element = function (opts) { // jshint ignore:line
-
- Transformable.call(this, opts);
- Eventful.call(this, opts);
- Animatable.call(this, opts);
-
- /**
- * 画布元素ID
- * @type {string}
- */
- this.id = opts.id || guid();
-};
-
-Element.prototype = {
-
- /**
- * 元素类型
- * Element type
- * @type {string}
- */
- type: 'element',
-
- /**
- * 元素名字
- * Element name
- * @type {string}
- */
- name: '',
-
- /**
- * ZRender 实例对象,会在 element 添加到 zrender 实例中后自动赋值
- * ZRender instance will be assigned when element is associated with zrender
- * @name module:/zrender/Element#__zr
- * @type {module:zrender/ZRender}
- */
- __zr: null,
-
- /**
- * 图形是否忽略,为true时忽略图形的绘制以及事件触发
- * If ignore drawing and events of the element object
- * @name module:/zrender/Element#ignore
- * @type {boolean}
- * @default false
- */
- ignore: false,
-
- /**
- * 用于裁剪的路径(shape),所有 Group 内的路径在绘制时都会被这个路径裁剪
- * 该路径会继承被裁减对象的变换
- * @type {module:zrender/graphic/Path}
- * @see http://www.w3.org/TR/2dcontext/#clipping-region
- * @readOnly
- */
- clipPath: null,
-
- /**
- * 是否是 Group
- * @type {boolean}
- */
- isGroup: false,
-
- /**
- * Drift element
- * @param {number} dx dx on the global space
- * @param {number} dy dy on the global space
- */
- drift: function (dx, dy) {
- switch (this.draggable) {
- case 'horizontal':
- dy = 0;
- break;
- case 'vertical':
- dx = 0;
- break;
- }
-
- var m = this.transform;
- if (!m) {
- m = this.transform = [1, 0, 0, 1, 0, 0];
- }
- m[4] += dx;
- m[5] += dy;
-
- this.decomposeTransform();
- this.dirty(false);
- },
-
- /**
- * Hook before update
- */
- beforeUpdate: function () {},
- /**
- * Hook after update
- */
- afterUpdate: function () {},
- /**
- * Update each frame
- */
- update: function () {
- this.updateTransform();
- },
-
- /**
- * @param {Function} cb
- * @param {} context
- */
- traverse: function (cb, context) {},
-
- /**
- * @protected
- */
- attrKV: function (key, value) {
- if (key === 'position' || key === 'scale' || key === 'origin') {
- // Copy the array
- if (value) {
- var target = this[key];
- if (!target) {
- target = this[key] = [];
- }
- target[0] = value[0];
- target[1] = value[1];
- }
- }
- else {
- this[key] = value;
- }
- },
-
- /**
- * Hide the element
- */
- hide: function () {
- this.ignore = true;
- this.__zr && this.__zr.refresh();
- },
-
- /**
- * Show the element
- */
- show: function () {
- this.ignore = false;
- this.__zr && this.__zr.refresh();
- },
-
- /**
- * @param {string|Object} key
- * @param {*} value
- */
- attr: function (key, value) {
- if (typeof key === 'string') {
- this.attrKV(key, value);
- }
- else if (isObject$1(key)) {
- for (var name in key) {
- if (key.hasOwnProperty(name)) {
- this.attrKV(name, key[name]);
- }
- }
- }
-
- this.dirty(false);
-
- return this;
- },
-
- /**
- * @param {module:zrender/graphic/Path} clipPath
- */
- setClipPath: function (clipPath) {
- var zr = this.__zr;
- if (zr) {
- clipPath.addSelfToZr(zr);
- }
-
- // Remove previous clip path
- if (this.clipPath && this.clipPath !== clipPath) {
- this.removeClipPath();
- }
-
- this.clipPath = clipPath;
- clipPath.__zr = zr;
- clipPath.__clipTarget = this;
-
- this.dirty(false);
- },
-
- /**
- */
- removeClipPath: function () {
- var clipPath = this.clipPath;
- if (clipPath) {
- if (clipPath.__zr) {
- clipPath.removeSelfFromZr(clipPath.__zr);
- }
-
- clipPath.__zr = null;
- clipPath.__clipTarget = null;
- this.clipPath = null;
-
- this.dirty(false);
- }
- },
-
- /**
- * Add self from zrender instance.
- * Not recursively because it will be invoked when element added to storage.
- * @param {module:zrender/ZRender} zr
- */
- addSelfToZr: function (zr) {
- this.__zr = zr;
- // 添加动画
- var animators = this.animators;
- if (animators) {
- for (var i = 0; i < animators.length; i++) {
- zr.animation.addAnimator(animators[i]);
- }
- }
-
- if (this.clipPath) {
- this.clipPath.addSelfToZr(zr);
- }
- },
-
- /**
- * Remove self from zrender instance.
- * Not recursively because it will be invoked when element added to storage.
- * @param {module:zrender/ZRender} zr
- */
- removeSelfFromZr: function (zr) {
- this.__zr = null;
- // 移除动画
- var animators = this.animators;
- if (animators) {
- for (var i = 0; i < animators.length; i++) {
- zr.animation.removeAnimator(animators[i]);
- }
- }
-
- if (this.clipPath) {
- this.clipPath.removeSelfFromZr(zr);
- }
- }
-};
-
-mixin(Element, Animatable);
-mixin(Element, Transformable);
-mixin(Element, Eventful);
-
-/**
- * @module echarts/core/BoundingRect
- */
-
-var v2ApplyTransform = applyTransform;
-var mathMin = Math.min;
-var mathMax = Math.max;
-
-/**
- * @alias module:echarts/core/BoundingRect
- */
-function BoundingRect(x, y, width, height) {
-
- if (width < 0) {
- x = x + width;
- width = -width;
- }
- if (height < 0) {
- y = y + height;
- height = -height;
- }
-
- /**
- * @type {number}
- */
- this.x = x;
- /**
- * @type {number}
- */
- this.y = y;
- /**
- * @type {number}
- */
- this.width = width;
- /**
- * @type {number}
- */
- this.height = height;
-}
-
-BoundingRect.prototype = {
-
- constructor: BoundingRect,
-
- /**
- * @param {module:echarts/core/BoundingRect} other
- */
- union: function (other) {
- var x = mathMin(other.x, this.x);
- var y = mathMin(other.y, this.y);
-
- this.width = mathMax(
- other.x + other.width,
- this.x + this.width
- ) - x;
- this.height = mathMax(
- other.y + other.height,
- this.y + this.height
- ) - y;
- this.x = x;
- this.y = y;
- },
-
- /**
- * @param {Array.} m
- * @methods
- */
- applyTransform: (function () {
- var lt = [];
- var rb = [];
- var lb = [];
- var rt = [];
- return function (m) {
- // In case usage like this
- // el.getBoundingRect().applyTransform(el.transform)
- // And element has no transform
- if (!m) {
- return;
- }
- lt[0] = lb[0] = this.x;
- lt[1] = rt[1] = this.y;
- rb[0] = rt[0] = this.x + this.width;
- rb[1] = lb[1] = this.y + this.height;
-
- v2ApplyTransform(lt, lt, m);
- v2ApplyTransform(rb, rb, m);
- v2ApplyTransform(lb, lb, m);
- v2ApplyTransform(rt, rt, m);
-
- this.x = mathMin(lt[0], rb[0], lb[0], rt[0]);
- this.y = mathMin(lt[1], rb[1], lb[1], rt[1]);
- var maxX = mathMax(lt[0], rb[0], lb[0], rt[0]);
- var maxY = mathMax(lt[1], rb[1], lb[1], rt[1]);
- this.width = maxX - this.x;
- this.height = maxY - this.y;
- };
- })(),
-
- /**
- * Calculate matrix of transforming from self to target rect
- * @param {module:zrender/core/BoundingRect} b
- * @return {Array.}
- */
- calculateTransform: function (b) {
- var a = this;
- var sx = b.width / a.width;
- var sy = b.height / a.height;
-
- var m = create$1();
-
- // 矩阵右乘
- translate(m, m, [-a.x, -a.y]);
- scale$1(m, m, [sx, sy]);
- translate(m, m, [b.x, b.y]);
-
- return m;
- },
-
- /**
- * @param {(module:echarts/core/BoundingRect|Object)} b
- * @return {boolean}
- */
- intersect: function (b) {
- if (!b) {
- return false;
- }
-
- if (!(b instanceof BoundingRect)) {
- // Normalize negative width/height.
- b = BoundingRect.create(b);
- }
-
- var a = this;
- var ax0 = a.x;
- var ax1 = a.x + a.width;
- var ay0 = a.y;
- var ay1 = a.y + a.height;
-
- var bx0 = b.x;
- var bx1 = b.x + b.width;
- var by0 = b.y;
- var by1 = b.y + b.height;
-
- return ! (ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
- },
-
- contain: function (x, y) {
- var rect = this;
- return x >= rect.x
- && x <= (rect.x + rect.width)
- && y >= rect.y
- && y <= (rect.y + rect.height);
- },
-
- /**
- * @return {module:echarts/core/BoundingRect}
- */
- clone: function () {
- return new BoundingRect(this.x, this.y, this.width, this.height);
- },
-
- /**
- * Copy from another rect
- */
- copy: function (other) {
- this.x = other.x;
- this.y = other.y;
- this.width = other.width;
- this.height = other.height;
- },
-
- plain: function () {
- return {
- x: this.x,
- y: this.y,
- width: this.width,
- height: this.height
- };
- }
-};
-
-/**
- * @param {Object|module:zrender/core/BoundingRect} rect
- * @param {number} rect.x
- * @param {number} rect.y
- * @param {number} rect.width
- * @param {number} rect.height
- * @return {module:zrender/core/BoundingRect}
- */
-BoundingRect.create = function (rect) {
- return new BoundingRect(rect.x, rect.y, rect.width, rect.height);
-};
-
-/**
- * Group是一个容器,可以插入子节点,Group的变换也会被应用到子节点上
- * @module zrender/graphic/Group
- * @example
- * var Group = require('zrender/container/Group');
- * var Circle = require('zrender/graphic/shape/Circle');
- * var g = new Group();
- * g.position[0] = 100;
- * g.position[1] = 100;
- * g.add(new Circle({
- * style: {
- * x: 100,
- * y: 100,
- * r: 20,
- * }
- * }));
- * zr.add(g);
- */
-
-/**
- * @alias module:zrender/graphic/Group
- * @constructor
- * @extends module:zrender/mixin/Transformable
- * @extends module:zrender/mixin/Eventful
- */
-var Group = function (opts) {
-
- opts = opts || {};
-
- Element.call(this, opts);
-
- for (var key in opts) {
- if (opts.hasOwnProperty(key)) {
- this[key] = opts[key];
- }
- }
-
- this._children = [];
-
- this.__storage = null;
-
- this.__dirty = true;
-};
-
-Group.prototype = {
-
- constructor: Group,
-
- isGroup: true,
-
- /**
- * @type {string}
- */
- type: 'group',
-
- /**
- * 所有子孙元素是否响应鼠标事件
- * @name module:/zrender/container/Group#silent
- * @type {boolean}
- * @default false
- */
- silent: false,
-
- /**
- * @return {Array.}
- */
- children: function () {
- return this._children.slice();
- },
-
- /**
- * 获取指定 index 的儿子节点
- * @param {number} idx
- * @return {module:zrender/Element}
- */
- childAt: function (idx) {
- return this._children[idx];
- },
-
- /**
- * 获取指定名字的儿子节点
- * @param {string} name
- * @return {module:zrender/Element}
- */
- childOfName: function (name) {
- var children = this._children;
- for (var i = 0; i < children.length; i++) {
- if (children[i].name === name) {
- return children[i];
- }
- }
- },
-
- /**
- * @return {number}
- */
- childCount: function () {
- return this._children.length;
- },
-
- /**
- * 添加子节点到最后
- * @param {module:zrender/Element} child
- */
- add: function (child) {
- if (child && child !== this && child.parent !== this) {
-
- this._children.push(child);
-
- this._doAdd(child);
- }
-
- return this;
- },
-
- /**
- * 添加子节点在 nextSibling 之前
- * @param {module:zrender/Element} child
- * @param {module:zrender/Element} nextSibling
- */
- addBefore: function (child, nextSibling) {
- if (child && child !== this && child.parent !== this
- && nextSibling && nextSibling.parent === this) {
-
- var children = this._children;
- var idx = children.indexOf(nextSibling);
-
- if (idx >= 0) {
- children.splice(idx, 0, child);
- this._doAdd(child);
- }
- }
-
- return this;
- },
-
- _doAdd: function (child) {
- if (child.parent) {
- child.parent.remove(child);
- }
-
- child.parent = this;
-
- var storage = this.__storage;
- var zr = this.__zr;
- if (storage && storage !== child.__storage) {
-
- storage.addToStorage(child);
-
- if (child instanceof Group) {
- child.addChildrenToStorage(storage);
- }
- }
-
- zr && zr.refresh();
- },
-
- /**
- * 移除子节点
- * @param {module:zrender/Element} child
- */
- remove: function (child) {
- var zr = this.__zr;
- var storage = this.__storage;
- var children = this._children;
-
- var idx = indexOf(children, child);
- if (idx < 0) {
- return this;
- }
- children.splice(idx, 1);
-
- child.parent = null;
-
- if (storage) {
-
- storage.delFromStorage(child);
-
- if (child instanceof Group) {
- child.delChildrenFromStorage(storage);
- }
- }
-
- zr && zr.refresh();
-
- return this;
- },
-
- /**
- * 移除所有子节点
- */
- removeAll: function () {
- var children = this._children;
- var storage = this.__storage;
- var child;
- var i;
- for (i = 0; i < children.length; i++) {
- child = children[i];
- if (storage) {
- storage.delFromStorage(child);
- if (child instanceof Group) {
- child.delChildrenFromStorage(storage);
- }
- }
- child.parent = null;
- }
- children.length = 0;
-
- return this;
- },
-
- /**
- * 遍历所有子节点
- * @param {Function} cb
- * @param {} context
- */
- eachChild: function (cb, context) {
- var children = this._children;
- for (var i = 0; i < children.length; i++) {
- var child = children[i];
- cb.call(context, child, i);
- }
- return this;
- },
-
- /**
- * 深度优先遍历所有子孙节点
- * @param {Function} cb
- * @param {} context
- */
- traverse: function (cb, context) {
- for (var i = 0; i < this._children.length; i++) {
- var child = this._children[i];
- cb.call(context, child);
-
- if (child.type === 'group') {
- child.traverse(cb, context);
- }
- }
- return this;
- },
-
- addChildrenToStorage: function (storage) {
- for (var i = 0; i < this._children.length; i++) {
- var child = this._children[i];
- storage.addToStorage(child);
- if (child instanceof Group) {
- child.addChildrenToStorage(storage);
- }
- }
- },
-
- delChildrenFromStorage: function (storage) {
- for (var i = 0; i < this._children.length; i++) {
- var child = this._children[i];
- storage.delFromStorage(child);
- if (child instanceof Group) {
- child.delChildrenFromStorage(storage);
- }
- }
- },
-
- dirty: function () {
- this.__dirty = true;
- this.__zr && this.__zr.refresh();
- return this;
- },
-
- /**
- * @return {module:zrender/core/BoundingRect}
- */
- getBoundingRect: function (includeChildren) {
- // TODO Caching
- var rect = null;
- var tmpRect = new BoundingRect(0, 0, 0, 0);
- var children = includeChildren || this._children;
- var tmpMat = [];
-
- for (var i = 0; i < children.length; i++) {
- var child = children[i];
- if (child.ignore || child.invisible) {
- continue;
- }
-
- var childRect = child.getBoundingRect();
- var transform = child.getLocalTransform(tmpMat);
- // TODO
- // The boundingRect cacluated by transforming original
- // rect may be bigger than the actual bundingRect when rotation
- // is used. (Consider a circle rotated aginst its center, where
- // the actual boundingRect should be the same as that not be
- // rotated.) But we can not find better approach to calculate
- // actual boundingRect yet, considering performance.
- if (transform) {
- tmpRect.copy(childRect);
- tmpRect.applyTransform(transform);
- rect = rect || tmpRect.clone();
- rect.union(tmpRect);
- }
- else {
- rect = rect || childRect.clone();
- rect.union(childRect);
- }
- }
- return rect || tmpRect;
- }
-};
-
-inherits(Group, Element);
-
-// https://github.com/mziccard/node-timsort
-var DEFAULT_MIN_MERGE = 32;
-
-var DEFAULT_MIN_GALLOPING = 7;
-
-function minRunLength(n) {
- var r = 0;
-
- while (n >= DEFAULT_MIN_MERGE) {
- r |= n & 1;
- n >>= 1;
- }
-
- return n + r;
-}
-
-function makeAscendingRun(array, lo, hi, compare) {
- var runHi = lo + 1;
-
- if (runHi === hi) {
- return 1;
- }
-
- if (compare(array[runHi++], array[lo]) < 0) {
- while (runHi < hi && compare(array[runHi], array[runHi - 1]) < 0) {
- runHi++;
- }
-
- reverseRun(array, lo, runHi);
- }
- else {
- while (runHi < hi && compare(array[runHi], array[runHi - 1]) >= 0) {
- runHi++;
- }
- }
-
- return runHi - lo;
-}
-
-function reverseRun(array, lo, hi) {
- hi--;
-
- while (lo < hi) {
- var t = array[lo];
- array[lo++] = array[hi];
- array[hi--] = t;
- }
-}
-
-function binaryInsertionSort(array, lo, hi, start, compare) {
- if (start === lo) {
- start++;
- }
-
- for (; start < hi; start++) {
- var pivot = array[start];
-
- var left = lo;
- var right = start;
- var mid;
-
- while (left < right) {
- mid = left + right >>> 1;
-
- if (compare(pivot, array[mid]) < 0) {
- right = mid;
- }
- else {
- left = mid + 1;
- }
- }
-
- var n = start - left;
-
- switch (n) {
- case 3:
- array[left + 3] = array[left + 2];
-
- case 2:
- array[left + 2] = array[left + 1];
-
- case 1:
- array[left + 1] = array[left];
- break;
- default:
- while (n > 0) {
- array[left + n] = array[left + n - 1];
- n--;
- }
- }
-
- array[left] = pivot;
- }
-}
-
-function gallopLeft(value, array, start, length, hint, compare) {
- var lastOffset = 0;
- var maxOffset = 0;
- var offset = 1;
-
- if (compare(value, array[start + hint]) > 0) {
- maxOffset = length - hint;
-
- while (offset < maxOffset && compare(value, array[start + hint + offset]) > 0) {
- lastOffset = offset;
- offset = (offset << 1) + 1;
-
- if (offset <= 0) {
- offset = maxOffset;
- }
- }
-
- if (offset > maxOffset) {
- offset = maxOffset;
- }
-
- lastOffset += hint;
- offset += hint;
- }
- else {
- maxOffset = hint + 1;
- while (offset < maxOffset && compare(value, array[start + hint - offset]) <= 0) {
- lastOffset = offset;
- offset = (offset << 1) + 1;
-
- if (offset <= 0) {
- offset = maxOffset;
- }
- }
- if (offset > maxOffset) {
- offset = maxOffset;
- }
-
- var tmp = lastOffset;
- lastOffset = hint - offset;
- offset = hint - tmp;
- }
-
- lastOffset++;
- while (lastOffset < offset) {
- var m = lastOffset + (offset - lastOffset >>> 1);
-
- if (compare(value, array[start + m]) > 0) {
- lastOffset = m + 1;
- }
- else {
- offset = m;
- }
- }
- return offset;
-}
-
-function gallopRight(value, array, start, length, hint, compare) {
- var lastOffset = 0;
- var maxOffset = 0;
- var offset = 1;
-
- if (compare(value, array[start + hint]) < 0) {
- maxOffset = hint + 1;
-
- while (offset < maxOffset && compare(value, array[start + hint - offset]) < 0) {
- lastOffset = offset;
- offset = (offset << 1) + 1;
-
- if (offset <= 0) {
- offset = maxOffset;
- }
- }
-
- if (offset > maxOffset) {
- offset = maxOffset;
- }
-
- var tmp = lastOffset;
- lastOffset = hint - offset;
- offset = hint - tmp;
- }
- else {
- maxOffset = length - hint;
-
- while (offset < maxOffset && compare(value, array[start + hint + offset]) >= 0) {
- lastOffset = offset;
- offset = (offset << 1) + 1;
-
- if (offset <= 0) {
- offset = maxOffset;
- }
- }
-
- if (offset > maxOffset) {
- offset = maxOffset;
- }
-
- lastOffset += hint;
- offset += hint;
- }
-
- lastOffset++;
-
- while (lastOffset < offset) {
- var m = lastOffset + (offset - lastOffset >>> 1);
-
- if (compare(value, array[start + m]) < 0) {
- offset = m;
- }
- else {
- lastOffset = m + 1;
- }
- }
-
- return offset;
-}
-
-function TimSort(array, compare) {
- var minGallop = DEFAULT_MIN_GALLOPING;
- var runStart;
- var runLength;
- var stackSize = 0;
-
- var tmp = [];
-
- runStart = [];
- runLength = [];
-
- function pushRun(_runStart, _runLength) {
- runStart[stackSize] = _runStart;
- runLength[stackSize] = _runLength;
- stackSize += 1;
- }
-
- function mergeRuns() {
- while (stackSize > 1) {
- var n = stackSize - 2;
-
- if (n >= 1 && runLength[n - 1] <= runLength[n] + runLength[n + 1] || n >= 2 && runLength[n - 2] <= runLength[n] + runLength[n - 1]) {
- if (runLength[n - 1] < runLength[n + 1]) {
- n--;
- }
- }
- else if (runLength[n] > runLength[n + 1]) {
- break;
- }
- mergeAt(n);
- }
- }
-
- function forceMergeRuns() {
- while (stackSize > 1) {
- var n = stackSize - 2;
-
- if (n > 0 && runLength[n - 1] < runLength[n + 1]) {
- n--;
- }
-
- mergeAt(n);
- }
- }
-
- function mergeAt(i) {
- var start1 = runStart[i];
- var length1 = runLength[i];
- var start2 = runStart[i + 1];
- var length2 = runLength[i + 1];
-
- runLength[i] = length1 + length2;
-
- if (i === stackSize - 3) {
- runStart[i + 1] = runStart[i + 2];
- runLength[i + 1] = runLength[i + 2];
- }
-
- stackSize--;
-
- var k = gallopRight(array[start2], array, start1, length1, 0, compare);
- start1 += k;
- length1 -= k;
-
- if (length1 === 0) {
- return;
- }
-
- length2 = gallopLeft(array[start1 + length1 - 1], array, start2, length2, length2 - 1, compare);
-
- if (length2 === 0) {
- return;
- }
-
- if (length1 <= length2) {
- mergeLow(start1, length1, start2, length2);
- }
- else {
- mergeHigh(start1, length1, start2, length2);
- }
- }
-
- function mergeLow(start1, length1, start2, length2) {
- var i = 0;
-
- for (i = 0; i < length1; i++) {
- tmp[i] = array[start1 + i];
- }
-
- var cursor1 = 0;
- var cursor2 = start2;
- var dest = start1;
-
- array[dest++] = array[cursor2++];
-
- if (--length2 === 0) {
- for (i = 0; i < length1; i++) {
- array[dest + i] = tmp[cursor1 + i];
- }
- return;
- }
-
- if (length1 === 1) {
- for (i = 0; i < length2; i++) {
- array[dest + i] = array[cursor2 + i];
- }
- array[dest + length2] = tmp[cursor1];
- return;
- }
-
- var _minGallop = minGallop;
- var count1, count2, exit;
-
- while (1) {
- count1 = 0;
- count2 = 0;
- exit = false;
-
- do {
- if (compare(array[cursor2], tmp[cursor1]) < 0) {
- array[dest++] = array[cursor2++];
- count2++;
- count1 = 0;
-
- if (--length2 === 0) {
- exit = true;
- break;
- }
- }
- else {
- array[dest++] = tmp[cursor1++];
- count1++;
- count2 = 0;
- if (--length1 === 1) {
- exit = true;
- break;
- }
- }
- } while ((count1 | count2) < _minGallop);
-
- if (exit) {
- break;
- }
-
- do {
- count1 = gallopRight(array[cursor2], tmp, cursor1, length1, 0, compare);
-
- if (count1 !== 0) {
- for (i = 0; i < count1; i++) {
- array[dest + i] = tmp[cursor1 + i];
- }
-
- dest += count1;
- cursor1 += count1;
- length1 -= count1;
- if (length1 <= 1) {
- exit = true;
- break;
- }
- }
-
- array[dest++] = array[cursor2++];
-
- if (--length2 === 0) {
- exit = true;
- break;
- }
-
- count2 = gallopLeft(tmp[cursor1], array, cursor2, length2, 0, compare);
-
- if (count2 !== 0) {
- for (i = 0; i < count2; i++) {
- array[dest + i] = array[cursor2 + i];
- }
-
- dest += count2;
- cursor2 += count2;
- length2 -= count2;
-
- if (length2 === 0) {
- exit = true;
- break;
- }
- }
- array[dest++] = tmp[cursor1++];
-
- if (--length1 === 1) {
- exit = true;
- break;
- }
-
- _minGallop--;
- } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);
-
- if (exit) {
- break;
- }
-
- if (_minGallop < 0) {
- _minGallop = 0;
- }
-
- _minGallop += 2;
- }
-
- minGallop = _minGallop;
-
- minGallop < 1 && (minGallop = 1);
-
- if (length1 === 1) {
- for (i = 0; i < length2; i++) {
- array[dest + i] = array[cursor2 + i];
- }
- array[dest + length2] = tmp[cursor1];
- }
- else if (length1 === 0) {
- throw new Error();
- // throw new Error('mergeLow preconditions were not respected');
- }
- else {
- for (i = 0; i < length1; i++) {
- array[dest + i] = tmp[cursor1 + i];
- }
- }
- }
-
- function mergeHigh (start1, length1, start2, length2) {
- var i = 0;
-
- for (i = 0; i < length2; i++) {
- tmp[i] = array[start2 + i];
- }
-
- var cursor1 = start1 + length1 - 1;
- var cursor2 = length2 - 1;
- var dest = start2 + length2 - 1;
- var customCursor = 0;
- var customDest = 0;
-
- array[dest--] = array[cursor1--];
-
- if (--length1 === 0) {
- customCursor = dest - (length2 - 1);
-
- for (i = 0; i < length2; i++) {
- array[customCursor + i] = tmp[i];
- }
-
- return;
- }
-
- if (length2 === 1) {
- dest -= length1;
- cursor1 -= length1;
- customDest = dest + 1;
- customCursor = cursor1 + 1;
-
- for (i = length1 - 1; i >= 0; i--) {
- array[customDest + i] = array[customCursor + i];
- }
-
- array[dest] = tmp[cursor2];
- return;
- }
-
- var _minGallop = minGallop;
-
- while (true) {
- var count1 = 0;
- var count2 = 0;
- var exit = false;
-
- do {
- if (compare(tmp[cursor2], array[cursor1]) < 0) {
- array[dest--] = array[cursor1--];
- count1++;
- count2 = 0;
- if (--length1 === 0) {
- exit = true;
- break;
- }
- }
- else {
- array[dest--] = tmp[cursor2--];
- count2++;
- count1 = 0;
- if (--length2 === 1) {
- exit = true;
- break;
- }
- }
- } while ((count1 | count2) < _minGallop);
-
- if (exit) {
- break;
- }
-
- do {
- count1 = length1 - gallopRight(tmp[cursor2], array, start1, length1, length1 - 1, compare);
-
- if (count1 !== 0) {
- dest -= count1;
- cursor1 -= count1;
- length1 -= count1;
- customDest = dest + 1;
- customCursor = cursor1 + 1;
-
- for (i = count1 - 1; i >= 0; i--) {
- array[customDest + i] = array[customCursor + i];
- }
-
- if (length1 === 0) {
- exit = true;
- break;
- }
- }
-
- array[dest--] = tmp[cursor2--];
-
- if (--length2 === 1) {
- exit = true;
- break;
- }
-
- count2 = length2 - gallopLeft(array[cursor1], tmp, 0, length2, length2 - 1, compare);
-
- if (count2 !== 0) {
- dest -= count2;
- cursor2 -= count2;
- length2 -= count2;
- customDest = dest + 1;
- customCursor = cursor2 + 1;
-
- for (i = 0; i < count2; i++) {
- array[customDest + i] = tmp[customCursor + i];
- }
-
- if (length2 <= 1) {
- exit = true;
- break;
- }
- }
-
- array[dest--] = array[cursor1--];
-
- if (--length1 === 0) {
- exit = true;
- break;
- }
-
- _minGallop--;
- } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);
-
- if (exit) {
- break;
- }
-
- if (_minGallop < 0) {
- _minGallop = 0;
- }
-
- _minGallop += 2;
- }
-
- minGallop = _minGallop;
-
- if (minGallop < 1) {
- minGallop = 1;
- }
-
- if (length2 === 1) {
- dest -= length1;
- cursor1 -= length1;
- customDest = dest + 1;
- customCursor = cursor1 + 1;
-
- for (i = length1 - 1; i >= 0; i--) {
- array[customDest + i] = array[customCursor + i];
- }
-
- array[dest] = tmp[cursor2];
- }
- else if (length2 === 0) {
- throw new Error();
- // throw new Error('mergeHigh preconditions were not respected');
- }
- else {
- customCursor = dest - (length2 - 1);
- for (i = 0; i < length2; i++) {
- array[customCursor + i] = tmp[i];
- }
- }
- }
-
- this.mergeRuns = mergeRuns;
- this.forceMergeRuns = forceMergeRuns;
- this.pushRun = pushRun;
-}
-
-function sort(array, compare, lo, hi) {
- if (!lo) {
- lo = 0;
- }
- if (!hi) {
- hi = array.length;
- }
-
- var remaining = hi - lo;
-
- if (remaining < 2) {
- return;
- }
-
- var runLength = 0;
-
- if (remaining < DEFAULT_MIN_MERGE) {
- runLength = makeAscendingRun(array, lo, hi, compare);
- binaryInsertionSort(array, lo, hi, lo + runLength, compare);
- return;
- }
-
- var ts = new TimSort(array, compare);
-
- var minRun = minRunLength(remaining);
-
- do {
- runLength = makeAscendingRun(array, lo, hi, compare);
- if (runLength < minRun) {
- var force = remaining;
- if (force > minRun) {
- force = minRun;
- }
-
- binaryInsertionSort(array, lo, lo + force, lo + runLength, compare);
- runLength = force;
- }
-
- ts.pushRun(lo, runLength);
- ts.mergeRuns();
-
- remaining -= runLength;
- lo += runLength;
- } while (remaining !== 0);
-
- ts.forceMergeRuns();
-}
-
-// Use timsort because in most case elements are partially sorted
-// https://jsfiddle.net/pissang/jr4x7mdm/8/
-function shapeCompareFunc(a, b) {
- if (a.zlevel === b.zlevel) {
- if (a.z === b.z) {
- // if (a.z2 === b.z2) {
- // // FIXME Slow has renderidx compare
- // // http://stackoverflow.com/questions/20883421/sorting-in-javascript-should-every-compare-function-have-a-return-0-statement
- // // https://github.com/v8/v8/blob/47cce544a31ed5577ffe2963f67acb4144ee0232/src/js/array.js#L1012
- // return a.__renderidx - b.__renderidx;
- // }
- return a.z2 - b.z2;
- }
- return a.z - b.z;
- }
- return a.zlevel - b.zlevel;
-}
-/**
- * 内容仓库 (M)
- * @alias module:zrender/Storage
- * @constructor
- */
-var Storage = function () { // jshint ignore:line
- this._roots = [];
-
- this._displayList = [];
-
- this._displayListLen = 0;
-};
-
-Storage.prototype = {
-
- constructor: Storage,
-
- /**
- * @param {Function} cb
- *
- */
- traverse: function (cb, context) {
- for (var i = 0; i < this._roots.length; i++) {
- this._roots[i].traverse(cb, context);
- }
- },
-
- /**
- * 返回所有图形的绘制队列
- * @param {boolean} [update=false] 是否在返回前更新该数组
- * @param {boolean} [includeIgnore=false] 是否包含 ignore 的数组, 在 update 为 true 的时候有效
- *
- * 详见{@link module:zrender/graphic/Displayable.prototype.updateDisplayList}
- * @return {Array.}
- */
- getDisplayList: function (update, includeIgnore) {
- includeIgnore = includeIgnore || false;
- if (update) {
- this.updateDisplayList(includeIgnore);
- }
- return this._displayList;
- },
-
- /**
- * 更新图形的绘制队列。
- * 每次绘制前都会调用,该方法会先深度优先遍历整个树,更新所有Group和Shape的变换并且把所有可见的Shape保存到数组中,
- * 最后根据绘制的优先级(zlevel > z > 插入顺序)排序得到绘制队列
- * @param {boolean} [includeIgnore=false] 是否包含 ignore 的数组
- */
- updateDisplayList: function (includeIgnore) {
- this._displayListLen = 0;
-
- var roots = this._roots;
- var displayList = this._displayList;
- for (var i = 0, len = roots.length; i < len; i++) {
- this._updateAndAddDisplayable(roots[i], null, includeIgnore);
- }
-
- displayList.length = this._displayListLen;
-
- env$1.canvasSupported && sort(displayList, shapeCompareFunc);
- },
-
- _updateAndAddDisplayable: function (el, clipPaths, includeIgnore) {
-
- if (el.ignore && !includeIgnore) {
- return;
- }
-
- el.beforeUpdate();
-
- if (el.__dirty) {
-
- el.update();
-
- }
-
- el.afterUpdate();
-
- var userSetClipPath = el.clipPath;
- if (userSetClipPath) {
-
- // FIXME 效率影响
- if (clipPaths) {
- clipPaths = clipPaths.slice();
- }
- else {
- clipPaths = [];
- }
-
- var currentClipPath = userSetClipPath;
- var parentClipPath = el;
- // Recursively add clip path
- while (currentClipPath) {
- // clipPath 的变换是基于使用这个 clipPath 的元素
- currentClipPath.parent = parentClipPath;
- currentClipPath.updateTransform();
-
- clipPaths.push(currentClipPath);
-
- parentClipPath = currentClipPath;
- currentClipPath = currentClipPath.clipPath;
- }
- }
-
- if (el.isGroup) {
- var children = el._children;
-
- for (var i = 0; i < children.length; i++) {
- var child = children[i];
-
- // Force to mark as dirty if group is dirty
- // FIXME __dirtyPath ?
- if (el.__dirty) {
- child.__dirty = true;
- }
-
- this._updateAndAddDisplayable(child, clipPaths, includeIgnore);
- }
-
- // Mark group clean here
- el.__dirty = false;
-
- }
- else {
- el.__clipPaths = clipPaths;
-
- this._displayList[this._displayListLen++] = el;
- }
- },
-
- /**
- * 添加图形(Shape)或者组(Group)到根节点
- * @param {module:zrender/Element} el
- */
- addRoot: function (el) {
- if (el.__storage === this) {
- return;
- }
-
- if (el instanceof Group) {
- el.addChildrenToStorage(this);
- }
-
- this.addToStorage(el);
- this._roots.push(el);
- },
-
- /**
- * 删除指定的图形(Shape)或者组(Group)
- * @param {string|Array.} [el] 如果为空清空整个Storage
- */
- delRoot: function (el) {
- if (el == null) {
- // 不指定el清空
- for (var i = 0; i < this._roots.length; i++) {
- var root = this._roots[i];
- if (root instanceof Group) {
- root.delChildrenFromStorage(this);
- }
- }
-
- this._roots = [];
- this._displayList = [];
- this._displayListLen = 0;
-
- return;
- }
-
- if (el instanceof Array) {
- for (var i = 0, l = el.length; i < l; i++) {
- this.delRoot(el[i]);
- }
- return;
- }
-
-
- var idx = indexOf(this._roots, el);
- if (idx >= 0) {
- this.delFromStorage(el);
- this._roots.splice(idx, 1);
- if (el instanceof Group) {
- el.delChildrenFromStorage(this);
- }
- }
- },
-
- addToStorage: function (el) {
- if (el) {
- el.__storage = this;
- el.dirty(false);
- }
- return this;
- },
-
- delFromStorage: function (el) {
- if (el) {
- el.__storage = null;
- }
-
- return this;
- },
-
- /**
- * 清空并且释放Storage
- */
- dispose: function () {
- this._renderList =
- this._roots = null;
- },
-
- displayableSortFunc: shapeCompareFunc
-};
-
-var SHADOW_PROPS = {
- 'shadowBlur': 1,
- 'shadowOffsetX': 1,
- 'shadowOffsetY': 1,
- 'textShadowBlur': 1,
- 'textShadowOffsetX': 1,
- 'textShadowOffsetY': 1,
- 'textBoxShadowBlur': 1,
- 'textBoxShadowOffsetX': 1,
- 'textBoxShadowOffsetY': 1
-};
-
-var fixShadow = function (ctx, propName, value) {
- if (SHADOW_PROPS.hasOwnProperty(propName)) {
- return value *= ctx.dpr;
- }
- return value;
-};
-
-var STYLE_COMMON_PROPS = [
- ['shadowBlur', 0], ['shadowOffsetX', 0], ['shadowOffsetY', 0], ['shadowColor', '#000'],
- ['lineCap', 'butt'], ['lineJoin', 'miter'], ['miterLimit', 10]
-];
-
-// var SHADOW_PROPS = STYLE_COMMON_PROPS.slice(0, 4);
-// var LINE_PROPS = STYLE_COMMON_PROPS.slice(4);
-
-var Style = function (opts, host) {
- this.extendFrom(opts, false);
- this.host = host;
-};
-
-function createLinearGradient(ctx, obj, rect) {
- var x = obj.x == null ? 0 : obj.x;
- var x2 = obj.x2 == null ? 1 : obj.x2;
- var y = obj.y == null ? 0 : obj.y;
- var y2 = obj.y2 == null ? 0 : obj.y2;
-
- if (!obj.global) {
- x = x * rect.width + rect.x;
- x2 = x2 * rect.width + rect.x;
- y = y * rect.height + rect.y;
- y2 = y2 * rect.height + rect.y;
- }
-
- // Fix NaN when rect is Infinity
- x = isNaN(x) ? 0 : x;
- x2 = isNaN(x2) ? 1 : x2;
- y = isNaN(y) ? 0 : y;
- y2 = isNaN(y2) ? 0 : y2;
-
- var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);
-
- return canvasGradient;
-}
-
-function createRadialGradient(ctx, obj, rect) {
- var width = rect.width;
- var height = rect.height;
- var min = Math.min(width, height);
-
- var x = obj.x == null ? 0.5 : obj.x;
- var y = obj.y == null ? 0.5 : obj.y;
- var r = obj.r == null ? 0.5 : obj.r;
- if (!obj.global) {
- x = x * width + rect.x;
- y = y * height + rect.y;
- r = r * min;
- }
-
- var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
-
- return canvasGradient;
-}
-
-
-Style.prototype = {
-
- constructor: Style,
-
- /**
- * @type {module:zrender/graphic/Displayable}
- */
- host: null,
-
- /**
- * @type {string}
- */
- fill: '#000',
-
- /**
- * @type {string}
- */
- stroke: null,
-
- /**
- * @type {number}
- */
- opacity: 1,
-
- /**
- * @type {Array.}
- */
- lineDash: null,
-
- /**
- * @type {number}
- */
- lineDashOffset: 0,
-
- /**
- * @type {number}
- */
- shadowBlur: 0,
-
- /**
- * @type {number}
- */
- shadowOffsetX: 0,
-
- /**
- * @type {number}
- */
- shadowOffsetY: 0,
-
- /**
- * @type {number}
- */
- lineWidth: 1,
-
- /**
- * If stroke ignore scale
- * @type {Boolean}
- */
- strokeNoScale: false,
-
- // Bounding rect text configuration
- // Not affected by element transform
- /**
- * @type {string}
- */
- text: null,
-
- /**
- * If `fontSize` or `fontFamily` exists, `font` will be reset by
- * `fontSize`, `fontStyle`, `fontWeight`, `fontFamily`.
- * So do not visit it directly in upper application (like echarts),
- * but use `contain/text#makeFont` instead.
- * @type {string}
- */
- font: null,
-
- /**
- * The same as font. Use font please.
- * @deprecated
- * @type {string}
- */
- textFont: null,
-
- /**
- * It helps merging respectively, rather than parsing an entire font string.
- * @type {string}
- */
- fontStyle: null,
-
- /**
- * It helps merging respectively, rather than parsing an entire font string.
- * @type {string}
- */
- fontWeight: null,
-
- /**
- * It helps merging respectively, rather than parsing an entire font string.
- * Should be 12 but not '12px'.
- * @type {number}
- */
- fontSize: null,
-
- /**
- * It helps merging respectively, rather than parsing an entire font string.
- * @type {string}
- */
- fontFamily: null,
-
- /**
- * Reserved for special functinality, like 'hr'.
- * @type {string}
- */
- textTag: null,
-
- /**
- * @type {string}
- */
- textFill: '#000',
-
- /**
- * @type {string}
- */
- textStroke: null,
-
- /**
- * @type {number}
- */
- textWidth: null,
-
- /**
- * Only for textBackground.
- * @type {number}
- */
- textHeight: null,
-
- /**
- * textStroke may be set as some color as a default
- * value in upper applicaion, where the default value
- * of textStrokeWidth should be 0 to make sure that
- * user can choose to do not use text stroke.
- * @type {number}
- */
- textStrokeWidth: 0,
-
- /**
- * @type {number}
- */
- textLineHeight: null,
-
- /**
- * 'inside', 'left', 'right', 'top', 'bottom'
- * [x, y]
- * Based on x, y of rect.
- * @type {string|Array.}
- * @default 'inside'
- */
- textPosition: 'inside',
-
- /**
- * If not specified, use the boundingRect of a `displayable`.
- * @type {Object}
- */
- textRect: null,
-
- /**
- * [x, y]
- * @type {Array.}
- */
- textOffset: null,
-
- /**
- * @type {string}
- */
- textAlign: null,
-
- /**
- * @type {string}
- */
- textVerticalAlign: null,
-
- /**
- * @type {number}
- */
- textDistance: 5,
-
- /**
- * @type {string}
- */
- textShadowColor: 'transparent',
-
- /**
- * @type {number}
- */
- textShadowBlur: 0,
-
- /**
- * @type {number}
- */
- textShadowOffsetX: 0,
-
- /**
- * @type {number}
- */
- textShadowOffsetY: 0,
-
- /**
- * @type {string}
- */
- textBoxShadowColor: 'transparent',
-
- /**
- * @type {number}
- */
- textBoxShadowBlur: 0,
-
- /**
- * @type {number}
- */
- textBoxShadowOffsetX: 0,
-
- /**
- * @type {number}
- */
- textBoxShadowOffsetY: 0,
-
- /**
- * Whether transform text.
- * Only useful in Path and Image element
- * @type {boolean}
- */
- transformText: false,
-
- /**
- * Text rotate around position of Path or Image
- * Only useful in Path and Image element and transformText is false.
- */
- textRotation: 0,
-
- /**
- * Text origin of text rotation, like [10, 40].
- * Based on x, y of rect.
- * Useful in label rotation of circular symbol.
- * By default, this origin is textPosition.
- * Can be 'center'.
- * @type {string|Array.}
- */
- textOrigin: null,
-
- /**
- * @type {string}
- */
- textBackgroundColor: null,
-
- /**
- * @type {string}
- */
- textBorderColor: null,
-
- /**
- * @type {number}
- */
- textBorderWidth: 0,
-
- /**
- * @type {number}
- */
- textBorderRadius: 0,
-
- /**
- * Can be `2` or `[2, 4]` or `[2, 3, 4, 5]`
- * @type {number|Array.}
- */
- textPadding: null,
-
- /**
- * Text styles for rich text.
- * @type {Object}
- */
- rich: null,
-
- /**
- * {outerWidth, outerHeight, ellipsis, placeholder}
- * @type {Object}
- */
- truncate: null,
-
- /**
- * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
- * @type {string}
- */
- blend: null,
-
- /**
- * @param {CanvasRenderingContext2D} ctx
- */
- bind: function (ctx, el, prevEl) {
- var style = this;
- var prevStyle = prevEl && prevEl.style;
- var firstDraw = !prevStyle;
-
- for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) {
- var prop = STYLE_COMMON_PROPS[i];
- var styleName = prop[0];
-
- if (firstDraw || style[styleName] !== prevStyle[styleName]) {
- // FIXME Invalid property value will cause style leak from previous element.
- ctx[styleName] =
- fixShadow(ctx, styleName, style[styleName] || prop[1]);
- }
- }
-
- if ((firstDraw || style.fill !== prevStyle.fill)) {
- ctx.fillStyle = style.fill;
- }
- if ((firstDraw || style.stroke !== prevStyle.stroke)) {
- ctx.strokeStyle = style.stroke;
- }
- if ((firstDraw || style.opacity !== prevStyle.opacity)) {
- ctx.globalAlpha = style.opacity == null ? 1 : style.opacity;
- }
-
- if ((firstDraw || style.blend !== prevStyle.blend)) {
- ctx.globalCompositeOperation = style.blend || 'source-over';
- }
- if (this.hasStroke()) {
- var lineWidth = style.lineWidth;
- ctx.lineWidth = lineWidth / (
- (this.strokeNoScale && el && el.getLineScale) ? el.getLineScale() : 1
- );
- }
- },
-
- hasFill: function () {
- var fill = this.fill;
- return fill != null && fill !== 'none';
- },
-
- hasStroke: function () {
- var stroke = this.stroke;
- return stroke != null && stroke !== 'none' && this.lineWidth > 0;
- },
-
- /**
- * Extend from other style
- * @param {zrender/graphic/Style} otherStyle
- * @param {boolean} overwrite true: overwrirte any way.
- * false: overwrite only when !target.hasOwnProperty
- * others: overwrite when property is not null/undefined.
- */
- extendFrom: function (otherStyle, overwrite) {
- if (otherStyle) {
- for (var name in otherStyle) {
- if (otherStyle.hasOwnProperty(name)
- && (overwrite === true
- || (
- overwrite === false
- ? !this.hasOwnProperty(name)
- : otherStyle[name] != null
- )
- )
- ) {
- this[name] = otherStyle[name];
- }
- }
- }
- },
-
- /**
- * Batch setting style with a given object
- * @param {Object|string} obj
- * @param {*} [obj]
- */
- set: function (obj, value) {
- if (typeof obj === 'string') {
- this[obj] = value;
- }
- else {
- this.extendFrom(obj, true);
- }
- },
-
- /**
- * Clone
- * @return {zrender/graphic/Style} [description]
- */
- clone: function () {
- var newStyle = new this.constructor();
- newStyle.extendFrom(this, true);
- return newStyle;
- },
-
- getGradient: function (ctx, obj, rect) {
- var method = obj.type === 'radial' ? createRadialGradient : createLinearGradient;
- var canvasGradient = method(ctx, obj, rect);
- var colorStops = obj.colorStops;
- for (var i = 0; i < colorStops.length; i++) {
- canvasGradient.addColorStop(
- colorStops[i].offset, colorStops[i].color
- );
- }
- return canvasGradient;
- }
-
-};
-
-var styleProto = Style.prototype;
-for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) {
- var prop = STYLE_COMMON_PROPS[i];
- if (!(prop[0] in styleProto)) {
- styleProto[prop[0]] = prop[1];
- }
-}
-
-// Provide for others
-Style.getGradient = styleProto.getGradient;
-
-var Pattern = function (image, repeat) {
- // Should do nothing more in this constructor. Because gradient can be
- // declard by `color: {image: ...}`, where this constructor will not be called.
-
- this.image = image;
- this.repeat = repeat;
-
- // Can be cloned
- this.type = 'pattern';
-};
-
-Pattern.prototype.getCanvasPattern = function (ctx) {
- return ctx.createPattern(this.image, this.repeat || 'repeat');
-};
-
-/**
- * @module zrender/Layer
- * @author pissang(https://www.github.com/pissang)
- */
-
-function returnFalse() {
- return false;
-}
-
-/**
- * 创建dom
- *
- * @inner
- * @param {string} id dom id 待用
- * @param {Painter} painter painter instance
- * @param {number} number
- */
-function createDom(id, painter, dpr) {
- var newDom = createCanvas();
- var width = painter.getWidth();
- var height = painter.getHeight();
-
- var newDomStyle = newDom.style;
- if (newDomStyle) { // In node or some other non-browser environment
- newDomStyle.position = 'absolute';
- newDomStyle.left = 0;
- newDomStyle.top = 0;
- newDomStyle.width = width + 'px';
- newDomStyle.height = height + 'px';
-
- newDom.setAttribute('data-zr-dom-id', id);
- }
-
- newDom.width = width * dpr;
- newDom.height = height * dpr;
-
- return newDom;
-}
-
-/**
- * @alias module:zrender/Layer
- * @constructor
- * @extends module:zrender/mixin/Transformable
- * @param {string} id
- * @param {module:zrender/Painter} painter
- * @param {number} [dpr]
- */
-var Layer = function(id, painter, dpr) {
- var dom;
- dpr = dpr || devicePixelRatio;
- if (typeof id === 'string') {
- dom = createDom(id, painter, dpr);
- }
- // Not using isDom because in node it will return false
- else if (isObject$1(id)) {
- dom = id;
- id = dom.id;
- }
- this.id = id;
- this.dom = dom;
-
- var domStyle = dom.style;
- if (domStyle) { // Not in node
- dom.onselectstart = returnFalse; // 避免页面选中的尴尬
- domStyle['-webkit-user-select'] = 'none';
- domStyle['user-select'] = 'none';
- domStyle['-webkit-touch-callout'] = 'none';
- domStyle['-webkit-tap-highlight-color'] = 'rgba(0,0,0,0)';
- domStyle['padding'] = 0;
- domStyle['margin'] = 0;
- domStyle['border-width'] = 0;
- }
-
- this.domBack = null;
- this.ctxBack = null;
-
- this.painter = painter;
-
- this.config = null;
-
- // Configs
- /**
- * 每次清空画布的颜色
- * @type {string}
- * @default 0
- */
- this.clearColor = 0;
- /**
- * 是否开启动态模糊
- * @type {boolean}
- * @default false
- */
- this.motionBlur = false;
- /**
- * 在开启动态模糊的时候使用,与上一帧混合的alpha值,值越大尾迹越明显
- * @type {number}
- * @default 0.7
- */
- this.lastFrameAlpha = 0.7;
-
- /**
- * Layer dpr
- * @type {number}
- */
- this.dpr = dpr;
-};
-
-Layer.prototype = {
-
- constructor: Layer,
-
- __dirty: true,
-
- __used: false,
-
- __drawIndex: 0,
- __startIndex: 0,
- __endIndex: 0,
-
- incremental: false,
-
- getElementCount: function () {
- return this.__endIndex - this.__startIndex;
- },
-
- initContext: function () {
- this.ctx = this.dom.getContext('2d');
- this.ctx.dpr = this.dpr;
- },
-
- createBackBuffer: function () {
- var dpr = this.dpr;
-
- this.domBack = createDom('back-' + this.id, this.painter, dpr);
- this.ctxBack = this.domBack.getContext('2d');
-
- if (dpr != 1) {
- this.ctxBack.scale(dpr, dpr);
- }
- },
-
- /**
- * @param {number} width
- * @param {number} height
- */
- resize: function (width, height) {
- var dpr = this.dpr;
-
- var dom = this.dom;
- var domStyle = dom.style;
- var domBack = this.domBack;
-
- if (domStyle) {
- domStyle.width = width + 'px';
- domStyle.height = height + 'px';
- }
-
- dom.width = width * dpr;
- dom.height = height * dpr;
-
- if (domBack) {
- domBack.width = width * dpr;
- domBack.height = height * dpr;
-
- if (dpr != 1) {
- this.ctxBack.scale(dpr, dpr);
- }
- }
- },
-
- /**
- * 清空该层画布
- * @param {boolean} [clearAll]=false Clear all with out motion blur
- * @param {Color} [clearColor]
- */
- clear: function (clearAll, clearColor) {
- var dom = this.dom;
- var ctx = this.ctx;
- var width = dom.width;
- var height = dom.height;
-
- var clearColor = clearColor || this.clearColor;
- var haveMotionBLur = this.motionBlur && !clearAll;
- var lastFrameAlpha = this.lastFrameAlpha;
-
- var dpr = this.dpr;
-
- if (haveMotionBLur) {
- if (!this.domBack) {
- this.createBackBuffer();
- }
-
- this.ctxBack.globalCompositeOperation = 'copy';
- this.ctxBack.drawImage(
- dom, 0, 0,
- width / dpr,
- height / dpr
- );
- }
-
- ctx.clearRect(0, 0, width, height);
- if (clearColor && clearColor !== 'transparent') {
- var clearColorGradientOrPattern;
- // Gradient
- if (clearColor.colorStops) {
- // Cache canvas gradient
- clearColorGradientOrPattern = clearColor.__canvasGradient || Style.getGradient(ctx, clearColor, {
- x: 0,
- y: 0,
- width: width,
- height: height
- });
-
- clearColor.__canvasGradient = clearColorGradientOrPattern;
- }
- // Pattern
- else if (clearColor.image) {
- clearColorGradientOrPattern = Pattern.prototype.getCanvasPattern.call(clearColor, ctx);
- }
- ctx.save();
- ctx.fillStyle = clearColorGradientOrPattern || clearColor;
- ctx.fillRect(0, 0, width, height);
- ctx.restore();
- }
-
- if (haveMotionBLur) {
- var domBack = this.domBack;
- ctx.save();
- ctx.globalAlpha = lastFrameAlpha;
- ctx.drawImage(domBack, 0, 0, width, height);
- ctx.restore();
- }
- }
-};
-
-var requestAnimationFrame = (
- typeof window !== 'undefined'
- && (
- (window.requestAnimationFrame && window.requestAnimationFrame.bind(window))
- // https://github.com/ecomfe/zrender/issues/189#issuecomment-224919809
- || (window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window))
- || window.mozRequestAnimationFrame
- || window.webkitRequestAnimationFrame
- )
-) || function (func) {
- setTimeout(func, 16);
-};
-
-var globalImageCache = new LRU(50);
-
-/**
- * @param {string|HTMLImageElement|HTMLCanvasElement|Canvas} newImageOrSrc
- * @return {HTMLImageElement|HTMLCanvasElement|Canvas} image
- */
-function findExistImage(newImageOrSrc) {
- if (typeof newImageOrSrc === 'string') {
- var cachedImgObj = globalImageCache.get(newImageOrSrc);
- return cachedImgObj && cachedImgObj.image;
- }
- else {
- return newImageOrSrc;
- }
-}
-
-/**
- * Caution: User should cache loaded images, but not just count on LRU.
- * Consider if required images more than LRU size, will dead loop occur?
- *
- * @param {string|HTMLImageElement|HTMLCanvasElement|Canvas} newImageOrSrc
- * @param {HTMLImageElement|HTMLCanvasElement|Canvas} image Existent image.
- * @param {module:zrender/Element} [hostEl] For calling `dirty`.
- * @param {Function} [cb] params: (image, cbPayload)
- * @param {Object} [cbPayload] Payload on cb calling.
- * @return {HTMLImageElement|HTMLCanvasElement|Canvas} image
- */
-function createOrUpdateImage(newImageOrSrc, image, hostEl, cb, cbPayload) {
- if (!newImageOrSrc) {
- return image;
- }
- else if (typeof newImageOrSrc === 'string') {
-
- // Image should not be loaded repeatly.
- if ((image && image.__zrImageSrc === newImageOrSrc) || !hostEl) {
- return image;
- }
-
- // Only when there is no existent image or existent image src
- // is different, this method is responsible for load.
- var cachedImgObj = globalImageCache.get(newImageOrSrc);
-
- var pendingWrap = {hostEl: hostEl, cb: cb, cbPayload: cbPayload};
-
- if (cachedImgObj) {
- image = cachedImgObj.image;
- !isImageReady(image) && cachedImgObj.pending.push(pendingWrap);
- }
- else {
- !image && (image = new Image());
- image.onload = imageOnLoad;
-
- globalImageCache.put(
- newImageOrSrc,
- image.__cachedImgObj = {
- image: image,
- pending: [pendingWrap]
- }
- );
-
- image.src = image.__zrImageSrc = newImageOrSrc;
- }
-
- return image;
- }
- // newImageOrSrc is an HTMLImageElement or HTMLCanvasElement or Canvas
- else {
- return newImageOrSrc;
- }
-}
-
-function imageOnLoad() {
- var cachedImgObj = this.__cachedImgObj;
- this.onload = this.__cachedImgObj = null;
-
- for (var i = 0; i < cachedImgObj.pending.length; i++) {
- var pendingWrap = cachedImgObj.pending[i];
- var cb = pendingWrap.cb;
- cb && cb(this, pendingWrap.cbPayload);
- pendingWrap.hostEl.dirty();
- }
- cachedImgObj.pending.length = 0;
-}
-
-function isImageReady(image) {
- return image && image.width && image.height;
-}
-
-var textWidthCache = {};
-var textWidthCacheCounter = 0;
-
-var TEXT_CACHE_MAX = 5000;
-var STYLE_REG = /\{([a-zA-Z0-9_]+)\|([^}]*)\}/g;
-
-var DEFAULT_FONT = '12px sans-serif';
-
-// Avoid assign to an exported variable, for transforming to cjs.
-var methods$1 = {};
-
-function $override$1(name, fn) {
- methods$1[name] = fn;
-}
-
-/**
- * @public
- * @param {string} text
- * @param {string} font
- * @return {number} width
- */
-function getWidth(text, font) {
- font = font || DEFAULT_FONT;
- var key = text + ':' + font;
- if (textWidthCache[key]) {
- return textWidthCache[key];
- }
-
- var textLines = (text + '').split('\n');
- var width = 0;
-
- for (var i = 0, l = textLines.length; i < l; i++) {
- // textContain.measureText may be overrided in SVG or VML
- width = Math.max(measureText(textLines[i], font).width, width);
- }
-
- if (textWidthCacheCounter > TEXT_CACHE_MAX) {
- textWidthCacheCounter = 0;
- textWidthCache = {};
- }
- textWidthCacheCounter++;
- textWidthCache[key] = width;
-
- return width;
-}
-
-/**
- * @public
- * @param {string} text
- * @param {string} font
- * @param {string} [textAlign='left']
- * @param {string} [textVerticalAlign='top']
- * @param {Array.} [textPadding]
- * @param {Object} [rich]
- * @param {Object} [truncate]
- * @return {Object} {x, y, width, height, lineHeight}
- */
-function getBoundingRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) {
- return rich
- ? getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate)
- : getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, truncate);
-}
-
-function getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, truncate) {
- var contentBlock = parsePlainText(text, font, textPadding, truncate);
- var outerWidth = getWidth(text, font);
- if (textPadding) {
- outerWidth += textPadding[1] + textPadding[3];
- }
- var outerHeight = contentBlock.outerHeight;
-
- var x = adjustTextX(0, outerWidth, textAlign);
- var y = adjustTextY(0, outerHeight, textVerticalAlign);
-
- var rect = new BoundingRect(x, y, outerWidth, outerHeight);
- rect.lineHeight = contentBlock.lineHeight;
-
- return rect;
-}
-
-function getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) {
- var contentBlock = parseRichText(text, {
- rich: rich,
- truncate: truncate,
- font: font,
- textAlign: textAlign,
- textPadding: textPadding
- });
- var outerWidth = contentBlock.outerWidth;
- var outerHeight = contentBlock.outerHeight;
-
- var x = adjustTextX(0, outerWidth, textAlign);
- var y = adjustTextY(0, outerHeight, textVerticalAlign);
-
- return new BoundingRect(x, y, outerWidth, outerHeight);
-}
-
-/**
- * @public
- * @param {number} x
- * @param {number} width
- * @param {string} [textAlign='left']
- * @return {number} Adjusted x.
- */
-function adjustTextX(x, width, textAlign) {
- // FIXME Right to left language
- if (textAlign === 'right') {
- x -= width;
- }
- else if (textAlign === 'center') {
- x -= width / 2;
- }
- return x;
-}
-
-/**
- * @public
- * @param {number} y
- * @param {number} height
- * @param {string} [textVerticalAlign='top']
- * @return {number} Adjusted y.
- */
-function adjustTextY(y, height, textVerticalAlign) {
- if (textVerticalAlign === 'middle') {
- y -= height / 2;
- }
- else if (textVerticalAlign === 'bottom') {
- y -= height;
- }
- return y;
-}
-
-/**
- * @public
- * @param {stirng} textPosition
- * @param {Object} rect {x, y, width, height}
- * @param {number} distance
- * @return {Object} {x, y, textAlign, textVerticalAlign}
- */
-function adjustTextPositionOnRect(textPosition, rect, distance) {
-
- var x = rect.x;
- var y = rect.y;
-
- var height = rect.height;
- var width = rect.width;
- var halfHeight = height / 2;
-
- var textAlign = 'left';
- var textVerticalAlign = 'top';
-
- switch (textPosition) {
- case 'left':
- x -= distance;
- y += halfHeight;
- textAlign = 'right';
- textVerticalAlign = 'middle';
- break;
- case 'right':
- x += distance + width;
- y += halfHeight;
- textVerticalAlign = 'middle';
- break;
- case 'top':
- x += width / 2;
- y -= distance;
- textAlign = 'center';
- textVerticalAlign = 'bottom';
- break;
- case 'bottom':
- x += width / 2;
- y += height + distance;
- textAlign = 'center';
- break;
- case 'inside':
- x += width / 2;
- y += halfHeight;
- textAlign = 'center';
- textVerticalAlign = 'middle';
- break;
- case 'insideLeft':
- x += distance;
- y += halfHeight;
- textVerticalAlign = 'middle';
- break;
- case 'insideRight':
- x += width - distance;
- y += halfHeight;
- textAlign = 'right';
- textVerticalAlign = 'middle';
- break;
- case 'insideTop':
- x += width / 2;
- y += distance;
- textAlign = 'center';
- break;
- case 'insideBottom':
- x += width / 2;
- y += height - distance;
- textAlign = 'center';
- textVerticalAlign = 'bottom';
- break;
- case 'insideTopLeft':
- x += distance;
- y += distance;
- break;
- case 'insideTopRight':
- x += width - distance;
- y += distance;
- textAlign = 'right';
- break;
- case 'insideBottomLeft':
- x += distance;
- y += height - distance;
- textVerticalAlign = 'bottom';
- break;
- case 'insideBottomRight':
- x += width - distance;
- y += height - distance;
- textAlign = 'right';
- textVerticalAlign = 'bottom';
- break;
- }
-
- return {
- x: x,
- y: y,
- textAlign: textAlign,
- textVerticalAlign: textVerticalAlign
- };
-}
-
-/**
- * Show ellipsis if overflow.
- *
- * @public
- * @param {string} text
- * @param {string} containerWidth
- * @param {string} font
- * @param {number} [ellipsis='...']
- * @param {Object} [options]
- * @param {number} [options.maxIterations=3]
- * @param {number} [options.minChar=0] If truncate result are less
- * then minChar, ellipsis will not show, which is
- * better for user hint in some cases.
- * @param {number} [options.placeholder=''] When all truncated, use the placeholder.
- * @return {string}
- */
-function truncateText(text, containerWidth, font, ellipsis, options) {
- if (!containerWidth) {
- return '';
- }
-
- var textLines = (text + '').split('\n');
- options = prepareTruncateOptions(containerWidth, font, ellipsis, options);
-
- // FIXME
- // It is not appropriate that every line has '...' when truncate multiple lines.
- for (var i = 0, len = textLines.length; i < len; i++) {
- textLines[i] = truncateSingleLine(textLines[i], options);
- }
-
- return textLines.join('\n');
-}
-
-function prepareTruncateOptions(containerWidth, font, ellipsis, options) {
- options = extend({}, options);
-
- options.font = font;
- var ellipsis = retrieve2(ellipsis, '...');
- options.maxIterations = retrieve2(options.maxIterations, 2);
- var minChar = options.minChar = retrieve2(options.minChar, 0);
- // FIXME
- // Other languages?
- options.cnCharWidth = getWidth('国', font);
- // FIXME
- // Consider proportional font?
- var ascCharWidth = options.ascCharWidth = getWidth('a', font);
- options.placeholder = retrieve2(options.placeholder, '');
-
- // Example 1: minChar: 3, text: 'asdfzxcv', truncate result: 'asdf', but not: 'a...'.
- // Example 2: minChar: 3, text: '维度', truncate result: '维', but not: '...'.
- var contentWidth = containerWidth = Math.max(0, containerWidth - 1); // Reserve some gap.
- for (var i = 0; i < minChar && contentWidth >= ascCharWidth; i++) {
- contentWidth -= ascCharWidth;
- }
-
- var ellipsisWidth = getWidth(ellipsis);
- if (ellipsisWidth > contentWidth) {
- ellipsis = '';
- ellipsisWidth = 0;
- }
-
- contentWidth = containerWidth - ellipsisWidth;
-
- options.ellipsis = ellipsis;
- options.ellipsisWidth = ellipsisWidth;
- options.contentWidth = contentWidth;
- options.containerWidth = containerWidth;
-
- return options;
-}
-
-function truncateSingleLine(textLine, options) {
- var containerWidth = options.containerWidth;
- var font = options.font;
- var contentWidth = options.contentWidth;
-
- if (!containerWidth) {
- return '';
- }
-
- var lineWidth = getWidth(textLine, font);
-
- if (lineWidth <= containerWidth) {
- return textLine;
- }
-
- for (var j = 0;; j++) {
- if (lineWidth <= contentWidth || j >= options.maxIterations) {
- textLine += options.ellipsis;
- break;
- }
-
- var subLength = j === 0
- ? estimateLength(textLine, contentWidth, options.ascCharWidth, options.cnCharWidth)
- : lineWidth > 0
- ? Math.floor(textLine.length * contentWidth / lineWidth)
- : 0;
-
- textLine = textLine.substr(0, subLength);
- lineWidth = getWidth(textLine, font);
- }
-
- if (textLine === '') {
- textLine = options.placeholder;
- }
-
- return textLine;
-}
-
-function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) {
- var width = 0;
- var i = 0;
- for (var len = text.length; i < len && width < contentWidth; i++) {
- var charCode = text.charCodeAt(i);
- width += (0 <= charCode && charCode <= 127) ? ascCharWidth : cnCharWidth;
- }
- return i;
-}
-
-/**
- * @public
- * @param {string} font
- * @return {number} line height
- */
-function getLineHeight(font) {
- // FIXME A rough approach.
- return getWidth('国', font);
-}
-
-/**
- * @public
- * @param {string} text
- * @param {string} font
- * @return {Object} width
- */
-function measureText(text, font) {
- return methods$1.measureText(text, font);
-}
-
-// Avoid assign to an exported variable, for transforming to cjs.
-methods$1.measureText = function (text, font) {
- var ctx = getContext();
- ctx.font = font || DEFAULT_FONT;
- return ctx.measureText(text);
-};
-
-/**
- * @public
- * @param {string} text
- * @param {string} font
- * @param {Object} [truncate]
- * @return {Object} block: {lineHeight, lines, height, outerHeight}
- * Notice: for performance, do not calculate outerWidth util needed.
- */
-function parsePlainText(text, font, padding, truncate) {
- text != null && (text += '');
-
- var lineHeight = getLineHeight(font);
- var lines = text ? text.split('\n') : [];
- var height = lines.length * lineHeight;
- var outerHeight = height;
-
- if (padding) {
- outerHeight += padding[0] + padding[2];
- }
-
- if (text && truncate) {
- var truncOuterHeight = truncate.outerHeight;
- var truncOuterWidth = truncate.outerWidth;
- if (truncOuterHeight != null && outerHeight > truncOuterHeight) {
- text = '';
- lines = [];
- }
- else if (truncOuterWidth != null) {
- var options = prepareTruncateOptions(
- truncOuterWidth - (padding ? padding[1] + padding[3] : 0),
- font,
- truncate.ellipsis,
- {minChar: truncate.minChar, placeholder: truncate.placeholder}
- );
-
- // FIXME
- // It is not appropriate that every line has '...' when truncate multiple lines.
- for (var i = 0, len = lines.length; i < len; i++) {
- lines[i] = truncateSingleLine(lines[i], options);
- }
- }
- }
-
- return {
- lines: lines,
- height: height,
- outerHeight: outerHeight,
- lineHeight: lineHeight
- };
-}
-
-/**
- * For example: 'some text {a|some text}other text{b|some text}xxx{c|}xxx'
- * Also consider 'bbbb{a|xxx\nzzz}xxxx\naaaa'.
- *
- * @public
- * @param {string} text
- * @param {Object} style
- * @return {Object} block
- * {
- * width,
- * height,
- * lines: [{
- * lineHeight,
- * width,
- * tokens: [[{
- * styleName,
- * text,
- * width, // include textPadding
- * height, // include textPadding
- * textWidth, // pure text width
- * textHeight, // pure text height
- * lineHeihgt,
- * font,
- * textAlign,
- * textVerticalAlign
- * }], [...], ...]
- * }, ...]
- * }
- * If styleName is undefined, it is plain text.
- */
-function parseRichText(text, style) {
- var contentBlock = {lines: [], width: 0, height: 0};
-
- text != null && (text += '');
- if (!text) {
- return contentBlock;
- }
-
- var lastIndex = STYLE_REG.lastIndex = 0;
- var result;
- while ((result = STYLE_REG.exec(text)) != null) {
- var matchedIndex = result.index;
- if (matchedIndex > lastIndex) {
- pushTokens(contentBlock, text.substring(lastIndex, matchedIndex));
- }
- pushTokens(contentBlock, result[2], result[1]);
- lastIndex = STYLE_REG.lastIndex;
- }
-
- if (lastIndex < text.length) {
- pushTokens(contentBlock, text.substring(lastIndex, text.length));
- }
-
- var lines = contentBlock.lines;
- var contentHeight = 0;
- var contentWidth = 0;
- // For `textWidth: 100%`
- var pendingList = [];
-
- var stlPadding = style.textPadding;
-
- var truncate = style.truncate;
- var truncateWidth = truncate && truncate.outerWidth;
- var truncateHeight = truncate && truncate.outerHeight;
- if (stlPadding) {
- truncateWidth != null && (truncateWidth -= stlPadding[1] + stlPadding[3]);
- truncateHeight != null && (truncateHeight -= stlPadding[0] + stlPadding[2]);
- }
-
- // Calculate layout info of tokens.
- for (var i = 0; i < lines.length; i++) {
- var line = lines[i];
- var lineHeight = 0;
- var lineWidth = 0;
-
- for (var j = 0; j < line.tokens.length; j++) {
- var token = line.tokens[j];
- var tokenStyle = token.styleName && style.rich[token.styleName] || {};
- // textPadding should not inherit from style.
- var textPadding = token.textPadding = tokenStyle.textPadding;
-
- // textFont has been asigned to font by `normalizeStyle`.
- var font = token.font = tokenStyle.font || style.font;
-
- // textHeight can be used when textVerticalAlign is specified in token.
- var tokenHeight = token.textHeight = retrieve2(
- // textHeight should not be inherited, consider it can be specified
- // as box height of the block.
- tokenStyle.textHeight, getLineHeight(font)
- );
- textPadding && (tokenHeight += textPadding[0] + textPadding[2]);
- token.height = tokenHeight;
- token.lineHeight = retrieve3(
- tokenStyle.textLineHeight, style.textLineHeight, tokenHeight
- );
-
- token.textAlign = tokenStyle && tokenStyle.textAlign || style.textAlign;
- token.textVerticalAlign = tokenStyle && tokenStyle.textVerticalAlign || 'middle';
-
- if (truncateHeight != null && contentHeight + token.lineHeight > truncateHeight) {
- return {lines: [], width: 0, height: 0};
- }
-
- token.textWidth = getWidth(token.text, font);
- var tokenWidth = tokenStyle.textWidth;
- var tokenWidthNotSpecified = tokenWidth == null || tokenWidth === 'auto';
-
- // Percent width, can be `100%`, can be used in drawing separate
- // line when box width is needed to be auto.
- if (typeof tokenWidth === 'string' && tokenWidth.charAt(tokenWidth.length - 1) === '%') {
- token.percentWidth = tokenWidth;
- pendingList.push(token);
- tokenWidth = 0;
- // Do not truncate in this case, because there is no user case
- // and it is too complicated.
- }
- else {
- if (tokenWidthNotSpecified) {
- tokenWidth = token.textWidth;
-
- // FIXME: If image is not loaded and textWidth is not specified, calling
- // `getBoundingRect()` will not get correct result.
- var textBackgroundColor = tokenStyle.textBackgroundColor;
- var bgImg = textBackgroundColor && textBackgroundColor.image;
-
- // Use cases:
- // (1) If image is not loaded, it will be loaded at render phase and call
- // `dirty()` and `textBackgroundColor.image` will be replaced with the loaded
- // image, and then the right size will be calculated here at the next tick.
- // See `graphic/helper/text.js`.
- // (2) If image loaded, and `textBackgroundColor.image` is image src string,
- // use `imageHelper.findExistImage` to find cached image.
- // `imageHelper.findExistImage` will always be called here before
- // `imageHelper.createOrUpdateImage` in `graphic/helper/text.js#renderRichText`
- // which ensures that image will not be rendered before correct size calcualted.
- if (bgImg) {
- bgImg = findExistImage(bgImg);
- if (isImageReady(bgImg)) {
- tokenWidth = Math.max(tokenWidth, bgImg.width * tokenHeight / bgImg.height);
- }
- }
- }
-
- var paddingW = textPadding ? textPadding[1] + textPadding[3] : 0;
- tokenWidth += paddingW;
-
- var remianTruncWidth = truncateWidth != null ? truncateWidth - lineWidth : null;
-
- if (remianTruncWidth != null && remianTruncWidth < tokenWidth) {
- if (!tokenWidthNotSpecified || remianTruncWidth < paddingW) {
- token.text = '';
- token.textWidth = tokenWidth = 0;
- }
- else {
- token.text = truncateText(
- token.text, remianTruncWidth - paddingW, font, truncate.ellipsis,
- {minChar: truncate.minChar}
- );
- token.textWidth = getWidth(token.text, font);
- tokenWidth = token.textWidth + paddingW;
- }
- }
- }
-
- lineWidth += (token.width = tokenWidth);
- tokenStyle && (lineHeight = Math.max(lineHeight, token.lineHeight));
- }
-
- line.width = lineWidth;
- line.lineHeight = lineHeight;
- contentHeight += lineHeight;
- contentWidth = Math.max(contentWidth, lineWidth);
- }
-
- contentBlock.outerWidth = contentBlock.width = retrieve2(style.textWidth, contentWidth);
- contentBlock.outerHeight = contentBlock.height = retrieve2(style.textHeight, contentHeight);
-
- if (stlPadding) {
- contentBlock.outerWidth += stlPadding[1] + stlPadding[3];
- contentBlock.outerHeight += stlPadding[0] + stlPadding[2];
- }
-
- for (var i = 0; i < pendingList.length; i++) {
- var token = pendingList[i];
- var percentWidth = token.percentWidth;
- // Should not base on outerWidth, because token can not be placed out of padding.
- token.width = parseInt(percentWidth, 10) / 100 * contentWidth;
- }
-
- return contentBlock;
-}
-
-function pushTokens(block, str, styleName) {
- var isEmptyStr = str === '';
- var strs = str.split('\n');
- var lines = block.lines;
-
- for (var i = 0; i < strs.length; i++) {
- var text = strs[i];
- var token = {
- styleName: styleName,
- text: text,
- isLineHolder: !text && !isEmptyStr
- };
-
- // The first token should be appended to the last line.
- if (!i) {
- var tokens = (lines[lines.length - 1] || (lines[0] = {tokens: []})).tokens;
-
- // Consider cases:
- // (1) ''.split('\n') => ['', '\n', ''], the '' at the first item
- // (which is a placeholder) should be replaced by new token.
- // (2) A image backage, where token likes {a|}.
- // (3) A redundant '' will affect textAlign in line.
- // (4) tokens with the same tplName should not be merged, because
- // they should be displayed in different box (with border and padding).
- var tokensLen = tokens.length;
- (tokensLen === 1 && tokens[0].isLineHolder)
- ? (tokens[0] = token)
- // Consider text is '', only insert when it is the "lineHolder" or
- // "emptyStr". Otherwise a redundant '' will affect textAlign in line.
- : ((text || !tokensLen || isEmptyStr) && tokens.push(token));
- }
- // Other tokens always start a new line.
- else {
- // If there is '', insert it as a placeholder.
- lines.push({tokens: [token]});
- }
- }
-}
-
-function makeFont(style) {
- // FIXME in node-canvas fontWeight is before fontStyle
- // Use `fontSize` `fontFamily` to check whether font properties are defined.
- var font = (style.fontSize || style.fontFamily) && [
- style.fontStyle,
- style.fontWeight,
- (style.fontSize || 12) + 'px',
- // If font properties are defined, `fontFamily` should not be ignored.
- style.fontFamily || 'sans-serif'
- ].join(' ');
- return font && trim(font) || style.textFont || style.font;
-}
-
-function buildPath(ctx, shape) {
- var x = shape.x;
- var y = shape.y;
- var width = shape.width;
- var height = shape.height;
- var r = shape.r;
- var r1;
- var r2;
- var r3;
- var r4;
-
- // Convert width and height to positive for better borderRadius
- if (width < 0) {
- x = x + width;
- width = -width;
- }
- if (height < 0) {
- y = y + height;
- height = -height;
- }
-
- if (typeof r === 'number') {
- r1 = r2 = r3 = r4 = r;
- }
- else if (r instanceof Array) {
- if (r.length === 1) {
- r1 = r2 = r3 = r4 = r[0];
- }
- else if (r.length === 2) {
- r1 = r3 = r[0];
- r2 = r4 = r[1];
- }
- else if (r.length === 3) {
- r1 = r[0];
- r2 = r4 = r[1];
- r3 = r[2];
- }
- else {
- r1 = r[0];
- r2 = r[1];
- r3 = r[2];
- r4 = r[3];
- }
- }
- else {
- r1 = r2 = r3 = r4 = 0;
- }
-
- var total;
- if (r1 + r2 > width) {
- total = r1 + r2;
- r1 *= width / total;
- r2 *= width / total;
- }
- if (r3 + r4 > width) {
- total = r3 + r4;
- r3 *= width / total;
- r4 *= width / total;
- }
- if (r2 + r3 > height) {
- total = r2 + r3;
- r2 *= height / total;
- r3 *= height / total;
- }
- if (r1 + r4 > height) {
- total = r1 + r4;
- r1 *= height / total;
- r4 *= height / total;
- }
- ctx.moveTo(x + r1, y);
- ctx.lineTo(x + width - r2, y);
- r2 !== 0 && ctx.arc(x + width - r2, y + r2, r2, -Math.PI / 2, 0);
- ctx.lineTo(x + width, y + height - r3);
- r3 !== 0 && ctx.arc(x + width - r3, y + height - r3, r3, 0, Math.PI / 2);
- ctx.lineTo(x + r4, y + height);
- r4 !== 0 && ctx.arc(x + r4, y + height - r4, r4, Math.PI / 2, Math.PI);
- ctx.lineTo(x, y + r1);
- r1 !== 0 && ctx.arc(x + r1, y + r1, r1, Math.PI, Math.PI * 1.5);
-}
-
-// TODO: Have not support 'start', 'end' yet.
-var VALID_TEXT_ALIGN = {left: 1, right: 1, center: 1};
-var VALID_TEXT_VERTICAL_ALIGN = {top: 1, bottom: 1, middle: 1};
-
-/**
- * @param {module:zrender/graphic/Style} style
- * @return {module:zrender/graphic/Style} The input style.
- */
-function normalizeTextStyle(style) {
- normalizeStyle(style);
- each$1(style.rich, normalizeStyle);
- return style;
-}
-
-function normalizeStyle(style) {
- if (style) {
-
- style.font = makeFont(style);
-
- var textAlign = style.textAlign;
- textAlign === 'middle' && (textAlign = 'center');
- style.textAlign = (
- textAlign == null || VALID_TEXT_ALIGN[textAlign]
- ) ? textAlign : 'left';
-
- // Compatible with textBaseline.
- var textVerticalAlign = style.textVerticalAlign || style.textBaseline;
- textVerticalAlign === 'center' && (textVerticalAlign = 'middle');
- style.textVerticalAlign = (
- textVerticalAlign == null || VALID_TEXT_VERTICAL_ALIGN[textVerticalAlign]
- ) ? textVerticalAlign : 'top';
-
- var textPadding = style.textPadding;
- if (textPadding) {
- style.textPadding = normalizeCssArray(style.textPadding);
- }
- }
-}
-
-/**
- * @param {CanvasRenderingContext2D} ctx
- * @param {string} text
- * @param {module:zrender/graphic/Style} style
- * @param {Object|boolean} [rect] {x, y, width, height}
- * If set false, rect text is not used.
- */
-function renderText(hostEl, ctx, text, style, rect) {
- style.rich
- ? renderRichText(hostEl, ctx, text, style, rect)
- : renderPlainText(hostEl, ctx, text, style, rect);
-}
-
-function renderPlainText(hostEl, ctx, text, style, rect) {
- var font = setCtx(ctx, 'font', style.font || DEFAULT_FONT);
-
- var textPadding = style.textPadding;
-
- var contentBlock = hostEl.__textCotentBlock;
- if (!contentBlock || hostEl.__dirty) {
- contentBlock = hostEl.__textCotentBlock = parsePlainText(
- text, font, textPadding, style.truncate
- );
- }
-
- var outerHeight = contentBlock.outerHeight;
-
- var textLines = contentBlock.lines;
- var lineHeight = contentBlock.lineHeight;
-
- var boxPos = getBoxPosition(outerHeight, style, rect);
- var baseX = boxPos.baseX;
- var baseY = boxPos.baseY;
- var textAlign = boxPos.textAlign;
- var textVerticalAlign = boxPos.textVerticalAlign;
-
- // Origin of textRotation should be the base point of text drawing.
- applyTextRotation(ctx, style, rect, baseX, baseY);
-
- var boxY = adjustTextY(baseY, outerHeight, textVerticalAlign);
- var textX = baseX;
- var textY = boxY;
-
- var needDrawBg = needDrawBackground(style);
- if (needDrawBg || textPadding) {
- // Consider performance, do not call getTextWidth util necessary.
- var textWidth = getWidth(text, font);
- var outerWidth = textWidth;
- textPadding && (outerWidth += textPadding[1] + textPadding[3]);
- var boxX = adjustTextX(baseX, outerWidth, textAlign);
-
- needDrawBg && drawBackground(hostEl, ctx, style, boxX, boxY, outerWidth, outerHeight);
-
- if (textPadding) {
- textX = getTextXForPadding(baseX, textAlign, textPadding);
- textY += textPadding[0];
- }
- }
-
- setCtx(ctx, 'textAlign', textAlign || 'left');
- // Force baseline to be "middle". Otherwise, if using "top", the
- // text will offset downward a little bit in font "Microsoft YaHei".
- setCtx(ctx, 'textBaseline', 'middle');
-
- // Always set shadowBlur and shadowOffset to avoid leak from displayable.
- setCtx(ctx, 'shadowBlur', style.textShadowBlur || 0);
- setCtx(ctx, 'shadowColor', style.textShadowColor || 'transparent');
- setCtx(ctx, 'shadowOffsetX', style.textShadowOffsetX || 0);
- setCtx(ctx, 'shadowOffsetY', style.textShadowOffsetY || 0);
-
- // `textBaseline` is set as 'middle'.
- textY += lineHeight / 2;
-
- var textStrokeWidth = style.textStrokeWidth;
- var textStroke = getStroke(style.textStroke, textStrokeWidth);
- var textFill = getFill(style.textFill);
-
- if (textStroke) {
- setCtx(ctx, 'lineWidth', textStrokeWidth);
- setCtx(ctx, 'strokeStyle', textStroke);
- }
- if (textFill) {
- setCtx(ctx, 'fillStyle', textFill);
- }
-
- for (var i = 0; i < textLines.length; i++) {
- // Fill after stroke so the outline will not cover the main part.
- textStroke && ctx.strokeText(textLines[i], textX, textY);
- textFill && ctx.fillText(textLines[i], textX, textY);
- textY += lineHeight;
- }
-}
-
-function renderRichText(hostEl, ctx, text, style, rect) {
- var contentBlock = hostEl.__textCotentBlock;
-
- if (!contentBlock || hostEl.__dirty) {
- contentBlock = hostEl.__textCotentBlock = parseRichText(text, style);
- }
-
- drawRichText(hostEl, ctx, contentBlock, style, rect);
-}
-
-function drawRichText(hostEl, ctx, contentBlock, style, rect) {
- var contentWidth = contentBlock.width;
- var outerWidth = contentBlock.outerWidth;
- var outerHeight = contentBlock.outerHeight;
- var textPadding = style.textPadding;
-
- var boxPos = getBoxPosition(outerHeight, style, rect);
- var baseX = boxPos.baseX;
- var baseY = boxPos.baseY;
- var textAlign = boxPos.textAlign;
- var textVerticalAlign = boxPos.textVerticalAlign;
-
- // Origin of textRotation should be the base point of text drawing.
- applyTextRotation(ctx, style, rect, baseX, baseY);
-
- var boxX = adjustTextX(baseX, outerWidth, textAlign);
- var boxY = adjustTextY(baseY, outerHeight, textVerticalAlign);
- var xLeft = boxX;
- var lineTop = boxY;
- if (textPadding) {
- xLeft += textPadding[3];
- lineTop += textPadding[0];
- }
- var xRight = xLeft + contentWidth;
-
- needDrawBackground(style) && drawBackground(
- hostEl, ctx, style, boxX, boxY, outerWidth, outerHeight
- );
-
- for (var i = 0; i < contentBlock.lines.length; i++) {
- var line = contentBlock.lines[i];
- var tokens = line.tokens;
- var tokenCount = tokens.length;
- var lineHeight = line.lineHeight;
- var usedWidth = line.width;
-
- var leftIndex = 0;
- var lineXLeft = xLeft;
- var lineXRight = xRight;
- var rightIndex = tokenCount - 1;
- var token;
-
- while (
- leftIndex < tokenCount
- && (token = tokens[leftIndex], !token.textAlign || token.textAlign === 'left')
- ) {
- placeToken(hostEl, ctx, token, style, lineHeight, lineTop, lineXLeft, 'left');
- usedWidth -= token.width;
- lineXLeft += token.width;
- leftIndex++;
- }
-
- while (
- rightIndex >= 0
- && (token = tokens[rightIndex], token.textAlign === 'right')
- ) {
- placeToken(hostEl, ctx, token, style, lineHeight, lineTop, lineXRight, 'right');
- usedWidth -= token.width;
- lineXRight -= token.width;
- rightIndex--;
- }
-
- // The other tokens are placed as textAlign 'center' if there is enough space.
- lineXLeft += (contentWidth - (lineXLeft - xLeft) - (xRight - lineXRight) - usedWidth) / 2;
- while (leftIndex <= rightIndex) {
- token = tokens[leftIndex];
- // Consider width specified by user, use 'center' rather than 'left'.
- placeToken(hostEl, ctx, token, style, lineHeight, lineTop, lineXLeft + token.width / 2, 'center');
- lineXLeft += token.width;
- leftIndex++;
- }
-
- lineTop += lineHeight;
- }
-}
-
-function applyTextRotation(ctx, style, rect, x, y) {
- // textRotation only apply in RectText.
- if (rect && style.textRotation) {
- var origin = style.textOrigin;
- if (origin === 'center') {
- x = rect.width / 2 + rect.x;
- y = rect.height / 2 + rect.y;
- }
- else if (origin) {
- x = origin[0] + rect.x;
- y = origin[1] + rect.y;
- }
-
- ctx.translate(x, y);
- // Positive: anticlockwise
- ctx.rotate(-style.textRotation);
- ctx.translate(-x, -y);
- }
-}
-
-function placeToken(hostEl, ctx, token, style, lineHeight, lineTop, x, textAlign) {
- var tokenStyle = style.rich[token.styleName] || {};
-
- // 'ctx.textBaseline' is always set as 'middle', for sake of
- // the bias of "Microsoft YaHei".
- var textVerticalAlign = token.textVerticalAlign;
- var y = lineTop + lineHeight / 2;
- if (textVerticalAlign === 'top') {
- y = lineTop + token.height / 2;
- }
- else if (textVerticalAlign === 'bottom') {
- y = lineTop + lineHeight - token.height / 2;
- }
-
- !token.isLineHolder && needDrawBackground(tokenStyle) && drawBackground(
- hostEl,
- ctx,
- tokenStyle,
- textAlign === 'right'
- ? x - token.width
- : textAlign === 'center'
- ? x - token.width / 2
- : x,
- y - token.height / 2,
- token.width,
- token.height
- );
-
- var textPadding = token.textPadding;
- if (textPadding) {
- x = getTextXForPadding(x, textAlign, textPadding);
- y -= token.height / 2 - textPadding[2] - token.textHeight / 2;
- }
-
- setCtx(ctx, 'shadowBlur', retrieve3(tokenStyle.textShadowBlur, style.textShadowBlur, 0));
- setCtx(ctx, 'shadowColor', tokenStyle.textShadowColor || style.textShadowColor || 'transparent');
- setCtx(ctx, 'shadowOffsetX', retrieve3(tokenStyle.textShadowOffsetX, style.textShadowOffsetX, 0));
- setCtx(ctx, 'shadowOffsetY', retrieve3(tokenStyle.textShadowOffsetY, style.textShadowOffsetY, 0));
-
- setCtx(ctx, 'textAlign', textAlign);
- // Force baseline to be "middle". Otherwise, if using "top", the
- // text will offset downward a little bit in font "Microsoft YaHei".
- setCtx(ctx, 'textBaseline', 'middle');
-
- setCtx(ctx, 'font', token.font || DEFAULT_FONT);
-
- var textStroke = getStroke(tokenStyle.textStroke || style.textStroke, textStrokeWidth);
- var textFill = getFill(tokenStyle.textFill || style.textFill);
- var textStrokeWidth = retrieve2(tokenStyle.textStrokeWidth, style.textStrokeWidth);
-
- // Fill after stroke so the outline will not cover the main part.
- if (textStroke) {
- setCtx(ctx, 'lineWidth', textStrokeWidth);
- setCtx(ctx, 'strokeStyle', textStroke);
- ctx.strokeText(token.text, x, y);
- }
- if (textFill) {
- setCtx(ctx, 'fillStyle', textFill);
- ctx.fillText(token.text, x, y);
- }
-}
-
-function needDrawBackground(style) {
- return style.textBackgroundColor
- || (style.textBorderWidth && style.textBorderColor);
-}
-
-// style: {textBackgroundColor, textBorderWidth, textBorderColor, textBorderRadius}
-// shape: {x, y, width, height}
-function drawBackground(hostEl, ctx, style, x, y, width, height) {
- var textBackgroundColor = style.textBackgroundColor;
- var textBorderWidth = style.textBorderWidth;
- var textBorderColor = style.textBorderColor;
- var isPlainBg = isString(textBackgroundColor);
-
- setCtx(ctx, 'shadowBlur', style.textBoxShadowBlur || 0);
- setCtx(ctx, 'shadowColor', style.textBoxShadowColor || 'transparent');
- setCtx(ctx, 'shadowOffsetX', style.textBoxShadowOffsetX || 0);
- setCtx(ctx, 'shadowOffsetY', style.textBoxShadowOffsetY || 0);
-
- if (isPlainBg || (textBorderWidth && textBorderColor)) {
- ctx.beginPath();
- var textBorderRadius = style.textBorderRadius;
- if (!textBorderRadius) {
- ctx.rect(x, y, width, height);
- }
- else {
- buildPath(ctx, {
- x: x, y: y, width: width, height: height, r: textBorderRadius
- });
- }
- ctx.closePath();
- }
-
- if (isPlainBg) {
- setCtx(ctx, 'fillStyle', textBackgroundColor);
- ctx.fill();
- }
- else if (isObject$1(textBackgroundColor)) {
- var image = textBackgroundColor.image;
-
- image = createOrUpdateImage(
- image, null, hostEl, onBgImageLoaded, textBackgroundColor
- );
- if (image && isImageReady(image)) {
- ctx.drawImage(image, x, y, width, height);
- }
- }
-
- if (textBorderWidth && textBorderColor) {
- setCtx(ctx, 'lineWidth', textBorderWidth);
- setCtx(ctx, 'strokeStyle', textBorderColor);
- ctx.stroke();
- }
-}
-
-function onBgImageLoaded(image, textBackgroundColor) {
- // Replace image, so that `contain/text.js#parseRichText`
- // will get correct result in next tick.
- textBackgroundColor.image = image;
-}
-
-function getBoxPosition(blockHeiht, style, rect) {
- var baseX = style.x || 0;
- var baseY = style.y || 0;
- var textAlign = style.textAlign;
- var textVerticalAlign = style.textVerticalAlign;
-
- // Text position represented by coord
- if (rect) {
- var textPosition = style.textPosition;
- if (textPosition instanceof Array) {
- // Percent
- baseX = rect.x + parsePercent(textPosition[0], rect.width);
- baseY = rect.y + parsePercent(textPosition[1], rect.height);
- }
- else {
- var res = adjustTextPositionOnRect(
- textPosition, rect, style.textDistance
- );
- baseX = res.x;
- baseY = res.y;
- // Default align and baseline when has textPosition
- textAlign = textAlign || res.textAlign;
- textVerticalAlign = textVerticalAlign || res.textVerticalAlign;
- }
-
- // textOffset is only support in RectText, otherwise
- // we have to adjust boundingRect for textOffset.
- var textOffset = style.textOffset;
- if (textOffset) {
- baseX += textOffset[0];
- baseY += textOffset[1];
- }
- }
-
- return {
- baseX: baseX,
- baseY: baseY,
- textAlign: textAlign,
- textVerticalAlign: textVerticalAlign
- };
-}
-
-function setCtx(ctx, prop, value) {
- ctx[prop] = fixShadow(ctx, prop, value);
- return ctx[prop];
-}
-
-/**
- * @param {string} [stroke] If specified, do not check style.textStroke.
- * @param {string} [lineWidth] If specified, do not check style.textStroke.
- * @param {number} style
- */
-function getStroke(stroke, lineWidth) {
- return (stroke == null || lineWidth <= 0 || stroke === 'transparent' || stroke === 'none')
- ? null
- // TODO pattern and gradient?
- : (stroke.image || stroke.colorStops)
- ? '#000'
- : stroke;
-}
-
-function getFill(fill) {
- return (fill == null || fill === 'none')
- ? null
- // TODO pattern and gradient?
- : (fill.image || fill.colorStops)
- ? '#000'
- : fill;
-}
-
-function parsePercent(value, maxValue) {
- if (typeof value === 'string') {
- if (value.lastIndexOf('%') >= 0) {
- return parseFloat(value) / 100 * maxValue;
- }
- return parseFloat(value);
- }
- return value;
-}
-
-function getTextXForPadding(x, textAlign, textPadding) {
- return textAlign === 'right'
- ? (x - textPadding[1])
- : textAlign === 'center'
- ? (x + textPadding[3] / 2 - textPadding[1] / 2)
- : (x + textPadding[3]);
-}
-
-/**
- * @param {string} text
- * @param {module:zrender/Style} style
- * @return {boolean}
- */
-function needDrawText(text, style) {
- return text != null
- && (text
- || style.textBackgroundColor
- || (style.textBorderWidth && style.textBorderColor)
- || style.textPadding
- );
-}
-
-/**
- * Mixin for drawing text in a element bounding rect
- * @module zrender/mixin/RectText
- */
-
-var tmpRect$1 = new BoundingRect();
-
-var RectText = function () {};
-
-RectText.prototype = {
-
- constructor: RectText,
-
- /**
- * Draw text in a rect with specified position.
- * @param {CanvasRenderingContext2D} ctx
- * @param {Object} rect Displayable rect
- */
- drawRectText: function (ctx, rect) {
- var style = this.style;
-
- rect = style.textRect || rect;
-
- // Optimize, avoid normalize every time.
- this.__dirty && normalizeTextStyle(style, true);
-
- var text = style.text;
-
- // Convert to string
- text != null && (text += '');
-
- if (!needDrawText(text, style)) {
- return;
- }
-
- // FIXME
- ctx.save();
-
- // Transform rect to view space
- var transform = this.transform;
- if (!style.transformText) {
- if (transform) {
- tmpRect$1.copy(rect);
- tmpRect$1.applyTransform(transform);
- rect = tmpRect$1;
- }
- }
- else {
- this.setTransform(ctx);
- }
-
- // transformText and textRotation can not be used at the same time.
- renderText(this, ctx, text, style, rect);
-
- ctx.restore();
- }
-};
-
-/**
- * 可绘制的图形基类
- * Base class of all displayable graphic objects
- * @module zrender/graphic/Displayable
- */
-
-
-/**
- * @alias module:zrender/graphic/Displayable
- * @extends module:zrender/Element
- * @extends module:zrender/graphic/mixin/RectText
- */
-function Displayable(opts) {
-
- opts = opts || {};
-
- Element.call(this, opts);
-
- // Extend properties
- for (var name in opts) {
- if (
- opts.hasOwnProperty(name) &&
- name !== 'style'
- ) {
- this[name] = opts[name];
- }
- }
-
- /**
- * @type {module:zrender/graphic/Style}
- */
- this.style = new Style(opts.style, this);
-
- this._rect = null;
- // Shapes for cascade clipping.
- this.__clipPaths = [];
-
- // FIXME Stateful must be mixined after style is setted
- // Stateful.call(this, opts);
-}
-
-Displayable.prototype = {
-
- constructor: Displayable,
-
- type: 'displayable',
-
- /**
- * Displayable 是否为脏,Painter 中会根据该标记判断是否需要是否需要重新绘制
- * Dirty flag. From which painter will determine if this displayable object needs brush
- * @name module:zrender/graphic/Displayable#__dirty
- * @type {boolean}
- */
- __dirty: true,
-
- /**
- * 图形是否可见,为true时不绘制图形,但是仍能触发鼠标事件
- * If ignore drawing of the displayable object. Mouse event will still be triggered
- * @name module:/zrender/graphic/Displayable#invisible
- * @type {boolean}
- * @default false
- */
- invisible: false,
-
- /**
- * @name module:/zrender/graphic/Displayable#z
- * @type {number}
- * @default 0
- */
- z: 0,
-
- /**
- * @name module:/zrender/graphic/Displayable#z
- * @type {number}
- * @default 0
- */
- z2: 0,
-
- /**
- * z层level,决定绘画在哪层canvas中
- * @name module:/zrender/graphic/Displayable#zlevel
- * @type {number}
- * @default 0
- */
- zlevel: 0,
-
- /**
- * 是否可拖拽
- * @name module:/zrender/graphic/Displayable#draggable
- * @type {boolean}
- * @default false
- */
- draggable: false,
-
- /**
- * 是否正在拖拽
- * @name module:/zrender/graphic/Displayable#draggable
- * @type {boolean}
- * @default false
- */
- dragging: false,
-
- /**
- * 是否相应鼠标事件
- * @name module:/zrender/graphic/Displayable#silent
- * @type {boolean}
- * @default false
- */
- silent: false,
-
- /**
- * If enable culling
- * @type {boolean}
- * @default false
- */
- culling: false,
-
- /**
- * Mouse cursor when hovered
- * @name module:/zrender/graphic/Displayable#cursor
- * @type {string}
- */
- cursor: 'pointer',
-
- /**
- * If hover area is bounding rect
- * @name module:/zrender/graphic/Displayable#rectHover
- * @type {string}
- */
- rectHover: false,
-
- /**
- * Render the element progressively when the value >= 0,
- * usefull for large data.
- * @type {boolean}
- */
- progressive: false,
-
- /**
- * @type {boolean}
- */
- incremental: false,
- // inplace is used with incremental
- inplace: false,
-
- beforeBrush: function (ctx) {},
-
- afterBrush: function (ctx) {},
-
- /**
- * 图形绘制方法
- * @param {CanvasRenderingContext2D} ctx
- */
- // Interface
- brush: function (ctx, prevEl) {},
-
- /**
- * 获取最小包围盒
- * @return {module:zrender/core/BoundingRect}
- */
- // Interface
- getBoundingRect: function () {},
-
- /**
- * 判断坐标 x, y 是否在图形上
- * If displayable element contain coord x, y
- * @param {number} x
- * @param {number} y
- * @return {boolean}
- */
- contain: function (x, y) {
- return this.rectContain(x, y);
- },
-
- /**
- * @param {Function} cb
- * @param {} context
- */
- traverse: function (cb, context) {
- cb.call(context, this);
- },
-
- /**
- * 判断坐标 x, y 是否在图形的包围盒上
- * If bounding rect of element contain coord x, y
- * @param {number} x
- * @param {number} y
- * @return {boolean}
- */
- rectContain: function (x, y) {
- var coord = this.transformCoordToLocal(x, y);
- var rect = this.getBoundingRect();
- return rect.contain(coord[0], coord[1]);
- },
-
- /**
- * 标记图形元素为脏,并且在下一帧重绘
- * Mark displayable element dirty and refresh next frame
- */
- dirty: function () {
- this.__dirty = true;
-
- this._rect = null;
-
- this.__zr && this.__zr.refresh();
- },
-
- /**
- * 图形是否会触发事件
- * If displayable object binded any event
- * @return {boolean}
- */
- // TODO, 通过 bind 绑定的事件
- // isSilent: function () {
- // return !(
- // this.hoverable || this.draggable
- // || this.onmousemove || this.onmouseover || this.onmouseout
- // || this.onmousedown || this.onmouseup || this.onclick
- // || this.ondragenter || this.ondragover || this.ondragleave
- // || this.ondrop
- // );
- // },
- /**
- * Alias for animate('style')
- * @param {boolean} loop
- */
- animateStyle: function (loop) {
- return this.animate('style', loop);
- },
-
- attrKV: function (key, value) {
- if (key !== 'style') {
- Element.prototype.attrKV.call(this, key, value);
- }
- else {
- this.style.set(value);
- }
- },
-
- /**
- * @param {Object|string} key
- * @param {*} value
- */
- setStyle: function (key, value) {
- this.style.set(key, value);
- this.dirty(false);
- return this;
- },
-
- /**
- * Use given style object
- * @param {Object} obj
- */
- useStyle: function (obj) {
- this.style = new Style(obj, this);
- this.dirty(false);
- return this;
- }
-};
-
-inherits(Displayable, Element);
-
-mixin(Displayable, RectText);
-
-/**
- * @alias zrender/graphic/Image
- * @extends module:zrender/graphic/Displayable
- * @constructor
- * @param {Object} opts
- */
-function ZImage(opts) {
- Displayable.call(this, opts);
-}
-
-ZImage.prototype = {
-
- constructor: ZImage,
-
- type: 'image',
-
- brush: function (ctx, prevEl) {
- var style = this.style;
- var src = style.image;
-
- // Must bind each time
- style.bind(ctx, this, prevEl);
-
- var image = this._image = createOrUpdateImage(
- src,
- this._image,
- this,
- this.onload
- );
-
- if (!image || !isImageReady(image)) {
- return;
- }
-
- // 图片已经加载完成
- // if (image.nodeName.toUpperCase() == 'IMG') {
- // if (!image.complete) {
- // return;
- // }
- // }
- // Else is canvas
-
- var x = style.x || 0;
- var y = style.y || 0;
- var width = style.width;
- var height = style.height;
- var aspect = image.width / image.height;
- if (width == null && height != null) {
- // Keep image/height ratio
- width = height * aspect;
- }
- else if (height == null && width != null) {
- height = width / aspect;
- }
- else if (width == null && height == null) {
- width = image.width;
- height = image.height;
- }
-
- // 设置transform
- this.setTransform(ctx);
-
- if (style.sWidth && style.sHeight) {
- var sx = style.sx || 0;
- var sy = style.sy || 0;
- ctx.drawImage(
- image,
- sx, sy, style.sWidth, style.sHeight,
- x, y, width, height
- );
- }
- else if (style.sx && style.sy) {
- var sx = style.sx;
- var sy = style.sy;
- var sWidth = width - sx;
- var sHeight = height - sy;
- ctx.drawImage(
- image,
- sx, sy, sWidth, sHeight,
- x, y, width, height
- );
- }
- else {
- ctx.drawImage(image, x, y, width, height);
- }
-
- // Draw rect text
- if (style.text != null) {
- // Only restore transform when needs draw text.
- this.restoreTransform(ctx);
- this.drawRectText(ctx, this.getBoundingRect());
- }
- },
-
- getBoundingRect: function () {
- var style = this.style;
- if (! this._rect) {
- this._rect = new BoundingRect(
- style.x || 0, style.y || 0, style.width || 0, style.height || 0
- );
- }
- return this._rect;
- }
-};
-
-inherits(ZImage, Displayable);
-
-var HOVER_LAYER_ZLEVEL = 1e5;
-var CANVAS_ZLEVEL = 314159;
-
-var EL_AFTER_INCREMENTAL_INC = 0.01;
-var INCREMENTAL_INC = 0.001;
-
-function parseInt10(val) {
- return parseInt(val, 10);
-}
-
-function isLayerValid(layer) {
- if (!layer) {
- return false;
- }
-
- if (layer.__builtin__) {
- return true;
- }
-
- if (typeof(layer.resize) !== 'function'
- || typeof(layer.refresh) !== 'function'
- ) {
- return false;
- }
-
- return true;
-}
-
-var tmpRect = new BoundingRect(0, 0, 0, 0);
-var viewRect = new BoundingRect(0, 0, 0, 0);
-function isDisplayableCulled(el, width, height) {
- tmpRect.copy(el.getBoundingRect());
- if (el.transform) {
- tmpRect.applyTransform(el.transform);
- }
- viewRect.width = width;
- viewRect.height = height;
- return !tmpRect.intersect(viewRect);
-}
-
-function isClipPathChanged(clipPaths, prevClipPaths) {
- if (clipPaths == prevClipPaths) { // Can both be null or undefined
- return false;
- }
-
- if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) {
- return true;
- }
- for (var i = 0; i < clipPaths.length; i++) {
- if (clipPaths[i] !== prevClipPaths[i]) {
- return true;
- }
- }
-}
-
-function doClip(clipPaths, ctx) {
- for (var i = 0; i < clipPaths.length; i++) {
- var clipPath = clipPaths[i];
-
- clipPath.setTransform(ctx);
- ctx.beginPath();
- clipPath.buildPath(ctx, clipPath.shape);
- ctx.clip();
- // Transform back
- clipPath.restoreTransform(ctx);
- }
-}
-
-function createRoot(width, height) {
- var domRoot = document.createElement('div');
-
- // domRoot.onselectstart = returnFalse; // 避免页面选中的尴尬
- domRoot.style.cssText = [
- 'position:relative',
- 'overflow:hidden',
- 'width:' + width + 'px',
- 'height:' + height + 'px',
- 'padding:0',
- 'margin:0',
- 'border-width:0'
- ].join(';') + ';';
-
- return domRoot;
-}
-
-
-/**
- * @alias module:zrender/Painter
- * @constructor
- * @param {HTMLElement} root 绘图容器
- * @param {module:zrender/Storage} storage
- * @param {Object} opts
- */
-var Painter = function (root, storage, opts) {
-
- this.type = 'canvas';
-
- // In node environment using node-canvas
- var singleCanvas = !root.nodeName // In node ?
- || root.nodeName.toUpperCase() === 'CANVAS';
-
- this._opts = opts = extend({}, opts || {});
-
- /**
- * @type {number}
- */
- this.dpr = opts.devicePixelRatio || devicePixelRatio;
- /**
- * @type {boolean}
- * @private
- */
- this._singleCanvas = singleCanvas;
- /**
- * 绘图容器
- * @type {HTMLElement}
- */
- this.root = root;
-
- var rootStyle = root.style;
-
- if (rootStyle) {
- rootStyle['-webkit-tap-highlight-color'] = 'transparent';
- rootStyle['-webkit-user-select'] =
- rootStyle['user-select'] =
- rootStyle['-webkit-touch-callout'] = 'none';
-
- root.innerHTML = '';
- }
-
- /**
- * @type {module:zrender/Storage}
- */
- this.storage = storage;
-
- /**
- * @type {Array.}
- * @private
- */
- var zlevelList = this._zlevelList = [];
-
- /**
- * @type {Object.}
- * @private
- */
- var layers = this._layers = {};
-
- /**
- * @type {Object.}
- * @private
- */
- this._layerConfig = {};
-
- /**
- * zrender will do compositing when root is a canvas and have multiple zlevels.
- */
- this._needsManuallyCompositing = false;
-
- if (!singleCanvas) {
- this._width = this._getSize(0);
- this._height = this._getSize(1);
-
- var domRoot = this._domRoot = createRoot(
- this._width, this._height
- );
- root.appendChild(domRoot);
- }
- else {
- var width = root.width;
- var height = root.height;
-
- if (opts.width != null) {
- width = opts.width;
- }
- if (opts.height != null) {
- height = opts.height;
- }
- this.dpr = opts.devicePixelRatio || 1;
-
- // Use canvas width and height directly
- root.width = width * this.dpr;
- root.height = height * this.dpr;
-
- this._width = width;
- this._height = height;
-
- // Create layer if only one given canvas
- // Device can be specified to create a high dpi image.
- var mainLayer = new Layer(root, this, this.dpr);
- mainLayer.__builtin__ = true;
- mainLayer.initContext();
- // FIXME Use canvas width and height
- // mainLayer.resize(width, height);
- layers[CANVAS_ZLEVEL] = mainLayer;
- // Not use common zlevel.
- zlevelList.push(CANVAS_ZLEVEL);
-
- this._domRoot = root;
- }
-
- /**
- * @type {module:zrender/Layer}
- * @private
- */
- this._hoverlayer = null;
-
- this._hoverElements = [];
-};
-
-Painter.prototype = {
-
- constructor: Painter,
-
- getType: function () {
- return 'canvas';
- },
-
- /**
- * If painter use a single canvas
- * @return {boolean}
- */
- isSingleCanvas: function () {
- return this._singleCanvas;
- },
- /**
- * @return {HTMLDivElement}
- */
- getViewportRoot: function () {
- return this._domRoot;
- },
-
- getViewportRootOffset: function () {
- var viewportRoot = this.getViewportRoot();
- if (viewportRoot) {
- return {
- offsetLeft: viewportRoot.offsetLeft || 0,
- offsetTop: viewportRoot.offsetTop || 0
- };
- }
- },
-
- /**
- * 刷新
- * @param {boolean} [paintAll=false] 强制绘制所有displayable
- */
- refresh: function (paintAll) {
-
- var list = this.storage.getDisplayList(true);
-
- var zlevelList = this._zlevelList;
-
- this._redrawId = Math.random();
-
- this._paintList(list, paintAll, this._redrawId);
-
- // Paint custum layers
- for (var i = 0; i < zlevelList.length; i++) {
- var z = zlevelList[i];
- var layer = this._layers[z];
- if (!layer.__builtin__ && layer.refresh) {
- var clearColor = i === 0 ? this._backgroundColor : null;
- layer.refresh(clearColor);
- }
- }
-
- this.refreshHover();
-
- return this;
- },
-
- addHover: function (el, hoverStyle) {
- if (el.__hoverMir) {
- return;
- }
- var elMirror = new el.constructor({
- style: el.style,
- shape: el.shape
- });
- elMirror.__from = el;
- el.__hoverMir = elMirror;
- elMirror.setStyle(hoverStyle);
- this._hoverElements.push(elMirror);
- },
-
- removeHover: function (el) {
- var elMirror = el.__hoverMir;
- var hoverElements = this._hoverElements;
- var idx = indexOf(hoverElements, elMirror);
- if (idx >= 0) {
- hoverElements.splice(idx, 1);
- }
- el.__hoverMir = null;
- },
-
- clearHover: function (el) {
- var hoverElements = this._hoverElements;
- for (var i = 0; i < hoverElements.length; i++) {
- var from = hoverElements[i].__from;
- if (from) {
- from.__hoverMir = null;
- }
- }
- hoverElements.length = 0;
- },
-
- refreshHover: function () {
- var hoverElements = this._hoverElements;
- var len = hoverElements.length;
- var hoverLayer = this._hoverlayer;
- hoverLayer && hoverLayer.clear();
-
- if (!len) {
- return;
- }
- sort(hoverElements, this.storage.displayableSortFunc);
-
- // Use a extream large zlevel
- // FIXME?
- if (!hoverLayer) {
- hoverLayer = this._hoverlayer = this.getLayer(HOVER_LAYER_ZLEVEL);
- }
-
- var scope = {};
- hoverLayer.ctx.save();
- for (var i = 0; i < len;) {
- var el = hoverElements[i];
- var originalEl = el.__from;
- // Original el is removed
- // PENDING
- if (!(originalEl && originalEl.__zr)) {
- hoverElements.splice(i, 1);
- originalEl.__hoverMir = null;
- len--;
- continue;
- }
- i++;
-
- // Use transform
- // FIXME style and shape ?
- if (!originalEl.invisible) {
- el.transform = originalEl.transform;
- el.invTransform = originalEl.invTransform;
- el.__clipPaths = originalEl.__clipPaths;
- // el.
- this._doPaintEl(el, hoverLayer, true, scope);
- }
- }
- hoverLayer.ctx.restore();
- },
-
- getHoverLayer: function () {
- return this.getLayer(HOVER_LAYER_ZLEVEL);
- },
-
- _paintList: function (list, paintAll, redrawId) {
- if (this._redrawId !== redrawId) {
- return;
- }
-
- paintAll = paintAll || false;
-
- this._updateLayerStatus(list);
-
- var finished = this._doPaintList(list, paintAll);
-
- if (this._needsManuallyCompositing) {
- this._compositeManually();
- }
-
- if (!finished) {
- var self = this;
- requestAnimationFrame(function () {
- self._paintList(list, paintAll, redrawId);
- });
- }
- },
-
- _compositeManually: function () {
- var ctx = this.getLayer(CANVAS_ZLEVEL).ctx;
- var width = this._domRoot.width;
- var height = this._domRoot.height;
- ctx.clearRect(0, 0, width, height);
- // PENDING, If only builtin layer?
- this.eachBuiltinLayer(function (layer) {
- if (layer.virtual) {
- ctx.drawImage(layer.dom, 0, 0, width, height);
- }
- });
- },
-
- _doPaintList: function (list, paintAll) {
- var layerList = [];
- for (var zi = 0; zi < this._zlevelList.length; zi++) {
- var zlevel = this._zlevelList[zi];
- var layer = this._layers[zlevel];
- if (layer.__builtin__
- && layer !== this._hoverlayer
- && (layer.__dirty || paintAll)
- ) {
- layerList.push(layer);
- }
- }
-
- var finished = true;
-
- for (var k = 0; k < layerList.length; k++) {
- var layer = layerList[k];
- var ctx = layer.ctx;
- var scope = {};
- ctx.save();
-
- var start = paintAll ? layer.__startIndex : layer.__drawIndex;
-
- var useTimer = !paintAll && layer.incremental && Date.now;
- var startTime = useTimer && Date.now();
-
- var clearColor = layer.zlevel === this._zlevelList[0]
- ? this._backgroundColor : null;
- // All elements in this layer are cleared.
- if (layer.__startIndex === layer.__endIndex) {
- layer.clear(false, clearColor);
- }
- else if (start === layer.__startIndex) {
- var firstEl = list[start];
- if (!firstEl.incremental || !firstEl.notClear || paintAll) {
- layer.clear(false, clearColor);
- }
- }
- if (start === -1) {
- console.error('For some unknown reason. drawIndex is -1');
- start = layer.__startIndex;
- }
- for (var i = start; i < layer.__endIndex; i++) {
- var el = list[i];
- this._doPaintEl(el, layer, paintAll, scope);
- el.__dirty = false;
-
- if (useTimer) {
- // Date.now can be executed in 13,025,305 ops/second.
- var dTime = Date.now() - startTime;
- // Give 15 millisecond to draw.
- // The rest elements will be drawn in the next frame.
- if (dTime > 15) {
- break;
- }
- }
- }
-
- layer.__drawIndex = i;
-
- if (layer.__drawIndex < layer.__endIndex) {
- finished = false;
- }
-
- if (scope.prevElClipPaths) {
- // Needs restore the state. If last drawn element is in the clipping area.
- ctx.restore();
- }
-
- ctx.restore();
- }
-
- if (env$1.wxa) {
- // Flush for weixin application
- each$1(this._layers, function (layer) {
- if (layer && layer.ctx && layer.ctx.draw) {
- layer.ctx.draw();
- }
- });
- }
-
- return finished;
- },
-
- _doPaintEl: function (el, currentLayer, forcePaint, scope) {
- var ctx = currentLayer.ctx;
- var m = el.transform;
- if (
- (currentLayer.__dirty || forcePaint)
- // Ignore invisible element
- && !el.invisible
- // Ignore transparent element
- && el.style.opacity !== 0
- // Ignore scale 0 element, in some environment like node-canvas
- // Draw a scale 0 element can cause all following draw wrong
- // And setTransform with scale 0 will cause set back transform failed.
- && !(m && !m[0] && !m[3])
- // Ignore culled element
- && !(el.culling && isDisplayableCulled(el, this._width, this._height))
- ) {
-
- var clipPaths = el.__clipPaths;
-
- // Optimize when clipping on group with several elements
- if (!scope.prevElClipPaths
- || isClipPathChanged(clipPaths, scope.prevElClipPaths)
- ) {
- // If has previous clipping state, restore from it
- if (scope.prevElClipPaths) {
- currentLayer.ctx.restore();
- scope.prevElClipPaths = null;
-
- // Reset prevEl since context has been restored
- scope.prevEl = null;
- }
- // New clipping state
- if (clipPaths) {
- ctx.save();
- doClip(clipPaths, ctx);
- scope.prevElClipPaths = clipPaths;
- }
- }
- el.beforeBrush && el.beforeBrush(ctx);
-
- el.brush(ctx, scope.prevEl || null);
- scope.prevEl = el;
-
- el.afterBrush && el.afterBrush(ctx);
- }
- },
-
- /**
- * 获取 zlevel 所在层,如果不存在则会创建一个新的层
- * @param {number} zlevel
- * @param {boolean} virtual Virtual layer will not be inserted into dom.
- * @return {module:zrender/Layer}
- */
- getLayer: function (zlevel, virtual) {
- if (this._singleCanvas && !this._needsManuallyCompositing) {
- zlevel = CANVAS_ZLEVEL;
- }
- var layer = this._layers[zlevel];
- if (!layer) {
- // Create a new layer
- layer = new Layer('zr_' + zlevel, this, this.dpr);
- layer.zlevel = zlevel;
- layer.__builtin__ = true;
-
- if (this._layerConfig[zlevel]) {
- merge(layer, this._layerConfig[zlevel], true);
- }
-
- if (virtual) {
- layer.virtual = virtual;
- }
-
- this.insertLayer(zlevel, layer);
-
- // Context is created after dom inserted to document
- // Or excanvas will get 0px clientWidth and clientHeight
- layer.initContext();
- }
-
- return layer;
- },
-
- insertLayer: function (zlevel, layer) {
-
- var layersMap = this._layers;
- var zlevelList = this._zlevelList;
- var len = zlevelList.length;
- var prevLayer = null;
- var i = -1;
- var domRoot = this._domRoot;
-
- if (layersMap[zlevel]) {
- zrLog('ZLevel ' + zlevel + ' has been used already');
- return;
- }
- // Check if is a valid layer
- if (!isLayerValid(layer)) {
- zrLog('Layer of zlevel ' + zlevel + ' is not valid');
- return;
- }
-
- if (len > 0 && zlevel > zlevelList[0]) {
- for (i = 0; i < len - 1; i++) {
- if (
- zlevelList[i] < zlevel
- && zlevelList[i + 1] > zlevel
- ) {
- break;
- }
- }
- prevLayer = layersMap[zlevelList[i]];
- }
- zlevelList.splice(i + 1, 0, zlevel);
-
- layersMap[zlevel] = layer;
-
- // Vitual layer will not directly show on the screen.
- // (It can be a WebGL layer and assigned to a ZImage element)
- // But it still under management of zrender.
- if (!layer.virtual) {
- if (prevLayer) {
- var prevDom = prevLayer.dom;
- if (prevDom.nextSibling) {
- domRoot.insertBefore(
- layer.dom,
- prevDom.nextSibling
- );
- }
- else {
- domRoot.appendChild(layer.dom);
- }
- }
- else {
- if (domRoot.firstChild) {
- domRoot.insertBefore(layer.dom, domRoot.firstChild);
- }
- else {
- domRoot.appendChild(layer.dom);
- }
- }
- }
- },
-
- // Iterate each layer
- eachLayer: function (cb, context) {
- var zlevelList = this._zlevelList;
- var z;
- var i;
- for (i = 0; i < zlevelList.length; i++) {
- z = zlevelList[i];
- cb.call(context, this._layers[z], z);
- }
- },
-
- // Iterate each buildin layer
- eachBuiltinLayer: function (cb, context) {
- var zlevelList = this._zlevelList;
- var layer;
- var z;
- var i;
- for (i = 0; i < zlevelList.length; i++) {
- z = zlevelList[i];
- layer = this._layers[z];
- if (layer.__builtin__) {
- cb.call(context, layer, z);
- }
- }
- },
-
- // Iterate each other layer except buildin layer
- eachOtherLayer: function (cb, context) {
- var zlevelList = this._zlevelList;
- var layer;
- var z;
- var i;
- for (i = 0; i < zlevelList.length; i++) {
- z = zlevelList[i];
- layer = this._layers[z];
- if (!layer.__builtin__) {
- cb.call(context, layer, z);
- }
- }
- },
-
- /**
- * 获取所有已创建的层
- * @param {Array.} [prevLayer]
- */
- getLayers: function () {
- return this._layers;
- },
-
- _updateLayerStatus: function (list) {
-
- this.eachBuiltinLayer(function (layer, z) {
- layer.__dirty = layer.__used = false;
- });
-
- function updatePrevLayer(idx) {
- if (prevLayer) {
- if (prevLayer.__endIndex !== idx) {
- prevLayer.__dirty = true;
- }
- prevLayer.__endIndex = idx;
- }
- }
-
- if (this._singleCanvas) {
- for (var i = 1; i < list.length; i++) {
- var el = list[i];
- if (el.zlevel !== list[i - 1].zlevel || el.incremental) {
- this._needsManuallyCompositing = true;
- break;
- }
- }
- }
-
- var prevLayer = null;
- var incrementalLayerCount = 0;
- for (var i = 0; i < list.length; i++) {
- var el = list[i];
- var zlevel = el.zlevel;
- var layer;
- // PENDING If change one incremental element style ?
- // TODO Where there are non-incremental elements between incremental elements.
- if (el.incremental) {
- layer = this.getLayer(zlevel + INCREMENTAL_INC, this._needsManuallyCompositing);
- layer.incremental = true;
- incrementalLayerCount = 1;
- }
- else {
- layer = this.getLayer(zlevel + (incrementalLayerCount > 0 ? EL_AFTER_INCREMENTAL_INC : 0), this._needsManuallyCompositing);
- }
-
- if (!layer.__builtin__) {
- zrLog('ZLevel ' + zlevel + ' has been used by unkown layer ' + layer.id);
- }
-
- if (layer !== prevLayer) {
- layer.__used = true;
- if (layer.__startIndex !== i) {
- layer.__dirty = true;
- }
- layer.__startIndex = i;
- if (!layer.incremental) {
- layer.__drawIndex = i;
- }
- else {
- // Mark layer draw index needs to update.
- layer.__drawIndex = -1;
- }
- updatePrevLayer(i);
- prevLayer = layer;
- }
- if (el.__dirty) {
- layer.__dirty = true;
- if (layer.incremental && layer.__drawIndex < 0) {
- // Start draw from the first dirty element.
- layer.__drawIndex = i;
- }
- }
- }
-
- updatePrevLayer(i);
-
- this.eachBuiltinLayer(function (layer, z) {
- // Used in last frame but not in this frame. Needs clear
- if (!layer.__used && layer.getElementCount() > 0) {
- layer.__dirty = true;
- layer.__startIndex = layer.__endIndex = layer.__drawIndex = 0;
- }
- // For incremental layer. In case start index changed and no elements are dirty.
- if (layer.__dirty && layer.__drawIndex < 0) {
- layer.__drawIndex = layer.__startIndex;
- }
- });
- },
-
- /**
- * 清除hover层外所有内容
- */
- clear: function () {
- this.eachBuiltinLayer(this._clearLayer);
- return this;
- },
-
- _clearLayer: function (layer) {
- layer.clear();
- },
-
- setBackgroundColor: function (backgroundColor) {
- this._backgroundColor = backgroundColor;
- },
-
- /**
- * 修改指定zlevel的绘制参数
- *
- * @param {string} zlevel
- * @param {Object} config 配置对象
- * @param {string} [config.clearColor=0] 每次清空画布的颜色
- * @param {string} [config.motionBlur=false] 是否开启动态模糊
- * @param {number} [config.lastFrameAlpha=0.7]
- * 在开启动态模糊的时候使用,与上一帧混合的alpha值,值越大尾迹越明显
- */
- configLayer: function (zlevel, config) {
- if (config) {
- var layerConfig = this._layerConfig;
- if (!layerConfig[zlevel]) {
- layerConfig[zlevel] = config;
- }
- else {
- merge(layerConfig[zlevel], config, true);
- }
-
- for (var i = 0; i < this._zlevelList.length; i++) {
- var _zlevel = this._zlevelList[i];
- if (_zlevel === zlevel || _zlevel === zlevel + EL_AFTER_INCREMENTAL_INC) {
- var layer = this._layers[_zlevel];
- merge(layer, layerConfig[zlevel], true);
- }
- }
- }
- },
-
- /**
- * 删除指定层
- * @param {number} zlevel 层所在的zlevel
- */
- delLayer: function (zlevel) {
- var layers = this._layers;
- var zlevelList = this._zlevelList;
- var layer = layers[zlevel];
- if (!layer) {
- return;
- }
- layer.dom.parentNode.removeChild(layer.dom);
- delete layers[zlevel];
-
- zlevelList.splice(indexOf(zlevelList, zlevel), 1);
- },
-
- /**
- * 区域大小变化后重绘
- */
- resize: function (width, height) {
- if (!this._domRoot.style) { // Maybe in node or worker
- if (width == null || height == null) {
- return;
- }
- this._width = width;
- this._height = height;
-
- this.getLayer(CANVAS_ZLEVEL).resize(width, height);
- }
- else {
- var domRoot = this._domRoot;
- // FIXME Why ?
- domRoot.style.display = 'none';
-
- // Save input w/h
- var opts = this._opts;
- width != null && (opts.width = width);
- height != null && (opts.height = height);
-
- width = this._getSize(0);
- height = this._getSize(1);
-
- domRoot.style.display = '';
-
- // 优化没有实际改变的resize
- if (this._width != width || height != this._height) {
- domRoot.style.width = width + 'px';
- domRoot.style.height = height + 'px';
-
- for (var id in this._layers) {
- if (this._layers.hasOwnProperty(id)) {
- this._layers[id].resize(width, height);
- }
- }
- each$1(this._progressiveLayers, function (layer) {
- layer.resize(width, height);
- });
-
- this.refresh(true);
- }
-
- this._width = width;
- this._height = height;
-
- }
- return this;
- },
-
- /**
- * 清除单独的一个层
- * @param {number} zlevel
- */
- clearLayer: function (zlevel) {
- var layer = this._layers[zlevel];
- if (layer) {
- layer.clear();
- }
- },
-
- /**
- * 释放
- */
- dispose: function () {
- this.root.innerHTML = '';
-
- this.root =
- this.storage =
-
- this._domRoot =
- this._layers = null;
- },
-
- /**
- * Get canvas which has all thing rendered
- * @param {Object} opts
- * @param {string} [opts.backgroundColor]
- * @param {number} [opts.pixelRatio]
- */
- getRenderedCanvas: function (opts) {
- opts = opts || {};
- if (this._singleCanvas && !this._compositeManually) {
- return this._layers[CANVAS_ZLEVEL].dom;
- }
-
- var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr);
- imageLayer.initContext();
- imageLayer.clear(false, opts.backgroundColor || this._backgroundColor);
-
- if (opts.pixelRatio <= this.dpr) {
- this.refresh();
-
- var width = imageLayer.dom.width;
- var height = imageLayer.dom.height;
- var ctx = imageLayer.ctx;
- this.eachLayer(function (layer) {
- if (layer.__builtin__) {
- ctx.drawImage(layer.dom, 0, 0, width, height);
- }
- else if (layer.renderToCanvas) {
- imageLayer.ctx.save();
- layer.renderToCanvas(imageLayer.ctx);
- imageLayer.ctx.restore();
- }
- });
- }
- else {
- // PENDING, echarts-gl and incremental rendering.
- var scope = {};
- var displayList = this.storage.getDisplayList(true);
- for (var i = 0; i < displayList.length; i++) {
- var el = displayList[i];
- this._doPaintEl(el, imageLayer, true, scope);
- }
- }
-
- return imageLayer.dom;
- },
- /**
- * 获取绘图区域宽度
- */
- getWidth: function () {
- return this._width;
- },
-
- /**
- * 获取绘图区域高度
- */
- getHeight: function () {
- return this._height;
- },
-
- _getSize: function (whIdx) {
- var opts = this._opts;
- var wh = ['width', 'height'][whIdx];
- var cwh = ['clientWidth', 'clientHeight'][whIdx];
- var plt = ['paddingLeft', 'paddingTop'][whIdx];
- var prb = ['paddingRight', 'paddingBottom'][whIdx];
-
- if (opts[wh] != null && opts[wh] !== 'auto') {
- return parseFloat(opts[wh]);
- }
-
- var root = this.root;
- // IE8 does not support getComputedStyle, but it use VML.
- var stl = document.defaultView.getComputedStyle(root);
-
- return (
- (root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh]))
- - (parseInt10(stl[plt]) || 0)
- - (parseInt10(stl[prb]) || 0)
- ) | 0;
- },
-
- pathToImage: function (path, dpr) {
- dpr = dpr || this.dpr;
-
- var canvas = document.createElement('canvas');
- var ctx = canvas.getContext('2d');
- var rect = path.getBoundingRect();
- var style = path.style;
- var shadowBlurSize = style.shadowBlur * dpr;
- var shadowOffsetX = style.shadowOffsetX * dpr;
- var shadowOffsetY = style.shadowOffsetY * dpr;
- var lineWidth = style.hasStroke() ? style.lineWidth : 0;
-
- var leftMargin = Math.max(lineWidth / 2, -shadowOffsetX + shadowBlurSize);
- var rightMargin = Math.max(lineWidth / 2, shadowOffsetX + shadowBlurSize);
- var topMargin = Math.max(lineWidth / 2, -shadowOffsetY + shadowBlurSize);
- var bottomMargin = Math.max(lineWidth / 2, shadowOffsetY + shadowBlurSize);
- var width = rect.width + leftMargin + rightMargin;
- var height = rect.height + topMargin + bottomMargin;
-
- canvas.width = width * dpr;
- canvas.height = height * dpr;
-
- ctx.scale(dpr, dpr);
- ctx.clearRect(0, 0, width, height);
- ctx.dpr = dpr;
-
- var pathTransform = {
- position: path.position,
- rotation: path.rotation,
- scale: path.scale
- };
- path.position = [leftMargin - rect.x, topMargin - rect.y];
- path.rotation = 0;
- path.scale = [1, 1];
- path.updateTransform();
- if (path) {
- path.brush(ctx);
- }
-
- var ImageShape = ZImage;
- var imgShape = new ImageShape({
- style: {
- x: 0,
- y: 0,
- image: canvas
- }
- });
-
- if (pathTransform.position != null) {
- imgShape.position = path.position = pathTransform.position;
- }
-
- if (pathTransform.rotation != null) {
- imgShape.rotation = path.rotation = pathTransform.rotation;
- }
-
- if (pathTransform.scale != null) {
- imgShape.scale = path.scale = pathTransform.scale;
- }
-
- return imgShape;
- }
-};
-
-/**
- * 事件辅助类
- * @module zrender/core/event
- * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
- */
-
-var isDomLevel2 = (typeof window !== 'undefined') && !!window.addEventListener;
-
-var MOUSE_EVENT_REG = /^(?:mouse|pointer|contextmenu|drag|drop)|click/;
-
-function getBoundingClientRect(el) {
- // BlackBerry 5, iOS 3 (original iPhone) don't have getBoundingRect
- return el.getBoundingClientRect ? el.getBoundingClientRect() : {left: 0, top: 0};
-}
-
-// `calculate` is optional, default false
-function clientToLocal(el, e, out, calculate) {
- out = out || {};
-
- // According to the W3C Working Draft, offsetX and offsetY should be relative
- // to the padding edge of the target element. The only browser using this convention
- // is IE. Webkit uses the border edge, Opera uses the content edge, and FireFox does
- // not support the properties.
- // (see http://www.jacklmoore.com/notes/mouse-position/)
- // In zr painter.dom, padding edge equals to border edge.
-
- // FIXME
- // When mousemove event triggered on ec tooltip, target is not zr painter.dom, and
- // offsetX/Y is relative to e.target, where the calculation of zrX/Y via offsetX/Y
- // is too complex. So css-transfrom dont support in this case temporarily.
- if (calculate || !env$1.canvasSupported) {
- defaultGetZrXY(el, e, out);
- }
- // Caution: In FireFox, layerX/layerY Mouse position relative to the closest positioned
- // ancestor element, so we should make sure el is positioned (e.g., not position:static).
- // BTW1, Webkit don't return the same results as FF in non-simple cases (like add
- // zoom-factor, overflow / opacity layers, transforms ...)
- // BTW2, (ev.offsetY || ev.pageY - $(ev.target).offset().top) is not correct in preserve-3d.
- //
- // BTW3, In ff, offsetX/offsetY is always 0.
- else if (env$1.browser.firefox && e.layerX != null && e.layerX !== e.offsetX) {
- out.zrX = e.layerX;
- out.zrY = e.layerY;
- }
- // For IE6+, chrome, safari, opera. (When will ff support offsetX?)
- else if (e.offsetX != null) {
- out.zrX = e.offsetX;
- out.zrY = e.offsetY;
- }
- // For some other device, e.g., IOS safari.
- else {
- defaultGetZrXY(el, e, out);
- }
-
- return out;
-}
-
-function defaultGetZrXY(el, e, out) {
- // This well-known method below does not support css transform.
- var box = getBoundingClientRect(el);
- out.zrX = e.clientX - box.left;
- out.zrY = e.clientY - box.top;
-}
-
-/**
- * 如果存在第三方嵌入的一些dom触发的事件,或touch事件,需要转换一下事件坐标.
- * `calculate` is optional, default false.
- */
-function normalizeEvent(el, e, calculate) {
-
- e = e || window.event;
-
- if (e.zrX != null) {
- return e;
- }
-
- var eventType = e.type;
- var isTouch = eventType && eventType.indexOf('touch') >= 0;
-
- if (!isTouch) {
- clientToLocal(el, e, e, calculate);
- e.zrDelta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3;
- }
- else {
- var touch = eventType != 'touchend'
- ? e.targetTouches[0]
- : e.changedTouches[0];
- touch && clientToLocal(el, touch, e, calculate);
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 === right; otherwise: 0;
- // See jQuery: https://github.com/jquery/jquery/blob/master/src/event.js
- // If e.which has been defined, if may be readonly,
- // see: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/which
- var button = e.button;
- if (e.which == null && button !== undefined && MOUSE_EVENT_REG.test(e.type)) {
- e.which = (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0)));
- }
-
- return e;
-}
-
-/**
- * @param {HTMLElement} el
- * @param {string} name
- * @param {Function} handler
- */
-function addEventListener(el, name, handler) {
- if (isDomLevel2) {
- // Reproduct the console warning:
- // [Violation] Added non-passive event listener to a scroll-blocking event.
- // Consider marking event handler as 'passive' to make the page more responsive.
- // Just set console log level: verbose in chrome dev tool.
- // then the warning log will be printed when addEventListener called.
- // See https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
- // We have not yet found a neat way to using passive. Because in zrender the dom event
- // listener delegate all of the upper events of element. Some of those events need
- // to prevent default. For example, the feature `preventDefaultMouseMove` of echarts.
- // Before passive can be adopted, these issues should be considered:
- // (1) Whether and how a zrender user specifies an event listener passive. And by default,
- // passive or not.
- // (2) How to tread that some zrender event listener is passive, and some is not. If
- // we use other way but not preventDefault of mousewheel and touchmove, browser
- // compatibility should be handled.
-
- // var opts = (env.passiveSupported && name === 'mousewheel')
- // ? {passive: true}
- // // By default, the third param of el.addEventListener is `capture: false`.
- // : void 0;
- // el.addEventListener(name, handler /* , opts */);
- el.addEventListener(name, handler);
- }
- else {
- el.attachEvent('on' + name, handler);
- }
-}
-
-function removeEventListener(el, name, handler) {
- if (isDomLevel2) {
- el.removeEventListener(name, handler);
- }
- else {
- el.detachEvent('on' + name, handler);
- }
-}
-
-/**
- * preventDefault and stopPropagation.
- * Notice: do not do that in zrender. Upper application
- * do that if necessary.
- *
- * @memberOf module:zrender/core/event
- * @method
- * @param {Event} e : event对象
- */
-var stop = isDomLevel2
- ? function (e) {
- e.preventDefault();
- e.stopPropagation();
- e.cancelBubble = true;
- }
- : function (e) {
- e.returnValue = false;
- e.cancelBubble = true;
- };
-
-function notLeftMouse(e) {
- // If e.which is undefined, considered as left mouse event.
- return e.which > 1;
-}
-
-/**
- * 动画主类, 调度和管理所有动画控制器
- *
- * @module zrender/animation/Animation
- * @author pissang(https://github.com/pissang)
- */
-// TODO Additive animation
-// http://iosoteric.com/additive-animations-animatewithduration-in-ios-8/
-// https://developer.apple.com/videos/wwdc2014/#236
-
-/**
- * @typedef {Object} IZRenderStage
- * @property {Function} update
- */
-
-/**
- * @alias module:zrender/animation/Animation
- * @constructor
- * @param {Object} [options]
- * @param {Function} [options.onframe]
- * @param {IZRenderStage} [options.stage]
- * @example
- * var animation = new Animation();
- * var obj = {
- * x: 100,
- * y: 100
- * };
- * animation.animate(node.position)
- * .when(1000, {
- * x: 500,
- * y: 500
- * })
- * .when(2000, {
- * x: 100,
- * y: 100
- * })
- * .start('spline');
- */
-var Animation = function (options) {
-
- options = options || {};
-
- this.stage = options.stage || {};
-
- this.onframe = options.onframe || function() {};
-
- // private properties
- this._clips = [];
-
- this._running = false;
-
- this._time;
-
- this._pausedTime;
-
- this._pauseStart;
-
- this._paused = false;
-
- Eventful.call(this);
-};
-
-Animation.prototype = {
-
- constructor: Animation,
- /**
- * 添加 clip
- * @param {module:zrender/animation/Clip} clip
- */
- addClip: function (clip) {
- this._clips.push(clip);
- },
- /**
- * 添加 animator
- * @param {module:zrender/animation/Animator} animator
- */
- addAnimator: function (animator) {
- animator.animation = this;
- var clips = animator.getClips();
- for (var i = 0; i < clips.length; i++) {
- this.addClip(clips[i]);
- }
- },
- /**
- * 删除动画片段
- * @param {module:zrender/animation/Clip} clip
- */
- removeClip: function(clip) {
- var idx = indexOf(this._clips, clip);
- if (idx >= 0) {
- this._clips.splice(idx, 1);
- }
- },
-
- /**
- * 删除动画片段
- * @param {module:zrender/animation/Animator} animator
- */
- removeAnimator: function (animator) {
- var clips = animator.getClips();
- for (var i = 0; i < clips.length; i++) {
- this.removeClip(clips[i]);
- }
- animator.animation = null;
- },
-
- _update: function() {
- var time = new Date().getTime() - this._pausedTime;
- var delta = time - this._time;
- var clips = this._clips;
- var len = clips.length;
-
- var deferredEvents = [];
- var deferredClips = [];
- for (var i = 0; i < len; i++) {
- var clip = clips[i];
- var e = clip.step(time, delta);
- // Throw out the events need to be called after
- // stage.update, like destroy
- if (e) {
- deferredEvents.push(e);
- deferredClips.push(clip);
- }
- }
-
- // Remove the finished clip
- for (var i = 0; i < len;) {
- if (clips[i]._needsRemove) {
- clips[i] = clips[len - 1];
- clips.pop();
- len--;
- }
- else {
- i++;
- }
- }
-
- len = deferredEvents.length;
- for (var i = 0; i < len; i++) {
- deferredClips[i].fire(deferredEvents[i]);
- }
-
- this._time = time;
-
- this.onframe(delta);
-
- // 'frame' should be triggered before stage, because upper application
- // depends on the sequence (e.g., echarts-stream and finish
- // event judge)
- this.trigger('frame', delta);
-
- if (this.stage.update) {
- this.stage.update();
- }
- },
-
- _startLoop: function () {
- var self = this;
-
- this._running = true;
-
- function step() {
- if (self._running) {
-
- requestAnimationFrame(step);
-
- !self._paused && self._update();
- }
- }
-
- requestAnimationFrame(step);
- },
-
- /**
- * Start animation.
- */
- start: function () {
-
- this._time = new Date().getTime();
- this._pausedTime = 0;
-
- this._startLoop();
- },
-
- /**
- * Stop animation.
- */
- stop: function () {
- this._running = false;
- },
-
- /**
- * Pause animation.
- */
- pause: function () {
- if (!this._paused) {
- this._pauseStart = new Date().getTime();
- this._paused = true;
- }
- },
-
- /**
- * Resume animation.
- */
- resume: function () {
- if (this._paused) {
- this._pausedTime += (new Date().getTime()) - this._pauseStart;
- this._paused = false;
- }
- },
-
- /**
- * Clear animation.
- */
- clear: function () {
- this._clips = [];
- },
-
- /**
- * Whether animation finished.
- */
- isFinished: function () {
- return !this._clips.length;
- },
-
- /**
- * Creat animator for a target, whose props can be animated.
- *
- * @param {Object} target
- * @param {Object} options
- * @param {boolean} [options.loop=false] Whether loop animation.
- * @param {Function} [options.getter=null] Get value from target.
- * @param {Function} [options.setter=null] Set value to target.
- * @return {module:zrender/animation/Animation~Animator}
- */
- // TODO Gap
- animate: function (target, options) {
- options = options || {};
-
- var animator = new Animator(
- target,
- options.loop,
- options.getter,
- options.setter
- );
-
- this.addAnimator(animator);
-
- return animator;
- }
-};
-
-mixin(Animation, Eventful);
-
-/**
- * Only implements needed gestures for mobile.
- */
-
-var GestureMgr = function () {
-
- /**
- * @private
- * @type {Array.