/** * echarts设备环境识别 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author firede[firede@firede.us] * @desc thanks zepto. */ define('zrender/tool/env',[],function() { // Zepto.js // (c) 2010-2013 Thomas Fuchs // Zepto.js may be freely distributed under the MIT license. function detect( ua ) { var os = this.os = {}; var browser = this.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 ie = ua.match(/MSIE ([\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.]+)/); // 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 (ie) browser.ie = true, browser.version = ie[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]; 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 || blackberry || bb10 || (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) || (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/)))); return { browser: browser, os: os, // 原生canvas支持 canvasSupported : document.createElement('canvas').getContext ? true : false } } return detect( navigator.userAgent ); }); /** * echarts默认配置项 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/config',[],function() { // 请原谅我这样写,这显然可以直接返回个对象,但那样的话outline就显示不出来了~~ var config = { // 图表类型 CHART_TYPE_LINE: 'line', CHART_TYPE_BAR: 'bar', CHART_TYPE_SCATTER: 'scatter', CHART_TYPE_PIE: 'pie', CHART_TYPE_RADAR: 'radar', CHART_TYPE_MAP: 'map', CHART_TYPE_K: 'k', CHART_TYPE_ISLAND: 'island', CHART_TYPE_FORCE : 'force', CHART_TYPE_CHORD : 'chord', // 组件类型 COMPONENT_TYPE_TITLE: 'title', COMPONENT_TYPE_LEGEND: 'legend', COMPONENT_TYPE_DATARANGE: 'dataRange', COMPONENT_TYPE_DATAVIEW: 'dataView', COMPONENT_TYPE_DATAZOOM: 'dataZoom', COMPONENT_TYPE_TOOLBOX: 'toolbox', COMPONENT_TYPE_TOOLTIP: 'tooltip', COMPONENT_TYPE_GRID: 'grid', COMPONENT_TYPE_AXIS: 'axis', COMPONENT_TYPE_POLAR: 'polar', COMPONENT_TYPE_X_AXIS: 'xAxis', COMPONENT_TYPE_Y_AXIS: 'yAxis', COMPONENT_TYPE_AXIS_CATEGORY: 'categoryAxis', COMPONENT_TYPE_AXIS_VALUE: 'valueAxis', // 全图默认背景 // backgroundColor: 'rgba(0,0,0,0)', // 默认色板 color: ['#ff7f50','#87cefa','#da70d6','#32cd32','#6495ed', '#ff69b4','#ba55d3','#cd5c5c','#ffa500','#40e0d0', '#1e90ff','#ff6347','#7b68ee','#00fa9a','#ffd700', '#6699FF','#ff6666','#3cb371','#b8860b','#30e0e0'], // 图表标题 title: { text: '', //link: null, // 超链接跳转 subtext: '', //sublink: null, // 超链接跳转 x: 'left', // 水平安放位置,默认为左对齐,可选为: // 'center' ¦ 'left' ¦ 'right' // ¦ {number}(x坐标,单位px) y: 'top', // 垂直安放位置,默认为全图顶端,可选为: // 'top' ¦ 'bottom' ¦ 'center' // ¦ {number}(y坐标,单位px) //textAlign: null // 水平对齐方式,默认根据x设置自动调整 backgroundColor: 'rgba(0,0,0,0)', borderColor: '#ccc', // 标题边框颜色 borderWidth: 0, // 标题边框线宽,单位px,默认为0(无边框) padding: 5, // 标题内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css itemGap: 10, // 主副标题纵向间隔,单位px,默认为10, textStyle: { fontSize: 18, fontWeight: 'bolder', color: '#333' // 主标题文字颜色 }, subtextStyle: { color: '#aaa' // 副标题文字颜色 } }, // 图例 legend: { orient: 'horizontal', // 布局方式,默认为水平布局,可选为: // 'horizontal' ¦ 'vertical' x: 'center', // 水平安放位置,默认为全图居中,可选为: // 'center' ¦ 'left' ¦ 'right' // ¦ {number}(x坐标,单位px) y: 'top', // 垂直安放位置,默认为全图顶端,可选为: // 'top' ¦ 'bottom' ¦ 'center' // ¦ {number}(y坐标,单位px) backgroundColor: 'rgba(0,0,0,0)', borderColor: '#ccc', // 图例边框颜色 borderWidth: 0, // 图例边框线宽,单位px,默认为0(无边框) padding: 5, // 图例内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css itemGap: 10, // 各个item之间的间隔,单位px,默认为10, // 横向布局时为水平间隔,纵向布局时为纵向间隔 itemWidth: 20, // 图例图形宽度 itemHeight: 14, // 图例图形高度 textStyle: { color: '#333' // 图例文字颜色 }, selectedMode: true // 选择模式,默认开启图例开关 // selected: null, // 配置默认选中状态,可配合LEGEND.SELECTED事件做动态数据载入 // data: [], // 图例内容(详见legend.data,数组中每一项代表一个item }, // 值域 dataRange: { orient: 'vertical', // 布局方式,默认为垂直布局,可选为: // 'horizontal' ¦ 'vertical' x: 'left', // 水平安放位置,默认为全图左对齐,可选为: // 'center' ¦ 'left' ¦ 'right' // ¦ {number}(x坐标,单位px) y: 'bottom', // 垂直安放位置,默认为全图底部,可选为: // 'top' ¦ 'bottom' ¦ 'center' // ¦ {number}(y坐标,单位px) backgroundColor: 'rgba(0,0,0,0)', borderColor: '#ccc', // 值域边框颜色 borderWidth: 0, // 值域边框线宽,单位px,默认为0(无边框) padding: 5, // 值域内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css itemGap: 10, // 各个item之间的间隔,单位px,默认为10, // 横向布局时为水平间隔,纵向布局时为纵向间隔 itemWidth: 20, // 值域图形宽度,线性渐变水平布局宽度为该值 * 10 itemHeight: 14, // 值域图形高度,线性渐变垂直布局高度为该值 * 10 // min: null, // 最小值 // max: null, // 最大值 precision: 0, // 小数精度,默认为0,无小数点 splitNumber: 5, // 分割段数,默认为5,为0时为线性渐变 calculable: false, // 是否值域漫游,启用后无视splitNumber,线性渐变 realtime: true, color:['#006edd','#e0ffff'],//颜色 //text:['高','低'], // 文本,默认为数值文本 textStyle: { color: '#333' // 值域文字颜色 } }, toolbox: { show : false, orient: 'horizontal', // 布局方式,默认为水平布局,可选为: // 'horizontal' ¦ 'vertical' x: 'right', // 水平安放位置,默认为全图右对齐,可选为: // 'center' ¦ 'left' ¦ 'right' // ¦ {number}(x坐标,单位px) y: 'top', // 垂直安放位置,默认为全图顶端,可选为: // 'top' ¦ 'bottom' ¦ 'center' // ¦ {number}(y坐标,单位px) color : ['#1e90ff','#22bb22','#4b0082','#d2691e'], backgroundColor: 'rgba(0,0,0,0)', // 工具箱背景颜色 borderColor: '#ccc', // 工具箱边框颜色 borderWidth: 0, // 工具箱边框线宽,单位px,默认为0(无边框) padding: 5, // 工具箱内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css itemGap: 10, // 各个item之间的间隔,单位px,默认为10, // 横向布局时为水平间隔,纵向布局时为纵向间隔 itemSize: 16, // 工具箱图形宽度 showTitle : true, //textStyle : {}, feature : { mark : { show : false, title : { mark : '辅助线开关', markUndo : '删除辅助线', markClear : '清空辅助线' }, lineStyle : { width : 1, color : '#1e90ff', type : 'dashed' } }, dataZoom : { show : false, title : { dataZoom : '区域缩放', dataZoomReset : '区域缩放后退' } }, dataView : { show : false, title : '数据视图', readOnly: false, lang : ['Data View', 'close', 'refresh'] }, magicType: { show : false, title : { line : '折线图切换', bar : '柱形图切换', stack : '堆叠', tiled : '平铺' }, type : [] // 'line', 'bar', 'stack', 'tiled' }, restore : { show : false, title : '还原' }, saveAsImage : { show : false, title : '保存为图片', type : 'png', lang : ['点击保存'] } } }, // 提示框 tooltip: { show: true, showContent: true, // tooltip主体内容 trigger: 'item', // 触发类型,默认数据触发,见下图,可选为:'item' ¦ 'axis' // formatter: null // 内容格式器:{string}(Template) ¦ {Function} islandFormatter: '{a}
{b} : {c}', // 数据孤岛内容格式器 showDelay: 20, // 显示延迟,添加显示延迟可以避免频繁切换,单位ms hideDelay: 100, // 隐藏延迟,单位ms transitionDuration : 0.4, // 动画变换时间,单位s backgroundColor: 'rgba(0,0,0,0.7)', // 提示背景颜色,默认为透明度为0.7的黑色 borderColor: '#333', // 提示边框颜色 borderRadius: 4, // 提示边框圆角,单位px,默认为4 borderWidth: 0, // 提示边框线宽,单位px,默认为0(无边框) padding: 5, // 提示内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css axisPointer : { // 坐标轴指示器,坐标轴触发有效 type : 'line', // 默认为直线,可选为:'line' | 'shadow' lineStyle : { // 直线指示器样式设置 color: '#48b', width: 2, type: 'solid' }, areaStyle : { // 阴影指示器样式设置 size: 'auto', // 阴影大小 color: 'rgba(150,150,150,0.3)' // 阴影颜色 } }, textStyle: { color: '#fff' } }, // 区域缩放控制器 dataZoom: { show: false, orient: 'horizontal', // 布局方式,默认为水平布局,可选为: // 'horizontal' ¦ 'vertical' // x: {number}, // 水平安放位置,默认为根据grid参数适配,可选为: // {number}(x坐标,单位px) // y: {number}, // 垂直安放位置,默认为根据grid参数适配,可选为: // {number}(y坐标,单位px) // width: {number}, // 指定宽度,横向布局时默认为根据grid参数适配 // height: {number}, // 指定高度,纵向布局时默认为根据grid参数适配 backgroundColor: 'rgba(0,0,0,0)', // 背景颜色 dataBackgroundColor: '#eee', // 数据背景颜色 fillerColor: 'rgba(144,197,237,0.2)', // 填充颜色 handleColor: 'rgba(70,130,180,0.8)', // 手柄颜色 // xAxisIndex: [], // 默认控制所有横向类目 // yAxisIndex: [], // 默认控制所有横向类目 // start: 0, // 默认为0 // end: 100, // 默认为全部 100% realtime: true // zoomLock: false // 是否锁定选择区域大小 }, // 网格 grid: { x: 80, y: 60, x2: 80, y2: 60, // width: {totalWidth} - x - x2, // height: {totalHeight} - y - y2, backgroundColor: 'rgba(0,0,0,0)', borderWidth: 1, borderColor: '#ccc' }, // 类目轴 categoryAxis: { position: 'bottom', // 位置 name: '', // 坐标轴名字,默认为空 nameLocation: 'end', // 坐标轴名字位置,支持'start' | 'end' nameTextStyle: {}, // 坐标轴文字样式,默认取全局样式 boundaryGap: true, // 类目起始和结束两端空白策略 axisLine: { // 坐标轴线 show: true, // 默认显示,属性show控制显示与否 lineStyle: { // 属性lineStyle控制线条样式 color: '#48b', width: 2, type: 'solid' } }, axisTick: { // 坐标轴小标记 show: true, // 属性show控制显示与否,默认不显示 interval: 'auto', inside : false, // 控制小标记是否在grid里 // onGap: null, length :5, // 属性length控制线长 lineStyle: { // 属性lineStyle控制线条样式 color: '#333', width: 1 } }, axisLabel: { // 坐标轴文本标签,详见axis.axisLabel show: true, interval: 'auto', rotate: 0, margin: 8, // formatter: null, textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE color: '#333' } }, splitLine: { // 分隔线 show: true, // 默认显示,属性show控制显示与否 // onGap: null, lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 color: ['#ccc'], width: 1, type: 'solid' } }, splitArea: { // 分隔区域 show: false, // 默认不显示,属性show控制显示与否 // onGap: null, areaStyle: { // 属性areaStyle(详见areaStyle)控制区域样式 color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'] } } }, // 数值型坐标轴默认参数 valueAxis: { position: 'left', // 位置 name: '', // 坐标轴名字,默认为空 nameLocation: 'end', // 坐标轴名字位置,支持'start' | 'end' nameTextStyle: {}, // 坐标轴文字样式,默认取全局样式 boundaryGap: [0, 0], // 数值起始和结束两端空白策略 // min: null, // 最小值 // max: null, // 最大值 // scale: false, // 脱离0值比例,放大聚焦到最终_min,_max区间 precision: 0, // 小数精度,默认为0,无小数点 power: 100, // 整数精度,默认为100,个位和百位为0 splitNumber: 5, // 分割段数,默认为5 axisLine: { // 坐标轴线 show: true, // 默认显示,属性show控制显示与否 lineStyle: { // 属性lineStyle控制线条样式 color: '#48b', width: 2, type: 'solid' } }, axisTick: { // 坐标轴小标记 show: false, // 属性show控制显示与否,默认不显示 inside : false, // 控制小标记是否在grid里 length :5, // 属性length控制线长 lineStyle: { // 属性lineStyle控制线条样式 color: '#333', width: 1 } }, axisLabel: { // 坐标轴文本标签,详见axis.axisLabel show: true, rotate: 0, margin: 8, // formatter: null, textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE color: '#333' } }, splitLine: { // 分隔线 show: true, // 默认显示,属性show控制显示与否 lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 color: ['#ccc'], width: 1, type: 'solid' } }, splitArea: { // 分隔区域 show: false, // 默认不显示,属性show控制显示与否 areaStyle: { // 属性areaStyle(详见areaStyle)控制区域样式 color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'] } } }, polar : { center : ['50%', '50%'], // 默认全局居中 radius : '75%', startAngle : 90, splitNumber : 5, name : { show: true, // formatter: null, textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE color: '#333' } }, axisLine: { // 坐标轴线 show: true, // 默认显示,属性show控制显示与否 lineStyle: { // 属性lineStyle控制线条样式 color: '#ccc', width: 1, type: 'solid' } }, axisLabel: { // 坐标轴文本标签,详见axis.axisLabel show: false, // formatter: null, textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE color: '#333' } }, splitArea : { show : true, areaStyle : { color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'] } }, splitLine : { show : true, lineStyle : { width : 1, color : '#ccc' } } //indicator : [] }, // 柱形图默认参数 bar: { // stack: null xAxisIndex: 0, yAxisIndex: 0, barMinHeight: 0, // 最小高度改为0 // barWidth: null, // 默认自适应 barGap: '30%', // 柱间距离,默认为柱形宽度的30%,可设固定值 barCategoryGap : '20%', // 类目间柱形距离,默认为类目间距的20%,可设固定值 itemStyle: { normal: { // color: '各异', borderColor: '#fff', // 柱条边线 borderRadius: 0, // 柱条边线圆角,单位px,默认为0 borderWidth: 0, // 柱条边线线宽,单位px,默认为1 label: { show: false // formatter: 标签文本格式器,同Tooltip.formatter,不支持回调 // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } }, emphasis: { // color: '各异', borderColor: '#fff', // 柱条边线 borderRadius: 0, // 柱条边线圆角,单位px,默认为0 borderWidth: 0, // 柱条边线线宽,单位px,默认为1 label: { show: false // formatter: 标签文本格式器,同Tooltip.formatter,不支持回调 // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } } } }, // 折线图默认参数 line: { // stack: null xAxisIndex: 0, yAxisIndex: 0, itemStyle: { normal: { // color: 各异, label: { show: false // formatter: 标签文本格式器,同Tooltip.formatter,不支持回调 // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, lineStyle: { width: 2, type: 'solid', shadowColor : 'rgba(0,0,0,0)', //默认透明 shadowBlur: 0, shadowOffsetX: 0, shadowOffsetY: 0 } }, emphasis: { // color: 各异, label: { show: false // formatter: 标签文本格式器,同Tooltip.formatter,不支持回调 // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } } }, //smooth : false, //symbol: null, // 拐点图形类型 symbolSize: 2, // 拐点图形大小 //symbolRotate : null, // 拐点图形旋转控制 showAllSymbol: false // 标志图形默认只有主轴显示(随主轴标签间隔隐藏策略) }, // K线图默认参数 k: { xAxisIndex: 0, yAxisIndex: 0, // barWidth : null // 默认自适应 // barMaxWidth : null // 默认自适应 itemStyle: { normal: { color: '#fff', // 阳线填充颜色 color0: '#00aa11', // 阴线填充颜色 lineStyle: { width: 1, color: '#ff3200', // 阳线边框颜色 color0: '#00aa11' // 阴线边框颜色 } }, emphasis: { // color: 各异, // color0: 各异 } } }, // 散点图默认参数 scatter: { xAxisIndex: 0, yAxisIndex: 0, //symbol: null, // 图形类型 symbolSize: 4, // 图形大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2 //symbolRotate : null, // 图形旋转控制 large: false, // 大规模散点图 largeThreshold: 2000,// 大规模阀值,large为true且数据量>largeThreshold才启用大规模模式 itemStyle: { normal: { // color: 各异, label: { show: false, // 标签文本格式器,同Tooltip.formatter,不支持回调 formatter : function(a, b, c) { if (typeof c[2] != 'undefined') { return c[2]; } else { return c[0] + ' , ' + c[1]; } } // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } }, emphasis: { // color: '各异' label: { show: false, // 标签文本格式器,同Tooltip.formatter,不支持回调 formatter : function(a, b, c) { if (typeof c[2] != 'undefined') { return c[2]; } else { return c[0] + ' , ' + c[1]; } } // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } } } }, // 雷达图默认参数 radar : { polarIndex: 0, itemStyle: { normal: { // color: 各异, label: { show: false }, lineStyle: { width: 2, type: 'solid' } }, emphasis: { // color: 各异, label: { show: false } } }, //symbol: null, // 拐点图形类型 symbolSize: 2 // 可计算特性参数,空数据拖拽提示图形大小 //symbolRotate : null, // 图形旋转控制 }, // 饼图默认参数 pie: { center : ['50%', '50%'], // 默认全局居中 radius : [0, '75%'], clockWise : true, // 默认顺时针 startAngle: 90, minAngle: 0, // 最小角度改为0 selectedOffset: 10, // 选中是扇区偏移量 // selectedMode: false, // 选择模式,默认关闭,可选single,multiple // roseType : null, // 南丁格尔玫瑰图模式,'radius'(半径) | 'area'(面积) itemStyle: { normal: { // color: 各异, borderColor: '#fff', borderWidth: 1, label: { show: true, position: 'outer' // formatter: 标签文本格式器,同Tooltip.formatter,不支持回调 // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, labelLine: { show: true, length: 20, lineStyle: { // color: 各异, width: 1, type: 'solid' } } }, emphasis: { // color: 各异, borderColor: 'rgba(0,0,0,0)', borderWidth: 1, label: { show: false // position: 'outer' // formatter: 标签文本格式器,同Tooltip.formatter,不支持回调 // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, labelLine: { show: false, length: 20, lineStyle: { // color: 各异, width: 1, type: 'solid' } } } } }, map: { mapType: 'china', // 各省的mapType暂时都用中文 mapLocation: { x : 'center', y : 'center' // width // 自适应 // height // 自适应 }, // mapValueCalculation: 'sum', // 数值合并方式,默认加和,可选为: // 'sum' | 'average' | 'max' | 'min' mapValuePrecision : 0, // 地图数值计算结果小数精度 showLegendSymbol : true, // 显示图例颜色标识(系列标识的小圆点),存在legend时生效 // selectedMode: false, // 选择模式,默认关闭,可选single,multiple hoverable: true, // roam : false, // 是否开启缩放及漫游模式 itemStyle: { normal: { // color: 各异, borderColor: '#fff', borderWidth: 1, areaStyle: { color: '#ccc' }, label: { show: false, textStyle: { color: 'rgb(139,69,19)' } } }, emphasis: { // 也是选中样式 // color: 各异, borderColor: 'rgba(0,0,0,0)', borderWidth: 1, areaStyle: { color: 'rgba(255,215,0,0.8)' }, label: { show: false, textStyle: { color: 'rgb(100,0,0)' } } } } }, force : { // 数据map到圆的半径的最小值和最大值 minRadius : 10, maxRadius : 20, density : 1.0, attractiveness : 1.0, // 初始化的随机大小位置 initSize : 300, // 向心力因子,越大向心力越大 centripetal : 1, // 冷却因子 coolDown : 0.99, // 分类里如果有样式会覆盖节点默认样式 categories : [], itemStyle: { normal: { // color: 各异, label: { show: false // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, nodeStyle : { brushType : 'both', color : '#f08c2e', strokeColor : '#5182ab' }, linkStyle : { strokeColor : '#5182ab' } }, emphasis: { // color: 各异, label: { show: false // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, nodeStyle : {}, linkStyle : {} } } }, chord : { radius : ['65%', '75%'], center : ['50%', '50%'], padding : 2, sort : 'none', // can be 'none', 'ascending', 'descending' sortSub : 'none', // can be 'none', 'ascending', 'descending' startAngle : 90, clockWise : false, showScale : false, showScaleText : false, itemStyle : { normal : { label : { show : true // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, lineStyle : { width : 0, color : '#000' }, chordStyle : { lineStyle : { width : 1, color : '#666' } } }, emphasis : { lineStyle : { width : 0, color : '#000' }, chordStyle : { lineStyle : { width : 2, color : '#333' } } } }, // Source data matrix /** * target * -1--2--3--4--5- * 1| x x x x x * 2| x x x x x * 3| x x x x x source * 4| x x x x x * 5| x x x x x * * Relation ship from source to target * https://github.com/mbostock/d3/wiki/Chord-Layout#wiki-chord * * Row based */ matrix : [] }, island: { r: 15, calculateStep: 0.1 // 滚轮可计算步长 0.1 = 10% }, markPoint : { symbol: 'pin', // 标注类型 symbolSize: 10, // 标注大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2 //symbolRotate : null, // 标注旋转控制 effect : { show: false, period: 15, // 运动周期,无单位,值越大越慢 scaleSize : 2 // 放大倍数,以markPoint点size为基准 // color : 'gold', // shadowColor : 'rgba(255,215,0,0.8)', // shadowBlur : 0 // 炫光模糊 }, itemStyle: { normal: { // color: 各异, // borderColor: 各异, // 标注边线颜色,优先于color borderWidth: 2, // 标注边线线宽,单位px,默认为1 label: { show: true, // 标签文本格式器,同Tooltip.formatter,不支持回调 // formatter : null, position: 'inside' // 可选为'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } }, emphasis: { // color: 各异 label: { show: true // 标签文本格式器,同Tooltip.formatter,不支持回调 // formatter : null, // position: 'inside' // 'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } } } }, markLine : { // 标线起始和结束的symbol介绍类型,如果都一样,可以直接传string symbol: ['circle', 'arrow'], // 标线起始和结束的symbol大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2 symbolSize: [2, 4], // 标线起始和结束的symbol旋转控制 //symbolRotate : null, //smooth : false, effect : { show: false, period: 15, // 运动周期,无单位,值越大越慢 scaleSize : 2 // 放大倍数,以markLine线lineWidth为基准 // color : 'gold', // shadowColor : 'rgba(255,215,0,0.8)', // shadowBlur : lineWidth * 2 // 炫光模糊,默认等于scaleSize计算所得 }, itemStyle: { normal: { // color: 各异, // 标线主色,线色,symbol主色 // borderColor: 随color, // 标线symbol边框颜色,优先于color borderWidth: 1.5, // 标线symbol边框线宽,单位px,默认为2 label: { show: true, // 标签文本格式器,同Tooltip.formatter,不支持回调 // formatter : null, // 可选为 'start'|'end'|'left'|'right'|'top'|'bottom' position: 'end' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, lineStyle: { // color: 随borderColor, // 主色,线色,优先级高于borderColor和color // width: 随borderWidth, // 优先于borderWidth type: 'dashed', shadowColor : 'rgba(0,0,0,0)', //默认透明 shadowBlur: 0, shadowOffsetX: 0, shadowOffsetY: 0 } }, emphasis: { // color: 各异 label: { show: false // 标签文本格式器,同Tooltip.formatter,不支持回调 // formatter : null, // position: 'inside' // 'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, lineStyle : {} } } }, // 主题,主题 textStyle: { decoration: 'none', fontFamily: 'Arial, Verdana, sans-serif', fontFamily2: '微软雅黑', // IE8- 字体模糊并且,不支持不同字体混排,额外指定一份 fontSize: 12, fontStyle: 'normal', fontWeight: 'normal' }, EVENT: { // -------全局通用 REFRESH: 'refresh', RESTORE: 'restore', RESIZE: 'resize', CLICK: 'click', HOVER: 'hover', //MOUSEWHEEL: 'mousewheel', // -------业务交互逻辑 DATA_CHANGED: 'dataChanged', DATA_ZOOM: 'dataZoom', DATA_RANGE: 'dataRange', LEGEND_SELECTED: 'legendSelected', MAP_SELECTED: 'mapSelected', PIE_SELECTED: 'pieSelected', MAGIC_TYPE_CHANGED: 'magicTypeChanged', DATA_VIEW_CHANGED: 'dataViewChanged', MAP_ROAM : 'mapRoam', // -------内部通信 TOOLTIP_HOVER: 'tooltipHover', TOOLTIP_IN_GRID: 'tooltipInGrid', TOOLTIP_OUT_GRID: 'tooltipOutGrid' }, DRAG_ENABLE_TIME : 150, // 降低图表内元素拖拽敏感度,单位ms,不建议外部干预 // 主题,默认标志图形类型列表 symbolList : [ 'circle', 'rectangle', 'triangle', 'diamond', 'emptyCircle', 'emptyRectangle', 'emptyTriangle', 'emptyDiamond' ], loadingText : 'Loading...', // 可计算特性配置,孤岛,提示颜色 calculable: false, // 默认关闭可计算特性 calculableColor: 'rgba(255,165,0,0.6)', // 拖拽提示边框颜色 calculableHolderColor: '#ccc', // 可计算占位提示颜色 nameConnector: ' & ', valueConnector: ' : ', animation: true, addDataAnimation: true, // 动态数据接口是否开启动画效果 animationThreshold: 2500, // 动画元素阀值,产生的图形原素超过2500不出动画 animationDuration: 2000, animationEasing: 'ExponentialOut' //BounceOut }; return config; }); /** * zrender: 向量操作类 * * author : lang(shenyi01@baidu.com) */ define( 'zrender/tool/vector',[],function() { var ArrayCtor = typeof Float32Array === 'undefined' ? Array : Float32Array; var vector = { create : function(x, y) { var out = new ArrayCtor(2); out[0] = x || 0; out[1] = y || 0; return out; }, copy : function(out, v) { out[0] = v[0]; out[1] = v[1]; }, set : function(out, a, b) { out[0] = a; out[1] = b; }, add : function(out, v1, v2) { out[0] = v1[0] + v2[0]; out[1] = v1[1] + v2[1]; return out; }, scaleAndAdd : function(out, v1, v2, a) { out[0] = v1[0] + v2[0] * a; out[1] = v1[1] + v2[1] * a; return out; }, sub : function(out, v1, v2) { out[0] = v1[0] - v2[0]; out[1] = v1[1] - v2[1]; return out; }, length : function(v) { return Math.sqrt(this.lengthSquare(v)); }, lengthSquare : function(v) { return v[0] * v[0] + v[1] * v[1]; }, mul : function(out, v1, v2) { out[0] = v1[0] * v2[0]; out[1] = v1[1] * v2[1]; return out; }, dot : function(v1, v2) { return v1[0] * v2[0] + v1[1] * v2[1]; }, scale : function(out, v, s) { out[0] = v[0] * s; out[1] = v[1] * s; return out; }, normalize : function(out, v) { var d = vector.length(v); if(d === 0){ out[0] = 0; out[1] = 0; }else{ out[0] = v[0]/d; out[1] = v[1]/d; } return out; }, distance : function(v1, v2) { return Math.sqrt( (v1[0] - v2[0]) * (v1[0] - v2[0]) + (v1[1] - v2[1]) * (v1[1] - v2[1]) ); }, negate : function(out, v) { out[0] = -v[0]; out[1] = -v[1]; }, middle : function(out, v1, v2) { out[0] = (v1[0] + v2[0])/2; out[1] = (v1[1] + v2[1])/2; return out; } }; return vector; } ); // Copyright 2006 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Known Issues: // // * Patterns only support repeat. // * Radial gradient are not implemented. The VML version of these look very // different from the canvas one. // * Clipping paths are not implemented. // * Coordsize. The width and height attribute have higher priority than the // width and height style values which isn't correct. // * Painting mode isn't implemented. // * Canvas width/height should is using content-box by default. IE in // Quirks mode will draw the canvas using border-box. Either change your // doctype to HTML5 // (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) // or use Box Sizing Behavior from WebFX // (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) // * Non uniform scaling does not correctly scale strokes. // * Optimize. There is always room for speed improvements. // AMD by kener.linfeng@gmail.com define('zrender/lib/excanvas',['require'],function(require) { // Only add this code if we do not already have a canvas implementation if (!document.createElement('canvas').getContext) { (function() { // alias some functions to make (compiled) code shorter var m = Math; var mr = m.round; var ms = m.sin; var mc = m.cos; var abs = m.abs; var sqrt = m.sqrt; // this is used for sub pixel precision var Z = 10; var Z2 = Z / 2; var IE_VERSION = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1]; /** * This funtion is assigned to the elements as element.getContext(). * @this {HTMLElement} * @return {CanvasRenderingContext2D_} */ function getContext() { return this.context_ || (this.context_ = new CanvasRenderingContext2D_(this)); } var slice = Array.prototype.slice; /** * Binds a function to an object. The returned function will always use the * passed in {@code obj} as {@code this}. * * Example: * * g = bind(f, obj, a, b) * g(c, d) // will do f.call(obj, a, b, c, d) * * @param {Function} f The function to bind the object to * @param {Object} obj The object that should act as this when the function * is called * @param {*} var_args Rest arguments that will be used as the initial * arguments when the function is called * @return {Function} A new function that has bound this */ function bind(f, obj, var_args) { var a = slice.call(arguments, 2); return function() { return f.apply(obj, a.concat(slice.call(arguments))); }; } function encodeHtmlAttribute(s) { return String(s).replace(/&/g, '&').replace(/"/g, '"'); } function addNamespace(doc, prefix, urn) { if (!doc.namespaces[prefix]) { doc.namespaces.add(prefix, urn, '#default#VML'); } } function addNamespacesAndStylesheet(doc) { addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml'); addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office'); // Setup default CSS. Only add one style sheet per document if (!doc.styleSheets['ex_canvas_']) { var ss = doc.createStyleSheet(); ss.owningElement.id = 'ex_canvas_'; ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + // default size is 300x150 in Gecko and Opera 'text-align:left;width:300px;height:150px}'; } } // Add namespaces and stylesheet at startup. addNamespacesAndStylesheet(document); var G_vmlCanvasManager_ = { init: function(opt_doc) { var doc = opt_doc || document; // Create a dummy element so that IE will allow canvas elements to be // recognized. doc.createElement('canvas'); doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); }, init_: function(doc) { // find all canvas elements var els = doc.getElementsByTagName('canvas'); for (var i = 0; i < els.length; i++) { this.initElement(els[i]); } }, /** * Public initializes a canvas element so that it can be used as canvas * element from now on. This is called automatically before the page is * loaded but if you are creating elements using createElement you need to * make sure this is called on the element. * @param {HTMLElement} el The canvas element to initialize. * @return {HTMLElement} the element that was created. */ initElement: function(el) { if (!el.getContext) { el.getContext = getContext; // Add namespaces and stylesheet to document of the element. addNamespacesAndStylesheet(el.ownerDocument); // Remove fallback content. There is no way to hide text nodes so we // just remove all childNodes. We could hide all elements and remove // text nodes but who really cares about the fallback content. el.innerHTML = ''; // do not use inline function because that will leak memory el.attachEvent('onpropertychange', onPropertyChange); el.attachEvent('onresize', onResize); var attrs = el.attributes; if (attrs.width && attrs.width.specified) { // TODO: use runtimeStyle and coordsize // el.getContext().setWidth_(attrs.width.nodeValue); el.style.width = attrs.width.nodeValue + 'px'; } else { el.width = el.clientWidth; } if (attrs.height && attrs.height.specified) { // TODO: use runtimeStyle and coordsize // el.getContext().setHeight_(attrs.height.nodeValue); el.style.height = attrs.height.nodeValue + 'px'; } else { el.height = el.clientHeight; } //el.getContext().setCoordsize_() } return el; } }; function onPropertyChange(e) { var el = e.srcElement; switch (e.propertyName) { case 'width': el.getContext().clearRect(); el.style.width = el.attributes.width.nodeValue + 'px'; // In IE8 this does not trigger onresize. el.firstChild.style.width = el.clientWidth + 'px'; break; case 'height': el.getContext().clearRect(); el.style.height = el.attributes.height.nodeValue + 'px'; el.firstChild.style.height = el.clientHeight + 'px'; break; } } function onResize(e) { var el = e.srcElement; if (el.firstChild) { el.firstChild.style.width = el.clientWidth + 'px'; el.firstChild.style.height = el.clientHeight + 'px'; } } G_vmlCanvasManager_.init(); // precompute "00" to "FF" var decToHex = []; for (var i = 0; i < 16; i++) { for (var j = 0; j < 16; j++) { decToHex[i * 16 + j] = i.toString(16) + j.toString(16); } } function createMatrixIdentity() { return [ [1, 0, 0], [0, 1, 0], [0, 0, 1] ]; } function matrixMultiply(m1, m2) { var result = createMatrixIdentity(); for (var x = 0; x < 3; x++) { for (var y = 0; y < 3; y++) { var sum = 0; for (var z = 0; z < 3; z++) { sum += m1[x][z] * m2[z][y]; } result[x][y] = sum; } } return result; } function copyState(o1, o2) { o2.fillStyle = o1.fillStyle; o2.lineCap = o1.lineCap; o2.lineJoin = o1.lineJoin; o2.lineWidth = o1.lineWidth; o2.miterLimit = o1.miterLimit; o2.shadowBlur = o1.shadowBlur; o2.shadowColor = o1.shadowColor; o2.shadowOffsetX = o1.shadowOffsetX; o2.shadowOffsetY = o1.shadowOffsetY; o2.strokeStyle = o1.strokeStyle; o2.globalAlpha = o1.globalAlpha; o2.font = o1.font; o2.textAlign = o1.textAlign; o2.textBaseline = o1.textBaseline; o2.arcScaleX_ = o1.arcScaleX_; o2.arcScaleY_ = o1.arcScaleY_; o2.lineScale_ = o1.lineScale_; } var colorData = { aliceblue: '#F0F8FF', antiquewhite: '#FAEBD7', aquamarine: '#7FFFD4', azure: '#F0FFFF', beige: '#F5F5DC', bisque: '#FFE4C4', black: '#000000', blanchedalmond: '#FFEBCD', blueviolet: '#8A2BE2', brown: '#A52A2A', burlywood: '#DEB887', cadetblue: '#5F9EA0', chartreuse: '#7FFF00', chocolate: '#D2691E', coral: '#FF7F50', cornflowerblue: '#6495ED', cornsilk: '#FFF8DC', crimson: '#DC143C', cyan: '#00FFFF', darkblue: '#00008B', darkcyan: '#008B8B', darkgoldenrod: '#B8860B', darkgray: '#A9A9A9', darkgreen: '#006400', darkgrey: '#A9A9A9', darkkhaki: '#BDB76B', darkmagenta: '#8B008B', darkolivegreen: '#556B2F', darkorange: '#FF8C00', darkorchid: '#9932CC', darkred: '#8B0000', darksalmon: '#E9967A', darkseagreen: '#8FBC8F', darkslateblue: '#483D8B', darkslategray: '#2F4F4F', darkslategrey: '#2F4F4F', darkturquoise: '#00CED1', darkviolet: '#9400D3', deeppink: '#FF1493', deepskyblue: '#00BFFF', dimgray: '#696969', dimgrey: '#696969', dodgerblue: '#1E90FF', firebrick: '#B22222', floralwhite: '#FFFAF0', forestgreen: '#228B22', gainsboro: '#DCDCDC', ghostwhite: '#F8F8FF', gold: '#FFD700', goldenrod: '#DAA520', grey: '#808080', greenyellow: '#ADFF2F', honeydew: '#F0FFF0', hotpink: '#FF69B4', indianred: '#CD5C5C', indigo: '#4B0082', ivory: '#FFFFF0', khaki: '#F0E68C', lavender: '#E6E6FA', lavenderblush: '#FFF0F5', lawngreen: '#7CFC00', lemonchiffon: '#FFFACD', lightblue: '#ADD8E6', lightcoral: '#F08080', lightcyan: '#E0FFFF', lightgoldenrodyellow: '#FAFAD2', lightgreen: '#90EE90', lightgrey: '#D3D3D3', lightpink: '#FFB6C1', lightsalmon: '#FFA07A', lightseagreen: '#20B2AA', lightskyblue: '#87CEFA', lightslategray: '#778899', lightslategrey: '#778899', lightsteelblue: '#B0C4DE', lightyellow: '#FFFFE0', limegreen: '#32CD32', linen: '#FAF0E6', magenta: '#FF00FF', mediumaquamarine: '#66CDAA', mediumblue: '#0000CD', mediumorchid: '#BA55D3', mediumpurple: '#9370DB', mediumseagreen: '#3CB371', mediumslateblue: '#7B68EE', mediumspringgreen: '#00FA9A', mediumturquoise: '#48D1CC', mediumvioletred: '#C71585', midnightblue: '#191970', mintcream: '#F5FFFA', mistyrose: '#FFE4E1', moccasin: '#FFE4B5', navajowhite: '#FFDEAD', oldlace: '#FDF5E6', olivedrab: '#6B8E23', orange: '#FFA500', orangered: '#FF4500', orchid: '#DA70D6', palegoldenrod: '#EEE8AA', palegreen: '#98FB98', paleturquoise: '#AFEEEE', palevioletred: '#DB7093', papayawhip: '#FFEFD5', peachpuff: '#FFDAB9', peru: '#CD853F', pink: '#FFC0CB', plum: '#DDA0DD', powderblue: '#B0E0E6', rosybrown: '#BC8F8F', royalblue: '#4169E1', saddlebrown: '#8B4513', salmon: '#FA8072', sandybrown: '#F4A460', seagreen: '#2E8B57', seashell: '#FFF5EE', sienna: '#A0522D', skyblue: '#87CEEB', slateblue: '#6A5ACD', slategray: '#708090', slategrey: '#708090', snow: '#FFFAFA', springgreen: '#00FF7F', steelblue: '#4682B4', tan: '#D2B48C', thistle: '#D8BFD8', tomato: '#FF6347', turquoise: '#40E0D0', violet: '#EE82EE', wheat: '#F5DEB3', whitesmoke: '#F5F5F5', yellowgreen: '#9ACD32' }; function getRgbHslContent(styleString) { var start = styleString.indexOf('(', 3); var end = styleString.indexOf(')', start + 1); var parts = styleString.substring(start + 1, end).split(','); // add alpha if needed if (parts.length != 4 || styleString.charAt(3) != 'a') { parts[3] = 1; } return parts; } function percent(s) { return parseFloat(s) / 100; } function clamp(v, min, max) { return Math.min(max, Math.max(min, v)); } function hslToRgb(parts){ var r, g, b, h, s, l; h = parseFloat(parts[0]) / 360 % 360; if (h < 0) h++; s = clamp(percent(parts[1]), 0, 1); l = clamp(percent(parts[2]), 0, 1); if (s == 0) { r = g = b = l; // achromatic } else { var q = l < 0.5 ? l * (1 + s) : l + s - l * s; var p = 2 * l - q; r = hueToRgb(p, q, h + 1 / 3); g = hueToRgb(p, q, h); b = hueToRgb(p, q, h - 1 / 3); } return '#' + decToHex[Math.floor(r * 255)] + decToHex[Math.floor(g * 255)] + decToHex[Math.floor(b * 255)]; } function hueToRgb(m1, m2, h) { if (h < 0) h++; if (h > 1) h--; if (6 * h < 1) return m1 + (m2 - m1) * 6 * h; else if (2 * h < 1) return m2; else if (3 * h < 2) return m1 + (m2 - m1) * (2 / 3 - h) * 6; else return m1; } var processStyleCache = {}; function processStyle(styleString) { if (styleString in processStyleCache) { return processStyleCache[styleString]; } var str, alpha = 1; styleString = String(styleString); if (styleString.charAt(0) == '#') { str = styleString; } else if (/^rgb/.test(styleString)) { var parts = getRgbHslContent(styleString); var str = '#', n; for (var i = 0; i < 3; i++) { if (parts[i].indexOf('%') != -1) { n = Math.floor(percent(parts[i]) * 255); } else { n = +parts[i]; } str += decToHex[clamp(n, 0, 255)]; } alpha = +parts[3]; } else if (/^hsl/.test(styleString)) { var parts = getRgbHslContent(styleString); str = hslToRgb(parts); alpha = parts[3]; } else { str = colorData[styleString] || styleString; } return processStyleCache[styleString] = {color: str, alpha: alpha}; } var DEFAULT_STYLE = { style: 'normal', variant: 'normal', weight: 'normal', size: 12, //10 family: '微软雅黑' //'sans-serif' }; // Internal text style cache var fontStyleCache = {}; function processFontStyle(styleString) { if (fontStyleCache[styleString]) { return fontStyleCache[styleString]; } var el = document.createElement('div'); var style = el.style; var fontFamily; try { style.font = styleString; fontFamily = style.fontFamily.split(',')[0]; } catch (ex) { // Ignore failures to set to invalid font. } return fontStyleCache[styleString] = { style: style.fontStyle || DEFAULT_STYLE.style, variant: style.fontVariant || DEFAULT_STYLE.variant, weight: style.fontWeight || DEFAULT_STYLE.weight, size: style.fontSize || DEFAULT_STYLE.size, family: fontFamily || DEFAULT_STYLE.family }; } function getComputedStyle(style, element) { var computedStyle = {}; for (var p in style) { computedStyle[p] = style[p]; } // Compute the size var canvasFontSize = parseFloat(element.currentStyle.fontSize), fontSize = parseFloat(style.size); if (typeof style.size == 'number') { computedStyle.size = style.size; } else if (style.size.indexOf('px') != -1) { computedStyle.size = fontSize; } else if (style.size.indexOf('em') != -1) { computedStyle.size = canvasFontSize * fontSize; } else if(style.size.indexOf('%') != -1) { computedStyle.size = (canvasFontSize / 100) * fontSize; } else if (style.size.indexOf('pt') != -1) { computedStyle.size = fontSize / .75; } else { computedStyle.size = canvasFontSize; } // Different scaling between normal text and VML text. This was found using // trial and error to get the same size as non VML text. //computedStyle.size *= 0.981; return computedStyle; } function buildStyle(style) { return style.style + ' ' + style.variant + ' ' + style.weight + ' ' + style.size + "px '" + style.family + "'"; } var lineCapMap = { 'butt': 'flat', 'round': 'round' }; function processLineCap(lineCap) { return lineCapMap[lineCap] || 'square'; } /** * This class implements CanvasRenderingContext2D interface as described by * the WHATWG. * @param {HTMLElement} canvasElement The element that the 2D context should * be associated with */ function CanvasRenderingContext2D_(canvasElement) { this.m_ = createMatrixIdentity(); this.mStack_ = []; this.aStack_ = []; this.currentPath_ = []; // Canvas context properties this.strokeStyle = '#000'; this.fillStyle = '#000'; this.lineWidth = 1; this.lineJoin = 'miter'; this.lineCap = 'butt'; this.miterLimit = Z * 1; this.globalAlpha = 1; // this.font = '10px sans-serif'; this.font = '12px 微软雅黑'; // 决定还是改这吧,影响代价最小 this.textAlign = 'left'; this.textBaseline = 'alphabetic'; this.canvas = canvasElement; var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' + canvasElement.clientHeight + 'px;overflow:hidden;position:absolute'; var el = canvasElement.ownerDocument.createElement('div'); el.style.cssText = cssText; canvasElement.appendChild(el); var overlayEl = el.cloneNode(false); // Use a non transparent background. overlayEl.style.backgroundColor = '#fff'; //red, I don't know why, it work! overlayEl.style.filter = 'alpha(opacity=0)'; canvasElement.appendChild(overlayEl); this.element_ = el; this.arcScaleX_ = 1; this.arcScaleY_ = 1; this.lineScale_ = 1; } var contextPrototype = CanvasRenderingContext2D_.prototype; contextPrototype.clearRect = function() { if (this.textMeasureEl_) { this.textMeasureEl_.removeNode(true); this.textMeasureEl_ = null; } this.element_.innerHTML = ''; }; contextPrototype.beginPath = function() { // TODO: Branch current matrix so that save/restore has no effect // as per safari docs. this.currentPath_ = []; }; contextPrototype.moveTo = function(aX, aY) { var p = getCoords(this, aX, aY); this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); this.currentX_ = p.x; this.currentY_ = p.y; }; contextPrototype.lineTo = function(aX, aY) { var p = getCoords(this, aX, aY); this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); this.currentX_ = p.x; this.currentY_ = p.y; }; contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { var p = getCoords(this, aX, aY); var cp1 = getCoords(this, aCP1x, aCP1y); var cp2 = getCoords(this, aCP2x, aCP2y); bezierCurveTo(this, cp1, cp2, p); }; // Helper function that takes the already fixed cordinates. function bezierCurveTo(self, cp1, cp2, p) { self.currentPath_.push({ type: 'bezierCurveTo', cp1x: cp1.x, cp1y: cp1.y, cp2x: cp2.x, cp2y: cp2.y, x: p.x, y: p.y }); self.currentX_ = p.x; self.currentY_ = p.y; } contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { // the following is lifted almost directly from // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes var cp = getCoords(this, aCPx, aCPy); var p = getCoords(this, aX, aY); var cp1 = { x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) }; var cp2 = { x: cp1.x + (p.x - this.currentX_) / 3.0, y: cp1.y + (p.y - this.currentY_) / 3.0 }; bezierCurveTo(this, cp1, cp2, p); }; contextPrototype.arc = function(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { aRadius *= Z; var arcType = aClockwise ? 'at' : 'wa'; var xStart = aX + mc(aStartAngle) * aRadius - Z2; var yStart = aY + ms(aStartAngle) * aRadius - Z2; var xEnd = aX + mc(aEndAngle) * aRadius - Z2; var yEnd = aY + ms(aEndAngle) * aRadius - Z2; // IE won't render arches drawn counter clockwise if xStart == xEnd. if (xStart == xEnd && !aClockwise) { xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something // that can be represented in binary } var p = getCoords(this, aX, aY); var pStart = getCoords(this, xStart, yStart); var pEnd = getCoords(this, xEnd, yEnd); this.currentPath_.push({type: arcType, x: p.x, y: p.y, radius: aRadius, xStart: pStart.x, yStart: pStart.y, xEnd: pEnd.x, yEnd: pEnd.y}); }; contextPrototype.rect = function(aX, aY, aWidth, aHeight) { this.moveTo(aX, aY); this.lineTo(aX + aWidth, aY); this.lineTo(aX + aWidth, aY + aHeight); this.lineTo(aX, aY + aHeight); this.closePath(); }; contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { var oldPath = this.currentPath_; this.beginPath(); this.moveTo(aX, aY); this.lineTo(aX + aWidth, aY); this.lineTo(aX + aWidth, aY + aHeight); this.lineTo(aX, aY + aHeight); this.closePath(); this.stroke(); this.currentPath_ = oldPath; }; contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { var oldPath = this.currentPath_; this.beginPath(); this.moveTo(aX, aY); this.lineTo(aX + aWidth, aY); this.lineTo(aX + aWidth, aY + aHeight); this.lineTo(aX, aY + aHeight); this.closePath(); this.fill(); this.currentPath_ = oldPath; }; contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { var gradient = new CanvasGradient_('gradient'); gradient.x0_ = aX0; gradient.y0_ = aY0; gradient.x1_ = aX1; gradient.y1_ = aY1; return gradient; }; contextPrototype.createRadialGradient = function(aX0, aY0, aR0, aX1, aY1, aR1) { var gradient = new CanvasGradient_('gradientradial'); gradient.x0_ = aX0; gradient.y0_ = aY0; gradient.r0_ = aR0; gradient.x1_ = aX1; gradient.y1_ = aY1; gradient.r1_ = aR1; return gradient; }; contextPrototype.drawImage = function(image, var_args) { var dx, dy, dw, dh, sx, sy, sw, sh; // to find the original width we overide the width and height var oldRuntimeWidth = image.runtimeStyle.width; var oldRuntimeHeight = image.runtimeStyle.height; image.runtimeStyle.width = 'auto'; image.runtimeStyle.height = 'auto'; // get the original size var w = image.width; var h = image.height; // and remove overides image.runtimeStyle.width = oldRuntimeWidth; image.runtimeStyle.height = oldRuntimeHeight; if (arguments.length == 3) { dx = arguments[1]; dy = arguments[2]; sx = sy = 0; sw = dw = w; sh = dh = h; } else if (arguments.length == 5) { dx = arguments[1]; dy = arguments[2]; dw = arguments[3]; dh = arguments[4]; sx = sy = 0; sw = w; sh = h; } else if (arguments.length == 9) { sx = arguments[1]; sy = arguments[2]; sw = arguments[3]; sh = arguments[4]; dx = arguments[5]; dy = arguments[6]; dw = arguments[7]; dh = arguments[8]; } else { throw Error('Invalid number of arguments'); } var d = getCoords(this, dx, dy); var w2 = sw / 2; var h2 = sh / 2; var vmlStr = []; var W = 10; var H = 10; var scaleX = scaleY = 1; // For some reason that I've now forgotten, using divs didn't work vmlStr.push(' '); // Draw a special cropping div if needed if (sx || sy) { // Apply scales to width and height vmlStr.push('
'); } // Apply scales to width and height vmlStr.push('
'); // Close the crop div if necessary if (sx || sy) vmlStr.push('
'); vmlStr.push('
'); this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join('')); }; contextPrototype.stroke = function(aFill) { var lineStr = []; var lineOpen = false; var W = 10; var H = 10; lineStr.push(''); if (!aFill) { appendStroke(this, lineStr); } else { appendFill(this, lineStr, min, max); } lineStr.push(''); this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); }; function appendStroke(ctx, lineStr) { var a = processStyle(ctx.strokeStyle); var color = a.color; var opacity = a.alpha * ctx.globalAlpha; var lineWidth = ctx.lineScale_ * ctx.lineWidth; // VML cannot correctly render a line if the width is less than 1px. // In that case, we dilute the color to make the line look thinner. if (lineWidth < 1) { opacity *= lineWidth; } lineStr.push( '' ); } function appendFill(ctx, lineStr, min, max) { var fillStyle = ctx.fillStyle; var arcScaleX = ctx.arcScaleX_; var arcScaleY = ctx.arcScaleY_; var width = max.x - min.x; var height = max.y - min.y; if (fillStyle instanceof CanvasGradient_) { // TODO: Gradients transformed with the transformation matrix. var angle = 0; var focus = {x: 0, y: 0}; // additional offset var shift = 0; // scale factor for offset var expansion = 1; if (fillStyle.type_ == 'gradient') { var x0 = fillStyle.x0_ / arcScaleX; var y0 = fillStyle.y0_ / arcScaleY; var x1 = fillStyle.x1_ / arcScaleX; var y1 = fillStyle.y1_ / arcScaleY; var p0 = getCoords(ctx, x0, y0); var p1 = getCoords(ctx, x1, y1); var dx = p1.x - p0.x; var dy = p1.y - p0.y; angle = Math.atan2(dx, dy) * 180 / Math.PI; // The angle should be a non-negative number. if (angle < 0) { angle += 360; } // Very small angles produce an unexpected result because they are // converted to a scientific notation string. if (angle < 1e-6) { angle = 0; } } else { var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_); focus = { x: (p0.x - min.x) / width, y: (p0.y - min.y) / height }; width /= arcScaleX * Z; height /= arcScaleY * Z; var dimension = m.max(width, height); shift = 2 * fillStyle.r0_ / dimension; expansion = 2 * fillStyle.r1_ / dimension - shift; } // We need to sort the color stops in ascending order by offset, // otherwise IE won't interpret it correctly. var stops = fillStyle.colors_; stops.sort(function(cs1, cs2) { return cs1.offset - cs2.offset; }); var length = stops.length; var color1 = stops[0].color; var color2 = stops[length - 1].color; var opacity1 = stops[0].alpha * ctx.globalAlpha; var opacity2 = stops[length - 1].alpha * ctx.globalAlpha; var colors = []; for (var i = 0; i < length; i++) { var stop = stops[i]; colors.push(stop.offset * expansion + shift + ' ' + stop.color); } // When colors attribute is used, the meanings of opacity and o:opacity2 // are reversed. lineStr.push(''); } else if (fillStyle instanceof CanvasPattern_) { if (width && height) { var deltaLeft = -min.x; var deltaTop = -min.y; lineStr.push(''); } } else { var a = processStyle(ctx.fillStyle); var color = a.color; var opacity = a.alpha * ctx.globalAlpha; lineStr.push(''); } } contextPrototype.fill = function() { this.stroke(true); }; contextPrototype.closePath = function() { this.currentPath_.push({type: 'close'}); }; function getCoords(ctx, aX, aY) { var m = ctx.m_; return { x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 }; }; contextPrototype.save = function() { var o = {}; copyState(this, o); this.aStack_.push(o); this.mStack_.push(this.m_); this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); }; contextPrototype.restore = function() { if (this.aStack_.length) { copyState(this.aStack_.pop(), this); this.m_ = this.mStack_.pop(); } }; function matrixIsFinite(m) { return isFinite(m[0][0]) && isFinite(m[0][1]) && isFinite(m[1][0]) && isFinite(m[1][1]) && isFinite(m[2][0]) && isFinite(m[2][1]); } function setM(ctx, m, updateLineScale) { if (!matrixIsFinite(m)) { return; } ctx.m_ = m; if (updateLineScale) { // Get the line scale. // Determinant of this.m_ means how much the area is enlarged by the // transformation. So its square root can be used as a scale factor // for width. var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; ctx.lineScale_ = sqrt(abs(det)); } } contextPrototype.translate = function(aX, aY) { var m1 = [ [1, 0, 0], [0, 1, 0], [aX, aY, 1] ]; setM(this, matrixMultiply(m1, this.m_), false); }; contextPrototype.rotate = function(aRot) { var c = mc(aRot); var s = ms(aRot); var m1 = [ [c, s, 0], [-s, c, 0], [0, 0, 1] ]; setM(this, matrixMultiply(m1, this.m_), false); }; contextPrototype.scale = function(aX, aY) { this.arcScaleX_ *= aX; this.arcScaleY_ *= aY; var m1 = [ [aX, 0, 0], [0, aY, 0], [0, 0, 1] ]; setM(this, matrixMultiply(m1, this.m_), true); }; contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) { var m1 = [ [m11, m12, 0], [m21, m22, 0], [dx, dy, 1] ]; setM(this, matrixMultiply(m1, this.m_), true); }; contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) { var m = [ [m11, m12, 0], [m21, m22, 0], [dx, dy, 1] ]; setM(this, m, true); }; /** * The text drawing function. * The maxWidth argument isn't taken in account, since no browser supports * it yet. */ contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) { var m = this.m_, delta = 1000, left = 0, right = delta, offset = {x: 0, y: 0}, lineStr = []; var fontStyle = getComputedStyle(processFontStyle(this.font), this.element_); var fontStyleString = buildStyle(fontStyle); var elementStyle = this.element_.currentStyle; var textAlign = this.textAlign.toLowerCase(); switch (textAlign) { case 'left': case 'center': case 'right': break; case 'end': textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left'; break; case 'start': textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left'; break; default: textAlign = 'left'; } // 1.75 is an arbitrary number, as there is no info about the text baseline switch (this.textBaseline) { case 'hanging': case 'top': offset.y = fontStyle.size / 1.75; break; case 'middle': break; default: case null: case 'alphabetic': case 'ideographic': case 'bottom': offset.y = -fontStyle.size / 2.25; break; } switch(textAlign) { case 'right': left = delta; right = 0.05; break; case 'center': left = right = delta / 2; break; } var d = getCoords(this, x + offset.x, y + offset.y); lineStr.push(''); if (stroke) { appendStroke(this, lineStr); } else { // TODO: Fix the min and max params. appendFill(this, lineStr, {x: -left, y: 0}, {x: right, y: fontStyle.size}); } var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' + m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0'; var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z); lineStr.push('', '', ''); this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); }; contextPrototype.fillText = function(text, x, y, maxWidth) { this.drawText_(text, x, y, maxWidth, false); }; contextPrototype.strokeText = function(text, x, y, maxWidth) { this.drawText_(text, x, y, maxWidth, true); }; contextPrototype.measureText = function(text) { if (!this.textMeasureEl_) { var s = ''; this.element_.insertAdjacentHTML('beforeEnd', s); this.textMeasureEl_ = this.element_.lastChild; } var doc = this.element_.ownerDocument; this.textMeasureEl_.innerHTML = ''; this.textMeasureEl_.style.font = this.font; // Don't use innerHTML or innerText because they allow markup/whitespace. this.textMeasureEl_.appendChild(doc.createTextNode(text)); return {width: this.textMeasureEl_.offsetWidth}; }; /******** STUBS ********/ contextPrototype.clip = function() { // TODO: Implement }; contextPrototype.arcTo = function() { // TODO: Implement }; contextPrototype.createPattern = function(image, repetition) { return new CanvasPattern_(image, repetition); }; // Gradient / Pattern Stubs function CanvasGradient_(aType) { this.type_ = aType; this.x0_ = 0; this.y0_ = 0; this.r0_ = 0; this.x1_ = 0; this.y1_ = 0; this.r1_ = 0; this.colors_ = []; } CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { aColor = processStyle(aColor); this.colors_.push({offset: aOffset, color: aColor.color, alpha: aColor.alpha}); }; function CanvasPattern_(image, repetition) { assertImageIsValid(image); switch (repetition) { case 'repeat': case null: case '': this.repetition_ = 'repeat'; break case 'repeat-x': case 'repeat-y': case 'no-repeat': this.repetition_ = repetition; break; default: throwException('SYNTAX_ERR'); } this.src_ = image.src; this.width_ = image.width; this.height_ = image.height; } function throwException(s) { throw new DOMException_(s); } function assertImageIsValid(img) { if (!img || img.nodeType != 1 || img.tagName != 'IMG') { throwException('TYPE_MISMATCH_ERR'); } if (img.readyState != 'complete') { throwException('INVALID_STATE_ERR'); } } function DOMException_(s) { this.code = this[s]; this.message = s +': DOM Exception ' + this.code; } var p = DOMException_.prototype = new Error; p.INDEX_SIZE_ERR = 1; p.DOMSTRING_SIZE_ERR = 2; p.HIERARCHY_REQUEST_ERR = 3; p.WRONG_DOCUMENT_ERR = 4; p.INVALID_CHARACTER_ERR = 5; p.NO_DATA_ALLOWED_ERR = 6; p.NO_MODIFICATION_ALLOWED_ERR = 7; p.NOT_FOUND_ERR = 8; p.NOT_SUPPORTED_ERR = 9; p.INUSE_ATTRIBUTE_ERR = 10; p.INVALID_STATE_ERR = 11; p.SYNTAX_ERR = 12; p.INVALID_MODIFICATION_ERR = 13; p.NAMESPACE_ERR = 14; p.INVALID_ACCESS_ERR = 15; p.VALIDATION_ERR = 16; p.TYPE_MISMATCH_ERR = 17; // set up externs G_vmlCanvasManager = G_vmlCanvasManager_; CanvasRenderingContext2D = CanvasRenderingContext2D_; CanvasGradient = CanvasGradient_; CanvasPattern = CanvasPattern_; DOMException = DOMException_; })(); } // if else { // make the canvas test simple by kener.linfeng@gmail.com G_vmlCanvasManager = false; } return G_vmlCanvasManager; }); // define; /** * zrender: 公共辅助函数 * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * clone:深度克隆 * merge:合并源对象的属性到目标对象 * getContext:获取一个自由使用的canvas 2D context,使用原生方法,如isPointInPath,measureText等 */ define( 'zrender/tool/util',['require','./vector','../lib/excanvas'],function(require) { var vec2 = require('./vector'); /** * 对一个object进行深度拷贝 * * @param {Any} source 需要进行拷贝的对象 * @return {Any} 拷贝后的新对象 */ function clone(source) { // buildInObject, 用于处理无法遍历Date等对象的问题 var buildInObject = { '[object Function]': 1, '[object RegExp]': 1, '[object Date]': 1, '[object Error]': 1, '[object CanvasGradient]': 1 }; var result = source; var i; var len; if (!source || source instanceof Number || source instanceof String || source instanceof Boolean ) { return result; } else if (source instanceof Array) { result = []; var resultLen = 0; for (i = 0, len = source.length; i < len; i++) { result[resultLen++] = this.clone(source[i]); } } else if ('object' == typeof source) { if(buildInObject[Object.prototype.toString.call(source)] || source.__nonRecursion ) { return result; } result = {}; for (i in source) { if (source.hasOwnProperty(i)) { result[i] = this.clone(source[i]); } } } return result; } /** * 合并源对象的属性到目标对象 * modify from Tangram * @param {*} target 目标对象 * @param {*} source 源对象 * @param {Object} optOptions 选项 * @param {boolean} optOptions.overwrite 是否覆盖 * @param {boolean} optOptions.recursive 是否递归 * @param {boolean} optOptions.whiteList 白名单,如果定义,则仅处理白名单属性 */ var merge = (function() { // buildInObject, 用于处理无法遍历Date等对象的问题 var buildInObject = { '[object Function]': 1, '[object RegExp]': 1, '[object Date]': 1, '[object Error]': 1, '[object CanvasGradient]': 1 }; function mergeItem(target, source, index, overwrite, recursive) { if (source.hasOwnProperty(index)) { if (recursive && typeof target[index] == 'object' && buildInObject[ Object.prototype.toString.call(target[index]) ] != 1 ) { // 如果需要递归覆盖,就递归调用merge merge( target[index], source[index], { 'overwrite': overwrite, 'recursive': recursive } ); } else if (overwrite || !(index in target)) { // 否则只处理overwrite为true,或者在目标对象中没有此属性的情况 target[index] = source[index]; } } } return function(target, source, optOptions){ var i = 0; var options = optOptions || {}; var overwrite = options['overwrite']; var whiteList = options['whiteList']; var recursive = options['recursive']; var len; // 只处理在白名单中的属性 if (whiteList && whiteList.length) { len = whiteList.length; for (; i < len; ++i) { mergeItem( target, source, whiteList[i], overwrite, recursive ); } } else { for (i in source) { mergeItem(target, source, i, overwrite, recursive); } } return target; }; })(); /** * 简化版的merge操作,舍去很多判断 * @param {*} target * @param {*} source * @param {boolean} overwrite * @param {boolean} recursive */ function mergeFast(target, source, overwrite, recursive) { if (!target || !source) { return; } if (source instanceof Object) { for (var name in source) { if (source.hasOwnProperty(name)) { if ( source[name] instanceof Object && recursive && target[name] ) { mergeFast( target[name], source[name], overwrite, recursive ); } else { if ( overwrite || !target.hasOwnProperty(name) ) { target[name] = source[name]; } } } } } } var _ctx; function getContext() { if (!_ctx) { require('../lib/excanvas'); if (G_vmlCanvasManager) { var _div = document.createElement('div'); _div.style.position = 'absolute'; _div.style.top = '-1000px'; document.body.appendChild(_div); _ctx = G_vmlCanvasManager.initElement(_div) .getContext('2d'); } else { _ctx = document.createElement('canvas').getContext('2d'); } } return _ctx; } var _canvas; var _pixelCtx; var _width; var _height; var _offsetX = 0; var _offsetY = 0; /** * 获取像素拾取专用的上下文 * @return {Object} 上下文 */ function getPixelContext() { if (!_pixelCtx) { _canvas = document.createElement('canvas'); _width = _canvas.width; _height = _canvas.height; _pixelCtx = _canvas.getContext('2d'); } return _pixelCtx; } /** * 如果坐标处在_canvas外部,改变_canvas的大小 * @param {number} x : 横坐标 * @param {number} y : 纵坐标 * 注意 修改canvas的大小 需要重新设置translate */ function adjustCanvasSize(x, y) { // 每次加的长度 var _v = 100; var _flag = false; if (x + _offsetX > _width) { _width = x + _offsetX + _v; _canvas.width = _width; _flag = true; } if (y + _offsetY > _height) { _height = y + _offsetY + _v; _canvas.height = _height; _flag = true; } if (x < -_offsetX) { _offsetX = Math.ceil(-x / _v) * _v; _width += _offsetX; _canvas.width = _width; _flag = true; } if (y < -_offsetY) { _offsetY = Math.ceil(-y / _v) * _v; _height += _offsetY; _canvas.height = _height; _flag = true; } if (_flag) { _pixelCtx.translate(_offsetX, _offsetY); } } /** * 获取像素canvas的偏移量 * @return {Object} 偏移量 */ function getPixelOffset() { return { x : _offsetX, y : _offsetY }; } /** * 查询数组中元素的index */ function indexOf(array, value){ if (array.indexOf) { return array.indexOf(value); } for(var i = 0, len=array.length; i right) { right = p[0]; } if (p[1] < top) { top = p[1]; } if (p[1] > bottom) { bottom = p[1]; } } min[0] = left; min[1] = top; max[0] = right; max[1] = bottom; } /** * 计算三阶贝塞尔曲线的包围盒 * http://pissang.net/blog/?p=91 */ function computeCubeBezierBoundingBox(p0, p1, p2, p3, min, max) { var xDim = _computeCubeBezierExtremitiesDim( p0[0], p1[0], p2[0], p3[0] ); var yDim = _computeCubeBezierExtremitiesDim( p0[1], p1[1], p2[1], p3[1] ); xDim.push(p0[0], p3[0]); yDim.push(p0[1], p3[1]); var left = Math.min.apply(null, xDim); var right = Math.max.apply(null, xDim); var top = Math.min.apply(null, yDim); var bottom = Math.max.apply(null, yDim); min[0] = left; min[1] = top; max[0] = right; max[1] = bottom; } function _computeCubeBezierExtremitiesDim(p0, p1, p2, p3) { var extremities = []; var b = 6 * p2 - 12 * p1 + 6 * p0; var a = 9 * p1 + 3 * p3 - 3 * p0 - 9 * p2; var c = 3 * p1 - 3 * p0; var tmp = b * b - 4 * a * c; if (tmp > 0){ var tmpSqrt = Math.sqrt(tmp); var t1 = (-b + tmpSqrt) / (2 * a); var t2 = (-b - tmpSqrt) / (2 * a); extremities.push(t1, t2); } else if (tmp === 0) { extremities.push(-b / (2 * a)); } var result = []; for (var i = 0; i < extremities.length; i++) { var t = extremities[i]; if (Math.abs(2 * a * t + b) > 0.0001 && t < 1 && t > 0) { var ct = 1 - t; var val = ct * ct * ct * p0 + 3 * ct * ct * t * p1 + 3 * ct * t * t * p2 + t * t *t * p3; result.push(val); } } return result; } /** * 计算二阶贝塞尔曲线的包围盒 * http://pissang.net/blog/?p=91 */ function computeQuadraticBezierBoundingBox(p0, p1, p2, min, max) { // Find extremities, where derivative in x dim or y dim is zero var tmp = (p0[0] + p2[0] - 2 * p1[0]); // p1 is center of p0 and p2 in x dim var t1; if (tmp === 0) { t1 = 0.5; } else { t1 = (p0[0] - p1[0]) / tmp; } tmp = (p0[1] + p2[1] - 2 * p1[1]); // p1 is center of p0 and p2 in y dim var t2; if (tmp === 0) { t2 = 0.5; } else { t2 = (p0[1] - p1[1]) / tmp; } t1 = Math.max(Math.min(t1, 1), 0); t2 = Math.max(Math.min(t2, 1), 0); var ct1 = 1-t1; var ct2 = 1-t2; var x1 = ct1 * ct1 * p0[0] + 2 * ct1 * t1 * p1[0] + t1 * t1 * p2[0]; var y1 = ct1 * ct1 * p0[1] + 2 * ct1 * t1 * p1[1] + t1 * t1 * p2[1]; var x2 = ct2 * ct2 * p0[0] + 2 * ct2 * t2 * p1[0] + t2 * t2 * p2[0]; var y2 = ct2 * ct2 * p0[1] + 2 * ct2 * t2 * p1[1] + t2 * t2 * p2[1]; return computeBoundingBox( [p0.slice(), p2.slice(), [x1, y1], [x2, y2]], min, max ); } /** * 计算圆弧的包围盒 * http://pissang.net/blog/?p=91 */ var computeArcBoundingBox = (function(){ var start = []; var end = []; // At most 4 extremities var extremities = [[], [], [], []]; return function( center, radius, startAngle, endAngle, clockwise, min, max ) { clockwise = clockwise ? 1 : -1; start[0] = Math.cos(startAngle); start[1] = Math.sin(startAngle) * clockwise; vec2.scale(start, start, radius); vec2.add(start, start, center); end[0] = Math.cos(endAngle); end[1] = Math.sin(endAngle) * clockwise; vec2.scale(end, end, radius); vec2.add(end, end, center); startAngle = startAngle % (Math.PI * 2); if (startAngle < 0) { startAngle = startAngle + Math.PI * 2; } endAngle = endAngle % (Math.PI * 2); if (endAngle < 0) { endAngle = endAngle + Math.PI * 2; } if (startAngle > endAngle) { endAngle += Math.PI * 2; } var number = 0; for (var angle = 0; angle < endAngle; angle += Math.PI / 2) { if (angle > startAngle) { var extremity = extremities[number++]; extremity[0] = Math.cos(angle); extremity[1] = Math.sin(angle) * clockwise; vec2.scale(extremity, extremity, radius); vec2.add(extremity, extremity, center); } } var points = extremities.slice(0, number); points.push(start, end); computeBoundingBox(points, min, max); }; })(); return { clone : clone, merge : merge, mergeFast : mergeFast, getContext : getContext, getPixelContext : getPixelContext, getPixelOffset : getPixelOffset, adjustCanvasSize : adjustCanvasSize, computeBoundingBox : computeBoundingBox, computeCubeBezierBoundingBox : computeCubeBezierBoundingBox, computeQuadraticBezierBoundingBox : computeQuadraticBezierBoundingBox, computeArcBoundingBox : computeArcBoundingBox, indexOf : indexOf }; } ); /** * zrender: shape仓库 * * @desc zrender是一个轻量级的Canvas类库,MVC封装,数据驱动,提供类Dom事件模型。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define( 'zrender/shape',[],function(/*require*/) { var self = {}; var _shapeLibrary = {}; //shape库 /** * 定义图形实现 * @param {Object} name * @param {Object} clazz 图形实现 */ self.define = function(name, clazz) { _shapeLibrary[name] = clazz; return self; }; /** * 获取图形实现 * @param {Object} name */ self.get = function(name) { return _shapeLibrary[name]; }; return self; } ); /** * zrender: 图形空间辅助类 * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * isInside:是否在区域内部 * isOutside:是否在区域外部 * getTextWidth:测算单行文本宽度 */ define( 'zrender/tool/area',['require','../tool/util','../shape'],function(require) { var util = require('../tool/util'); var _ctx; /** * 包含判断 * @param {string} shapeClazz : 图形类 * @param {Object} area : 目标区域 * @param {number} x : 横坐标 * @param {number} y : 纵坐标 */ function isInside(shapeClazz, area, x, y) { if (!area || !shapeClazz) { // 无参数或不支持类型 return false; } var zoneType = shapeClazz.type; if (!_ctx) { _ctx = util.getContext(); } if (!_isInsideRectangle( area.__rect || shapeClazz.getRect(area), x, y ) ) { // 不在矩形区域内直接返回false return false; } // 未实现或不可用时(excanvas不支持)则数学运算,主要是line,brokenLine,ring var _mathReturn = _mathMethod(zoneType, area, x, y); if (typeof _mathReturn != 'undefined') { return _mathReturn; } if (zoneType != 'beziercurve' && shapeClazz.buildPath && _ctx.isPointInPath ) { return _buildPathMethod(shapeClazz, _ctx, area, x, y); } else if (_ctx.getImageData) { return _pixelMethod(shapeClazz, area, x, y); } // 上面的方法都行不通时 switch (zoneType) { //心形----------------------10 case 'heart': return true; // Todo,不精确 //水滴----------------------11 case 'droplet': return true; // Todo,不精确 case 'ellipse': return true; // Todo,不精确 // 旋轮曲线 不准确 case 'trochoid': var _r = area.location == 'out' ? area.r1 + area.r2 + area.d : area.r1 - area.r2 + area.d; return _isInsideCircle(area, x, y, _r); // 玫瑰线 不准确 case 'rose' : return _isInsideCircle(area, x, y, area.maxr); //路径,椭圆,曲线等-----------------13 default: return false; // Todo,暂不支持 } } /** * 用数学方法判断,三个方法中最快,但是支持的shape少 * * @param {string} zoneType : 图形类型 * @param {Object} area :目标区域 * @param {number} x : 横坐标 * @param {number} y : 纵坐标 * @return {boolean=} true表示坐标处在图形中 */ function _mathMethod(zoneType, area, x, y) { // 在矩形内则部分图形需要进一步判断 switch (zoneType) { //线-----------------------1 case 'line': return _isInsideLine(area, x, y); //折线----------------------2 case 'brokenLine': return _isInsideBrokenLine(area, x, y); //文本----------------------3 case 'text': return true; //圆环----------------------4 case 'ring': return _isInsideRing(area, x, y); //矩形----------------------5 case 'rectangle': return true; //圆形----------------------6 case 'circle': return _isInsideCircle(area, x, y, area.r); //扇形----------------------7 case 'sector': return _isInsideSector(area, x, y); //多边形---------------------8 case 'path': return _isInsidePath(area, x, y); case 'polygon': case 'star': case 'isogon': return _isInsidePolygon(area, x, y); //图片----------------------9 case 'image': return true; } } /** * 通过buildPath方法来判断,三个方法中较快,但是不支持线条类型的shape, * 而且excanvas不支持isPointInPath方法 * * @param {Object} shapeClazz : shape类 * @param {Object} context : 上下文 * @param {Object} area :目标区域 * @param {number} x : 横坐标 * @param {number} y : 纵坐标 * @return {boolean} true表示坐标处在图形中 */ function _buildPathMethod(shapeClazz, context, area, x, y) { // 图形类实现路径创建了则用类的path context.beginPath(); shapeClazz.buildPath(context, area); context.closePath(); return context.isPointInPath(x, y); } /** * 通过像素值来判断,三个方法中最慢,但是支持广,不足之处是excanvas不支持像素处理 * * @param {Object} shapeClazz : shape类 * @param {Object} area :目标区域 * @param {number} x : 横坐标 * @param {number} y : 纵坐标 * @return {boolean} true表示坐标处在图形中 */ function _pixelMethod(shapeClazz, area, x, y) { var _rect = area.__rect || shapeClazz.getRect(area); var _context = util.getPixelContext(); var _offset = util.getPixelOffset(); util.adjustCanvasSize(x, y); _context.clearRect(_rect.x, _rect.y, _rect.width, _rect.height); _context.beginPath(); shapeClazz.brush(_context, {style : area}); _context.closePath(); return _isPainted(_context, x + _offset.x, y + _offset.y); } /** * 坐标像素值,判断坐标是否被作色 * * @param {Object} context : 上下文 * @param {number} x : 横坐标 * @param {number} y : 纵坐标 * @param {number=} unit : 触发的精度,越大越容易触发,可选,缺省是为1 * @return {boolean} 已经被画过返回true */ function _isPainted(context, x, y, unit) { var pixelsData; if (typeof unit != 'undefined') { unit = Math.floor((unit || 1 )/ 2); pixelsData = context.getImageData( x - unit, y - unit, unit + unit, unit + unit ).data; } else { pixelsData = context.getImageData(x, y, 1, 1).data; } var len = pixelsData.length; while (len--) { if (pixelsData[len] !== 0) { return true; } } return false; } /** * !isInside */ function isOutside(shapeClazz, area, x, y) { return !isInside(shapeClazz, area, x, y); } /** * 线段包含判断 */ function _isInsideLine(area, x, y) { var _x1 = area.xStart; var _y1 = area.yStart; var _x2 = area.xEnd; var _y2 = area.yEnd; var _l = Math.max(area.lineWidth, 5); var _a = 0; var _b = _x1; if (_x1 !== _x2) { _a = (_y1 - _y2) / (_x1 - _x2); _b = (_x1 * _y2 - _x2 * _y1) / (_x1 - _x2) ; } else { return Math.abs(x - _x1) <= _l / 2; } var _s = (_a * x - y + _b) * (_a * x - y + _b) / (_a * _a + 1); return _s <= _l / 2 * _l / 2; } function _isInsideBrokenLine(area, x, y) { var pointList = area.pointList; var lineArea; var insideCatch = false; for (var i = 0, l = pointList.length - 1; i < l; i++) { lineArea = { xStart : pointList[i][0], yStart : pointList[i][1], xEnd : pointList[i + 1][0], yEnd : pointList[i + 1][1], lineWidth : Math.max(area.lineWidth, 10) }; if (!_isInsideRectangle( { x : Math.min(lineArea.xStart, lineArea.xEnd) - lineArea.lineWidth, y : Math.min(lineArea.yStart, lineArea.yEnd) - lineArea.lineWidth, width : Math.abs(lineArea.xStart - lineArea.xEnd) + lineArea.lineWidth, height : Math.abs(lineArea.yStart - lineArea.yEnd) + lineArea.lineWidth }, x,y ) ) { // 不在矩形区内跳过 continue; } insideCatch = _isInsideLine(lineArea, x, y); if (insideCatch) { break; } } return insideCatch; } function _isInsideRing(area, x, y) { if (_isInsideCircle(area, x, y, area.r) && !_isInsideCircle( { x : area.x, y : area.y }, x, y, area.r0 || 0 ) ){ // 大圆内,小圆外 return true; } return false; } /** * 矩形包含判断 */ function _isInsideRectangle(area, x, y) { if (x >= area.x && x <= (area.x + area.width) && y >= area.y && y <= (area.y + area.height) ) { return true; } return false; } /** * 圆形包含判断 */ function _isInsideCircle(area, x, y, r) { return (x - area.x) * (x - area.x) + (y - area.y) * (y - area.y) < r * r; } /** * 扇形包含判断 */ function _isInsideSector(area, x, y) { if (!_isInsideCircle(area, x, y, area.r) || (area.r0 > 0 && _isInsideCircle( { x : area.x, y : area.y }, x, y, area.r0 ) ) ){ // 大圆外或者小圆内直接false return false; } else { // 判断夹角 if (Math.abs(area.endAngle - area.startAngle) >= 360) { // 大于360度的扇形,在环内就为true return true; } var angle = (360 - Math.atan2(y - area.y, x - area.x) / Math.PI * 180) % 360; var endA = (360 + area.endAngle) % 360; var startA = (360 + area.startAngle) % 360; if (endA > startA) { return (angle >= startA && angle <= endA); } else { return !(angle >= endA && angle <= startA); } } } /** * 多边形包含判断 * 警告:下面这段代码会很难看,建议跳过~ */ function _isInsidePolygon(area, x, y) { /** * 射线判别法 * 如果一个点在多边形内部,任意角度做射线肯定会与多边形要么有一个交点,要么有与多边形边界线重叠 * 如果一个点在多边形外部,任意角度做射线要么与多边形有一个交点, * 要么有两个交点,要么没有交点,要么有与多边形边界线重叠。 */ var i; var j; var polygon = area.pointList; var N = polygon.length; var inside = false; var redo = true; var v; for (i = 0; i < N; ++i) { // 是否在顶点上 if (polygon[i][0] == x && polygon[i][1] == y ) { redo = false; inside = true; break; } } if (redo) { redo = false; inside = false; for (i = 0,j = N - 1;i < N;j = i++) { if ((polygon[i][1] < y && y < polygon[j][1]) || (polygon[j][1] < y && y < polygon[i][1]) ) { if (x <= polygon[i][0] || x <= polygon[j][0]) { v = (y - polygon[i][1]) * (polygon[j][0] - polygon[i][0]) / (polygon[j][1] - polygon[i][1]) + polygon[i][0]; if (x < v) { // 在线的左侧 inside = !inside; } else if (x == v) { // 在线上 inside = true; break; } } } else if (y == polygon[i][1]) { if (x < polygon[i][0]) { // 交点在顶点上 polygon[i][1] > polygon[j][1] ? --y : ++y; //redo = true; break; } } else if (polygon[i][1] == polygon[j][1] // 在水平的边界线上 && y == polygon[i][1] && ((polygon[i][0] < x && x < polygon[j][0]) || (polygon[j][0] < x && x < polygon[i][0])) ) { inside = true; break; } } } return inside; } /** * 路径包含判断,依赖多边形判断 */ function _isInsidePath(area, x, y) { if (!area.pointList) { require('../shape').get('path').buildPath(_ctx, area); } var pointList = area.pointList; var insideCatch = false; for (var i = 0, l = pointList.length; i < l; i++) { insideCatch = _isInsidePolygon( { pointList : pointList[i] }, x, y ); if (insideCatch) { break; } } return insideCatch; } /** * 测算多行文本宽度 * @param {Object} text * @param {Object} textFont */ function getTextWidth(text, textFont) { if (!_ctx) { _ctx = util.getContext(); } _ctx.save(); if (textFont) { _ctx.font = textFont; } text = (text + '').split('\n'); var width = 0; for (var i = 0, l = text.length; i < l; i++) { width = Math.max( _ctx.measureText(text[i]).width, width ); } _ctx.restore(); return width; } /** * 测算多行文本高度 * @param {Object} text * @param {Object} textFont */ function getTextHeight(text, textFont) { if (!_ctx) { _ctx = util.getContext(); } _ctx.save(); if (textFont) { _ctx.font = textFont; } text = (text + '').split('\n'); //比较粗暴 var height = (_ctx.measureText('国').width + 2) * text.length; _ctx.restore(); return height; } return { isInside : isInside, isOutside : isOutside, getTextWidth : getTextWidth, getTextHeight : getTextHeight }; } ); /** * zrender: 3x2矩阵操作类 * * author: lang(shenyi01@baidu.com) * code from mat2d in http://glmatrix.net/ */ define( 'zrender/tool/matrix',[],function() { var matrix = { create : function() { return [1, 0, 0, 1, 0, 0]; }, identity : function(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 1; out[4] = 0; out[5] = 0; }, mul : function(out, m1, m2) { out[0] = m1[0] * m2[0] + m1[2] * m2[1]; out[1] = m1[1] * m2[0] + m1[3] * m2[1]; out[2] = m1[0] * m2[2] + m1[2] * m2[3]; out[3] = m1[1] * m2[2] + m1[3] * m2[3]; out[4] = m1[0] * m2[4] + m1[2] * m2[5] + m1[4]; out[5] = m1[1] * m2[4] + m1[3] * m2[5] + m1[5]; return out; }, translate : function(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; }, rotate : function(out, a, rad) { var aa = a[0], ac = a[2], atx = a[4]; var ab = a[1], ad = a[3], 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; }, scale : function(out, a, v) { var vx = v[0], 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; }, /** * 求逆矩阵 */ invert : function(out, a) { var aa = a[0], ac = a[2], atx = a[4]; var ab = a[1], ad = a[3], 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; }, /** * 矩阵左乘向量 */ mulVector : function(out, a, v) { var aa = a[0], ac = a[2], atx = a[4]; var ab = a[1], ad = a[3], aty = a[5]; out[0] = v[0] * aa + v[1] * ac + atx; out[1] = v[0] * ab + v[1] * ad + aty; return out; } }; return matrix; } ); /** * zrender : 颜色辅助类 * * author: CrossDo (chenhuaimu@baidu.com) * * getColor:获取色板颜色 * customPalette : 自定义调色板 * resetPalette : 重置调色板 * * getHighlightColor : 获取默认高亮颜色 * customHighlight : 自定义默认高亮颜色 * resetHighlight : 重置默认高亮颜色 * * getRadialGradient : 径向渐变 * getLinearGradient : 线性渐变 * getGradientColors : 获取颜色之间渐变颜色数组 * getStepColors : 获取两种颜色之间渐变颜色数组 * reverse : 颜色翻转 * mix : 颜色混合 * lift : 颜色升降 * trim : 清除空格 * random : 随机颜色 * toRGB : 转为RGB格式 * toRGBA : 转为RGBA格式 * toHex : 转为#RRGGBB格式 * toHSL : 转为HSL格式 * toHSLA : 转为HSLA格式 * toHSB : 转为HSB格式 * toHSBA : 转为HSBA格式 * toHSV : 转为HSV格式 * toHSVA : 转为HSVA格式 * toName : 转为颜色名字 * toColor: 颜色值数组转为指定格式颜色 * toArray: 返回颜色值数组 * alpha : 设置颜色的透明度 **/ define( 'zrender/tool/color',['require','../tool/util'],function(require) { var util = require('../tool/util'); var _ctx; // Color palette is an array containing the default colors for the chart's // series. // When all colors are used, new colors are selected from the start again. // Defaults to: // 默认色板 var palette = [ '#ff9277', ' #dddd00', ' #ffc877', ' #bbe3ff', ' #d5ffbb', '#bbbbff', ' #ddb000', ' #b0dd00', ' #e2bbff', ' #ffbbe3', '#ff7777', ' #ff9900', ' #83dd00', ' #77e3ff', ' #778fff', '#c877ff', ' #ff77ab', ' #ff6600', ' #aa8800', ' #77c7ff', '#ad77ff', ' #ff77ff', ' #dd0083', ' #777700', ' #00aa00', '#0088aa', ' #8400dd', ' #aa0088', ' #dd0000', ' #772e00' ]; var _palette = palette; var highlightColor = 'rgba(255,255,0,0.5)'; var _highlightColor = highlightColor; // 颜色格式 /*jshint maxlen: 330 */ var colorRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i; var _nameColors = { aliceblue : '#f0f8ff', antiquewhite : '#faebd7', aqua : '#0ff', aquamarine : '#7fffd4', azure : '#f0ffff', beige : '#f5f5dc', bisque : '#ffe4c4', black : '#000', blanchedalmond : '#ffebcd', blue : '#00f', blueviolet : '#8a2be2', brown : '#a52a2a', burlywood : '#deb887', cadetblue : '#5f9ea0', chartreuse : '#7fff00', chocolate : '#d2691e', coral : '#ff7f50', cornflowerblue : '#6495ed', cornsilk : '#fff8dc', crimson : '#dc143c', cyan : '#0ff', darkblue : '#00008b', darkcyan : '#008b8b', darkgoldenrod : '#b8860b', darkgray : '#a9a9a9', darkgrey : '#a9a9a9', darkgreen : '#006400', darkkhaki : '#bdb76b', darkmagenta : '#8b008b', darkolivegreen : '#556b2f', darkorange : '#ff8c00', darkorchid : '#9932cc', darkred : '#8b0000', darksalmon : '#e9967a', darkseagreen : '#8fbc8f', darkslateblue : '#483d8b', darkslategray : '#2f4f4f', darkslategrey : '#2f4f4f', darkturquoise : '#00ced1', darkviolet : '#9400d3', deeppink : '#ff1493', deepskyblue : '#00bfff', dimgray : '#696969', dimgrey : '#696969', dodgerblue : '#1e90ff', firebrick : '#b22222', floralwhite : '#fffaf0', forestgreen : '#228b22', fuchsia : '#f0f', gainsboro : '#dcdcdc', ghostwhite : '#f8f8ff', gold : '#ffd700', goldenrod : '#daa520', gray : '#808080', grey : '#808080', green : '#008000', greenyellow : '#adff2f', honeydew : '#f0fff0', hotpink : '#ff69b4', indianred : '#cd5c5c', indigo : '#4b0082', ivory : '#fffff0', khaki : '#f0e68c', lavender : '#e6e6fa', lavenderblush : '#fff0f5', lawngreen : '#7cfc00', lemonchiffon : '#fffacd', lightblue : '#add8e6', lightcoral : '#f08080', lightcyan : '#e0ffff', lightgoldenrodyellow : '#fafad2', lightgray : '#d3d3d3', lightgrey : '#d3d3d3', lightgreen : '#90ee90', lightpink : '#ffb6c1', lightsalmon : '#ffa07a', lightseagreen : '#20b2aa', lightskyblue : '#87cefa', lightslategray : '#789', lightslategrey : '#789', lightsteelblue : '#b0c4de', lightyellow : '#ffffe0', lime : '#0f0', limegreen : '#32cd32', linen : '#faf0e6', magenta : '#f0f', maroon : '#800000', mediumaquamarine : '#66cdaa', mediumblue : '#0000cd', mediumorchid : '#ba55d3', mediumpurple : '#9370d8', mediumseagreen : '#3cb371', mediumslateblue : '#7b68ee', mediumspringgreen : '#00fa9a', mediumturquoise : '#48d1cc', mediumvioletred : '#c71585', midnightblue : '#191970', mintcream : '#f5fffa', mistyrose : '#ffe4e1', moccasin : '#ffe4b5', navajowhite : '#ffdead', navy : '#000080', oldlace : '#fdf5e6', olive : '#808000', olivedrab : '#6b8e23', orange : '#ffa500', orangered : '#ff4500', orchid : '#da70d6', palegoldenrod : '#eee8aa', palegreen : '#98fb98', paleturquoise : '#afeeee', palevioletred : '#d87093', papayawhip : '#ffefd5', peachpuff : '#ffdab9', peru : '#cd853f', pink : '#ffc0cb', plum : '#dda0dd', powderblue : '#b0e0e6', purple : '#800080', red : '#f00', rosybrown : '#bc8f8f', royalblue : '#4169e1', saddlebrown : '#8b4513', salmon : '#fa8072', sandybrown : '#f4a460', seagreen : '#2e8b57', seashell : '#fff5ee', sienna : '#a0522d', silver : '#c0c0c0', skyblue : '#87ceeb', slateblue : '#6a5acd', slategray : '#708090', slategrey : '#708090', snow : '#fffafa', springgreen : '#00ff7f', steelblue : '#4682b4', tan : '#d2b48c', teal : '#008080', thistle : '#d8bfd8', tomato : '#ff6347', turquoise : '#40e0d0', violet : '#ee82ee', wheat : '#f5deb3', white : '#fff', whitesmoke : '#f5f5f5', yellow : '#ff0', yellowgreen : '#9acd32' }; /** * 自定义调色板 */ function customPalette(userPalete) { palette = userPalete; } /** * 复位默认色板 */ function resetPalette() { palette = _palette; } /** * 获取色板颜色 * @param {number} idx : 色板位置 * @param {array} [userPalete] : 自定义色板 * * @return {color} 颜色#000000~#ffffff */ function getColor(idx, userPalete) { idx = +idx || 0; userPalete = userPalete || palette; return userPalete[idx % userPalete.length]; } /** * 自定义默认高亮颜色 */ function customHighlight(userHighlightColor) { highlightColor = userHighlightColor; } /** * 重置默认高亮颜色 */ function resetHighlight() { _highlightColor = highlightColor; } /** * 获取默认高亮颜色 */ function getHighlightColor() { return highlightColor; } /** * 径向渐变 * @param {number} x0 渐变起点 * @param {number} y0 * @param {number} r0 * @param {number} x1 渐变终点 * @param {number} y1 * @param {number} r1 * @param {Array} colorList 颜色列表 */ function getRadialGradient(x0, y0, r0, x1, y1, r1, colorList) { if (!_ctx) { _ctx = util.getContext(); } var gradient = _ctx.createRadialGradient(x0, y0, r0, x1, y1, r1); for ( var i = 0, l = colorList.length; i < l; i++) { gradient.addColorStop(colorList[i][0], colorList[i][1]); } gradient.__nonRecursion = true; return gradient; } /** * 线性渐变 * @param {Object} x0 渐变起点 * @param {Object} y0 * @param {Object} x1 渐变终点 * @param {Object} y1 * @param {Array} colorList 颜色列表 */ function getLinearGradient(x0, y0, x1, y1, colorList) { if (!_ctx) { _ctx = util.getContext(); } var gradient = _ctx.createLinearGradient(x0, y0, x1, y1); for ( var i = 0, l = colorList.length; i < l; i++) { gradient.addColorStop(colorList[i][0], colorList[i][1]); } gradient.__nonRecursion = true; return gradient; } /** * 获取两种颜色之间渐变颜色数组 * @param {color} start 起始颜色 * @param {color} end 结束颜色 * @param {number} step 渐变级数 * @return {Array} 颜色数组 */ function getStepColors(start, end, step) { start = toRGBA(start); end = toRGBA(end); start = getData(start); end = getData(end); var colors = []; var stepR = (end[0] - start[0]) / step; var stepG = (end[1] - start[1]) / step; var stepB = (end[2] - start[2]) / step; // 生成颜色集合 // fix by linfeng 颜色堆积 for (var i = 0, r = start[0], g = start[1], b = start[2]; i < step; i++ ) { colors[i] = toColor([ adjust(Math.floor(r), [ 0, 255 ]), adjust(Math.floor(g), [ 0, 255 ]), adjust(Math.floor(b), [ 0, 255 ]) ]); r += stepR; g += stepG; b += stepB; } r = end[0]; g = end[1]; b = end[2]; colors[i] = toColor( [ r, g, b ]); return colors; } /** * 获取指定级数的渐变颜色数组 * @param {Array} colors 颜色组 * @param {number=20} step 渐变级数 * @return {Array} 颜色数组 */ function getGradientColors(colors, step) { var ret = []; var len = colors.length; if (step === undefined) { step = 20; } if (len === 1) { ret = getStepColors(colors[0], colors[0], step); } else if (len > 1) { for ( var i = 0, n = len - 1; i < n; i++) { var steps = getStepColors(colors[i], colors[i + 1], step); if (i < n - 1) { steps.pop(); } ret = ret.concat(steps); } } return ret; } /** * 颜色值数组转为指定格式颜色,例如:
* data = [60,20,20,0.1] format = 'rgba' * 返回:rgba(60,20,20,0.1) * @param {Array} data 颜色值数组 * @param {string} format 格式,默认rgb * @return {string} 颜色 */ function toColor(data, format) { format = format || 'rgb'; if (data && (data.length === 3 || data.length === 4)) { data = map(data, function(c) { return c > 1 ? Math.ceil(c) : c; }); if (format.indexOf('hex') > -1) { data = map(data.slice(0, 3), function(c) { c = Number(c).toString(16); return (c.length === 1) ? '0' + c : c; }); return '#' + data.join(''); } else if (format.indexOf('hs') > -1) { var sx = map(data.slice(1, 3), function(c) { return c + '%'; }); data[1] = sx[0]; data[2] = sx[1]; } if (format.indexOf('a') > -1) { if (data.length === 3) { data.push(1); } data[3] = adjust(data[3], [ 0, 1 ]); return format + '(' + data.slice(0, 4).join(',') + ')'; } return format + '(' + data.slice(0, 3).join(',') + ')'; } } /** * 返回颜色值数组 * @param {string} color 颜色 * @return {Array} 颜色值数组 */ function toArray(color) { color = trim(color); if (color.indexOf('#') > -1) { color = toRGB(color); } var data = color.replace(/[rgbahsvl%\(\)]/ig, '').split(','); data = map(data, function(c) { return Number(c); }); return data; } /** * 颜色格式转化 * @param {Array} data 颜色值数组 * @param {string} format 格式,默认rgb * @return {string} 颜色 */ function convert(color, format) { var data = getData(color); var alpha = data[3]; if(typeof alpha === 'undefined') { alpha = 1; } if (color.indexOf('hsb') > -1) { data = _HSV_2_RGB(data); } else if (color.indexOf('hsl') > -1) { data = _HSL_2_RGB(data); } if (format.indexOf('hsb') > -1 || format.indexOf('hsv') > -1) { data = _RGB_2_HSB(data); } else if (format.indexOf('hsl') > -1) { data = _RGB_2_HSL(data); } data[3] = alpha; return toColor(data, format); } /** * 转换为rgba格式的颜色 * @param {string} color 颜色 * @return {string} rgba颜色,rgba(r,g,b,a) */ function toRGBA(color) { return convert(color, 'rgba'); } /** * 转换为rgb数字格式的颜色 * @param {string} color 颜色 * @return {string} rgb颜色,rgb(0,0,0)格式 */ function toRGB(color) { return convert(color, 'rgb'); } /** * 转换为16进制颜色 * @param {string} color 颜色 * @return {string} 16进制颜色,#rrggbb格式 */ function toHex(color) { return convert(color, 'hex'); } /** * 转换为HSV颜色 * @param {string} color 颜色 * @return {string} HSVA颜色,hsva(h,s,v,a) */ function toHSVA(color) { return convert(color, 'hsva'); } /** * 转换为HSV颜色 * @param {string} color 颜色 * @return {string} HSV颜色,hsv(h,s,v) */ function toHSV(color) { return convert(color, 'hsv'); } /** * 转换为HSBA颜色 * @param {string} color 颜色 * @return {string} HSBA颜色,hsba(h,s,b,a) */ function toHSBA(color) { return convert(color, 'hsba'); } /** * 转换为HSB颜色 * @param {string} color 颜色 * @return {string} HSB颜色,hsb(h,s,b) */ function toHSB(color) { return convert(color, 'hsb'); } /** * 转换为HSLA颜色 * @param {string} color 颜色 * @return {string} HSLA颜色,hsla(h,s,l,a) */ function toHSLA(color) { return convert(color, 'hsla'); } /** * 转换为HSL颜色 * @param {string} color 颜色 * @return {string} HSL颜色,hsl(h,s,l) */ function toHSL(color) { return convert(color, 'hsl'); } /** * 转换颜色名 * @param {string} color 颜色 * @return {String} 颜色名 */ function toName(color) { for ( var key in _nameColors) { if (toHex(_nameColors[key]) === toHex(color)) { return key; } } return null; } /** * 移除颜色中多余空格 * @param {String} color 颜色 * @return {String} 无空格颜色 */ function trim(color) { color = String(color); color = color.replace(/(^\s*)|(\s*$)/g, ''); if (/^[^#]*?$/i.test(color)) { color = color.replace(/\s/g, ''); } return color; } // 规范化 function normalize(color) { // 颜色名 if (_nameColors[color]) { color = _nameColors[color]; } // 去掉空格 color = trim(color); // hsv与hsb等价 color = color.replace(/hsv/i, 'hsb'); // rgb转为rrggbb if (/^#[0-9a-f]{3}$/i.test(color)) { var d = color.replace('#', '').split(''); color = '#' + d[0] + d[0] + d[1] + d[1] + d[2] + d[2]; } return color; } /** * 颜色加深或减淡,当level>0加深,当level<0减淡 * @param {string} color 颜色 * @param {number} level 升降程度,取值区间[-1,1] * @return {string} 加深或减淡后颜色值 */ function lift(color, level) { var direct = level > 0 ? 1 : -1; if (typeof level === 'undefined') { level = 0; } level = Math.abs(level) > 1 ? 1 : Math.abs(level); color = toRGB(color); var data = getData(color); for ( var i = 0; i < 3; i++) { if (direct === 1) { data[i] = Math.floor(data[i] * (1 - level)); } else { data[i] = Math.floor((255 - data[i]) * level + data[i]); } } return 'rgb(' + data.join(',') + ')'; } /** * 颜色翻转,[255-r,255-g,255-b,1-a] * @param {string} color 颜色 * @return {string} 翻转颜色 */ function reverse(color) { var data = getData(toRGBA(color)); data = map(data, function(c) { return 255 - c; }); return toColor(data, 'rgb'); } /** * 简单两种颜色混合 * @param {String} color1 第一种颜色 * @param {String} color2 第二种颜色 * @param {String} weight 混合权重[0-1] * @return {String} 结果色,rgb(r,g,b)或rgba(r,g,b,a) */ function mix(color1, color2, weight) { if(typeof weight === 'undefined') { weight = 0.5; } weight = 1 - adjust(weight, [0, 1]); var w = weight * 2 - 1; var data1 = getData(toRGBA(color1)); var data2 = getData(toRGBA(color2)); var d = data1[3] - data2[3]; var weight1 = (((w * d === -1) ? w : (w + d) / (1 + w * d)) + 1) / 2; var weight2 = 1 - weight1; var data = []; for ( var i = 0; i < 3; i++) { data[i] = data1[i] * weight1 + data2[i] * weight2; } var alpha = data1[3] * weight + data2[3] * (1 - weight); alpha = Math.max(0, Math.min(1, alpha)); if (data1[3] === 1 && data2[3] === 1) {// 不考虑透明度 return toColor(data, 'rgb'); } data[3] = alpha; return toColor(data, 'rgba'); } /** * 随机颜色 * @return {string} 颜色值,#rrggbb格式 */ function random() { return toHex( 'rgb(' + Math.round(Math.random() * 256) + ',' + Math.round(Math.random() * 256) + ',' + Math.round(Math.random() * 256) + ')' ); } /** * 获取颜色值数组,返回值范围:
* RGB 范围[0-255]
* HSL/HSV/HSB 范围[0-1]
* A透明度范围[0-1] * 支持格式: * #rgb * #rrggbb * rgb(r,g,b) * rgb(r%,g%,b%) * rgba(r,g,b,a) * hsb(h,s,b) // hsv与hsb等价 * hsb(h%,s%,b%) * hsba(h,s,b,a) * hsl(h,s,l) * hsl(h%,s%,l%) * hsla(h,s,l,a) * @param {string} color 颜色 * @return {Array} 颜色值数组或null */ function getData(color) { color = normalize(color); var r = color.match(colorRegExp); if (r === null) { throw new Error('The color format error'); // 颜色格式错误 } var d; var a; var data = []; var rgb; if (r[2]) { // #rrggbb d = r[2].replace('#', '').split(''); rgb = [ d[0] + d[1], d[2] + d[3], d[4] + d[5] ]; data = map(rgb, function(c) { return adjust(parseInt(c, 16), [ 0, 255 ]); }); } else if (r[4]) { // rgb rgba var rgba = (r[4]).split(','); a = rgba[3]; rgb = rgba.slice(0, 3); data = map( rgb, function(c) { c = Math.floor( c.indexOf('%') > 0 ? parseInt(c, 0) * 2.55 : c ); return adjust(c, [ 0, 255 ]); } ); if( typeof a !== 'undefined') { data.push(adjust(parseFloat(a), [ 0, 1 ])); } } else if (r[5] || r[6]) { // hsb hsba hsl hsla var hsxa = (r[5] || r[6]).split(','); var h = parseInt(hsxa[0], 0) / 360; var s = hsxa[1]; var x = hsxa[2]; a = hsxa[3]; data = map( [ s, x ], function(c) { return adjust(parseFloat(c) / 100, [ 0, 1 ]); }); data.unshift(h); if( typeof a !== 'undefined') { data.push(adjust(parseFloat(a), [ 0, 1 ])); } } return data; } /** * 设置颜色透明度 * @param {string} color 颜色 * @param {number} alpha 透明度,区间[0,1] * @return {string} rgba颜色值 */ function alpha(color, a) { if (a === null) { a = 1; } var data = getData(toRGBA(color)); data[3] = adjust(Number(a).toFixed(4), [ 0, 1 ]); return toColor(data, 'rgba'); } // 数组映射 function map(array, fun) { if (typeof fun !== 'function') { throw new TypeError(); } var len = array ? array.length : 0; for ( var i = 0; i < len; i++) { array[i] = fun(array[i]); } return array; } // 调整值区间 function adjust(value, region) { // < to <= & > to >= // modify by linzhifeng 2014-05-25 because -0 == 0 if (value <= region[0]) { value = region[0]; } else if (value >= region[1]) { value = region[1]; } return value; } // 参见 http:// www.easyrgb.com/index.php?X=MATH function _HSV_2_RGB(data) { var H = data[0]; var S = data[1]; var V = data[2]; // HSV from 0 to 1 var R, G, B; if (S === 0) { R = V * 255; G = V * 255; B = V * 255; } else { var h = H * 6; if (h === 6) { h = 0; } var i = Math.floor(h); var v1 = V * (1 - S); var v2 = V * (1 - S * (h - i)); var v3 = V * (1 - S * (1 - (h - i))); var r = 0; var g = 0; var b = 0; if (i === 0) { r = V; g = v3; b = v1; } else if (i === 1) { r = v2; g = V; b = v1; } else if (i === 2) { r = v1; g = V; b = v3; } else if (i === 3) { r = v1; g = v2; b = V; } else if (i === 4) { r = v3; g = v1; b = V; } else { r = V; g = v1; b = v2; } // RGB results from 0 to 255 R = r * 255; G = g * 255; B = b * 255; } return [ R, G, B ]; } function _HSL_2_RGB(data) { var H = data[0]; var S = data[1]; var L = data[2]; // HSL from 0 to 1 var R, G, B; if (S === 0) { R = L * 255; G = L * 255; B = L * 255; } else { var v2; if (L < 0.5) { v2 = L * (1 + S); } else { v2 = (L + S) - (S * L); } var v1 = 2 * L - v2; R = 255 * _HUE_2_RGB(v1, v2, H + (1 / 3)); G = 255 * _HUE_2_RGB(v1, v2, H); B = 255 * _HUE_2_RGB(v1, v2, H - (1 / 3)); } return [ R, G, B ]; } function _HUE_2_RGB(v1, v2, vH) { if (vH < 0) { vH += 1; } if (vH > 1) { vH -= 1; } if ((6 * vH) < 1) { return (v1 + (v2 - v1) * 6 * vH); } if ((2 * vH) < 1) { return (v2); } if ((3 * vH) < 2) { return (v1 + (v2 - v1) * ((2 / 3) - vH) * 6); } return v1; } function _RGB_2_HSB(data) { // RGB from 0 to 255 var R = (data[0] / 255); var G = (data[1] / 255); var B = (data[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 V = vMax; var H; var S; // HSV results from 0 to 1 if (delta === 0) { H = 0; S = 0; } else { S = delta / vMax; 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; } } H = H * 360; S = S * 100; V = V * 100; return [ H, S, V ]; } function _RGB_2_HSL(data) { // RGB from 0 to 255 var R = (data[0] / 255); var G = (data[1] / 255); var B = (data[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; } } H = H * 360; S = S * 100; L = L * 100; return [ H, S, L ]; } return { customPalette : customPalette, resetPalette : resetPalette, getColor : getColor, getHighlightColor : getHighlightColor, customHighlight : customHighlight, resetHighlight : resetHighlight, getRadialGradient : getRadialGradient, getLinearGradient : getLinearGradient, getGradientColors : getGradientColors, getStepColors : getStepColors, reverse : reverse, mix : mix, lift : lift, trim : trim, random : random, toRGB : toRGB, toRGBA : toRGBA, toHex : toHex, toHSL : toHSL, toHSLA : toHSLA, toHSB : toHSB, toHSBA : toHSBA, toHSV : toHSV, toHSVA : toHSVA, toName : toName, toColor : toColor, toArray : toArray, alpha : alpha, getData : getData }; }); /** * zrender : shape基类 * * desc: zrender是一个轻量级的Canvas类库,MVC封装,数据驱动,提供类Dom事件模型。 * author: Kener (@Kener-林峰, linzhifeng@baidu.com) * * 可配图形属性: { // 基础属性,详见各shape shape : {string}, // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 变换 position : {array}, // 默认为[0, 0], shape的坐标 rotation : {number|array}, // 默认为[0, 0, 0],shape绕自身旋转的角度,不被translate 影响 // 后两个值为旋转的origin scale : {array}, // 默认为[1, 1, 0, 0], shape纵横缩放比例,不被translate影响 // 后两个值为缩放的origin // 样式属性,详见各shape,默认状态样式属性 style : {Object}, // 样式属性,详见各shape,高亮样式属性,当不存在highlightStyle时使用默认样式扩展显示 highlightStyle : {Object}, // 交互属性,zrender支持,非图形类实现 hoverable : {boolean}, // 默认为true,可悬浮响应,默认悬浮响应为高亮显示 // 可在onbrush中捕获并阻塞高亮绘画 clickable : {boolean}, // 默认为false,可点击响应,影响鼠标hover时图标是否为可点击样式 // 为false则阻断点击事件抛出,为true可在onclick中捕获 draggable : {boolean}, // 默认为false,可拖拽响应,默认拖拽响应改变图形位置, // 可在ondrift中捕获并阻塞默认拖拽行为 // 事件属性 onbrush : {Function}, // 默认为null,当前图形被刷画时回调,可用于实现自定义绘画 // 回传参数为: // @param {2D Context} context 当前canvas context // @param {Object} shape 当前shape // @param {boolean} isHighlight 是否高亮 // @return {boolean} 回调返回true则不执行默认绘画 ondrift : {Function}, // 默认为null,当前图形被拖拽改变位置时回调,可用于限制拖拽范围 // 回传参数为: // @param {Object} shape 当前shape // @param {number} dx x方向变化 // @param {number} dy y方向变化 onclick : {Function}, // 默认为null,当前图形点击响应,回传参数为: // @param {Object} eventPacket 对象内容如下: // @param {string} eventPacket.type 事件类型,EVENT.CLICK // @param {event} eventPacket.event 原始dom事件对象 // @param {Object} eventPacket.target 当前图形shape对象 // @return {boolean} 回调返回true则阻止抛出全局事件 onmousewheel : {Function}, // 默认为null,当前图形上鼠标滚轮触发,回传参数格式同onclick,其中: // 事件类型为confit.EVENT.MOUSEWHEEL // @return {boolean} 回调返回true则阻止抛出全局事件 onmousemove : {Function}, // 默认为null,当前图上形鼠标(或手指)移动触发,回传参数格式同onclick,其中: // 事件类型为confit.EVENT.MOUSEMOVE // @return {boolean} 回调返回true则阻止抛出全局事件 onmouseover : {Function}, // 默认为null,鼠标(或手指)移动到当前图形上触发,回传参数格式同onclick: // 事件类型为confit.EVENT.MOUSEOVER // @return {boolean} 回调返回true则阻止抛出全局事件 onmouseout : {Function}, // 默认为null,鼠标(或手指)从当前图形移开,回传参数格式同onclick,其中: // 事件类型为confit.EVENT.MOUSEOUT // @return {boolean} 回调返回true则阻止抛出全局事件 onmousedown : {Function}, // 默认为null,鼠标按钮(或手指)按下,回传参数格式同onclick,其中: // 事件类型为confit.EVENT.MOUSEDOWN // @return {boolean} 回调返回true则阻止抛出全局事件 onmouseup : {Function}, // 默认为null,鼠标按钮(或手指)松开,回传参数格式同onclick,其中: // 事件类型为confit.EVENT.MOUSEUP // @return {boolean} 回调返回true则阻止抛出全局事件 ondragstart : {Function}, // 默认为null,开始拖拽时触发,回传参数格式同onclick,其中: // 事件类型为confit.EVENT.DRAGSTART // @return {boolean} 回调返回true则阻止抛出全局事件 ondragend : {Function}, // 默认为null,拖拽完毕时触发,回传参数格式同onclick,其中: // 事件类型为confit.EVENT.DRAGEND // @return {boolean} 回调返回true则阻止抛出全局事件 ondragenter : {Function}, // 默认为null,拖拽图形元素进入目标图形元素时触发 // 回传参数格式同onclick,其中: // @param {string} eventPacket.type 事件类型,EVENT.DRAGENTER // @param {Object} eventPacket.target 目标图形元素shape对象 // @param {Object} eventPacket.dragged 拖拽图形元素shape对象 // @return {boolean} 回调返回true则阻止抛出全局事件 ondragover : {Function}, // 默认为null,拖拽图形元素在目标图形元素上移动时触发, // 回传参数格式同onclick,其中: // @param {string} eventPacket.type 事件类型,EVENT.DRAGOVER // @param {Object} eventPacket.target 目标图形元素shape对象 // @param {Object} eventPacket.dragged 拖拽图形元素shape对象 // @return {boolean} 回调返回true则阻止抛出全局事件 ondragleave : {Function}, // 默认为null,拖拽图形元素离开目标图形元素时触发, // 回传参数格式同onclick,其中: // @param {string} eventPacket.type 事件类型,EVENT.DRAGLEAVE // @param {Object} eventPacket.target 目标图形元素shape对象 // @param {Object} eventPacket.dragged 拖拽图形元素shape对象 // @return {boolean} 回调返回true则阻止抛出全局事件 ondrop : {Function}, // 默认为null,拖拽图形元素放在目标图形元素内时触发, // 回传参数格式同onclick,其中: // @param {string} eventPacket.type 事件类型,EVENT.DRAG // @param {Object} eventPacket.target 目标图形元素shape对象 // @param {Object} eventPacket.dragged 拖拽图形元素shape对象 // @return {boolean} 回调返回true则阻止抛出全局事件 } */ define( 'zrender/shape/base',['require','../tool/area','../tool/matrix','../tool/vector','../tool/color'],function(require) { var self; var area = require('../tool/area'); var matrix = require('../tool/matrix'); var vec2 = require('../tool/vector'); /** * 派生实现通用功能 * @param {Object} clazz 图形类 */ function derive(clazz) { var methods = [ // 派生实现的基类方法 'brush', 'setContext', 'dashedLineTo', 'smoothBezier', 'smoothSpline', 'drawText', 'getHighlightStyle', 'getHighlightZoom', 'drift', 'isCover', 'updateTransform' ]; var len = methods.length; var proto = clazz.prototype; var i = 0; var method; for (; i < len; i++) { method = methods[i]; if (!proto[method]) { proto[method] = self[method]; } } } /** * 画刷 * @param ctx 画布句柄 * @param e 形状实体 * @param isHighlight 是否为高亮状态 * @param updateCallback 需要异步加载资源的shape可以通过这个callback(e) * 让painter更新视图,base.brush没用,需要的话重载brush */ function brush(ctx, e, isHighlight) { var style = e.style || {}; if (this.brushTypeOnly) { style.brushType = this.brushTypeOnly; } if (isHighlight) { // 根据style扩展默认高亮样式 style = this.getHighlightStyle( style, e.highlightStyle || {}, this.brushTypeOnly ); } if (this.brushTypeOnly == 'stroke') { style.strokeColor = style.strokeColor || style.color; } ctx.save(); this.setContext(ctx, style); // 设置transform if (e.__needTransform) { ctx.transform.apply(ctx,this.updateTransform(e)); } ctx.beginPath(); this.buildPath(ctx, style); if (this.brushTypeOnly != 'stroke') { ctx.closePath(); } switch (style.brushType) { case 'fill': ctx.fill(); break; case 'stroke': style.lineWidth > 0 && ctx.stroke(); break; case 'both': ctx.fill(); style.lineWidth > 0 && ctx.stroke(); break; default: ctx.fill(); } if (typeof style.text != 'undefined') { this.drawText(ctx, style, e.style); } ctx.restore(); return; } /** * 画布通用设置 * @param ctx 画布句柄 * @param style 通用样式 */ function setContext(ctx, style) { // 简单判断不做严格类型检测 if (style.color) { ctx.fillStyle = style.color; } if (style.strokeColor) { ctx.strokeStyle = style.strokeColor; } if (typeof style.opacity != 'undefined') { ctx.globalAlpha = style.opacity; } if (style.lineCap) { ctx.lineCap = style.lineCap; } if (style.lineJoin) { ctx.lineJoin = style.lineJoin; } if (style.miterLimit) { ctx.miterLimit = style.miterLimit; } if (typeof style.lineWidth != 'undefined') { ctx.lineWidth = style.lineWidth; } if (typeof style.shadowBlur != 'undefined') { ctx.shadowBlur = style.shadowBlur; } if (style.shadowColor) { ctx.shadowColor = style.shadowColor; } if (typeof style.shadowOffsetX != 'undefined') { ctx.shadowOffsetX = style.shadowOffsetX; } if (typeof style.shadowOffsetY != 'undefined') { ctx.shadowOffsetY = style.shadowOffsetY; } } /** * 虚线lineTo */ function dashedLineTo(ctx, x1, y1, x2, y2, dashLength) { dashLength = typeof dashLength == 'undefined' ? 5 : dashLength; var deltaX = x2 - x1; var deltaY = y2 - y1; var numDashes = Math.floor( Math.sqrt(deltaX * deltaX + deltaY * deltaY) / dashLength ); for (var i = 0; i < numDashes; ++i) { ctx[i % 2 === 0 ? 'moveTo' : 'lineTo']( x1 + (deltaX / numDashes) * i, y1 + (deltaY / numDashes) * i ); } } /** * 贝塞尔平滑曲线 */ function smoothBezier(points, smooth, loop) { var len = points.length; var cps = []; var v = []; var v1 = []; var v2 = []; var prevPoint; var nextPoint; for(var i = 0; i < len; i++){ var point = points[i]; var prevPoint; var nextPoint; if (loop) { prevPoint = points[i === 0 ? len-1 : i-1]; nextPoint = points[(i + 1) % len]; } else { if (i === 0 || i === len-1) { cps.push(points[i]); continue; } else { prevPoint = points[i-1]; nextPoint = points[i+1]; } } vec2.sub(v, nextPoint, prevPoint); //use degree to scale the handle length vec2.scale(v, v, smooth); var d0 = vec2.distance(point, prevPoint); var d1 = vec2.distance(point, nextPoint); var sum = d0 + d1; d0 /= sum; d1 /= sum; vec2.scale(v1, v, -d0); vec2.scale(v2, v, d1); cps.push(vec2.add([], point, v1)); cps.push(vec2.add([], point, v2)); } if (loop) { cps.push(cps.shift()); } return cps; } /** * 多线段平滑曲线 Catmull-Rom spline */ function smoothSpline(points, loop) { var len = points.length; var ret = []; var distance = 0; for (var i = 1; i < len; i++) { distance += vec2.distance(points[i-1], points[i]); } var segs = distance / 5; segs = segs < len ? len : segs; for (var i = 0; i < segs; i++) { var pos; if (loop) { pos = i / (segs-1) * len; } else { pos = i / (segs-1) * (len - 1); } var idx = Math.floor(pos); var w = pos - idx; var p0; var p1 = points[idx % len]; var p2; var p3; if (!loop) { p0 = points[idx === 0 ? idx : idx - 1]; p2 = points[idx > len - 2 ? len - 1 : idx + 1]; p3 = points[idx > len - 3 ? len - 1 : idx + 2]; } else { p0 = points[(idx -1 + len) % len]; p2 = points[(idx + 1) % len]; p3 = points[(idx + 2) % len]; } var w2 = w * w; var w3 = w * w2; ret.push([ _interpolate(p0[0], p1[0], p2[0], p3[0], w, w2, w3), _interpolate(p0[1], p1[1], p2[1], p3[1], w, w2, w3) ]); } return ret; } function _interpolate(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; } /** * 附加文本 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 * @param {Object} normalStyle 默认样式,用于定位文字显示 */ function drawText(ctx, style, normalStyle) { // 字体颜色策略 style.textColor= style.textColor || style.color || style.strokeColor; ctx.fillStyle = style.textColor; if (style.textPosition == 'inside') { ctx.shadowColor = 'rgba(0,0,0,0)'; // 内部文字不带shadowColor } // 文本与图形间空白间隙 var dd = 10; var al; // 文本水平对齐 var bl; // 文本垂直对齐 var tx; // 文本横坐标 var ty; // 文本纵坐标 var textPosition = style.textPosition // 用户定义 || this.textPosition // shape默认 || 'top'; // 全局默认 if ((textPosition == 'inside' || textPosition == 'top' || textPosition == 'bottom' || textPosition == 'left' || textPosition == 'right') && this.getRect // 矩形定位文字的图形必须提供getRect方法 ) { var rect = (normalStyle || style).__rect || this.getRect(normalStyle || style); switch (textPosition) { case 'inside': tx = rect.x + rect.width / 2; ty = rect.y + rect.height / 2; al = 'center'; bl = 'middle'; if (style.brushType != 'stroke' && style.textColor == style.color ) { ctx.fillStyle = '#fff'; } break; case 'left': tx = rect.x - dd; ty = rect.y + rect.height / 2; al = 'end'; bl = 'middle'; break; case 'right': tx = rect.x + rect.width + dd; ty = rect.y + rect.height / 2; al = 'start'; bl = 'middle'; break; case 'top': tx = rect.x + rect.width / 2; ty = rect.y - dd; al = 'center'; bl = 'bottom'; break; case 'bottom': tx = rect.x + rect.width / 2; ty = rect.y + rect.height + dd; al = 'center'; bl = 'top'; break; } } else if (textPosition == 'start' || textPosition == 'end') { var xStart; var xEnd; var yStart; var yEnd; if (typeof style.pointList != 'undefined') { var pointList = style.pointList; if (pointList.length < 2) { // 少于2个点就不画了~ return; } var length = pointList.length; switch (textPosition) { case 'start': xStart = pointList[0][0]; xEnd = pointList[1][0]; yStart = pointList[0][1]; yEnd = pointList[1][1]; break; case 'end': xStart = pointList[length - 2][0]; xEnd = pointList[length - 1][0]; yStart = pointList[length - 2][1]; yEnd = pointList[length - 1][1]; break; } } else { xStart = style.xStart || 0; xEnd = style.xEnd || 0; yStart = style.yStart || 0; yEnd = style.yEnd || 0; } switch (textPosition) { case 'start': al = xStart < xEnd ? 'end' : 'start'; bl = yStart < yEnd ? 'bottom' : 'top'; tx = xStart; ty = yStart; break; case 'end': al = xStart < xEnd ? 'start' : 'end'; bl = yStart < yEnd ? 'top' : 'bottom'; tx = xEnd; ty = yEnd; break; } dd -= 4; if (xStart != xEnd) { tx -= (al == 'end' ? dd : -dd); } else { al = 'center'; } if (yStart != yEnd) { ty -= (bl == 'bottom' ? dd : -dd); } else { bl = 'middle'; } } else if (textPosition == 'specific') { tx = style.textX || 0; ty = style.textY || 0; al = 'start'; bl = 'middle'; } if (typeof tx != 'undefined' && typeof ty != 'undefined') { _fillText( ctx, style.text, tx, ty, style.textFont, style.textAlign || al, style.textBaseline || bl ); } } function _fillText(ctx, text, x, y, textFont, textAlign, textBaseline) { if (textFont) { ctx.font = textFont; } ctx.textAlign = textAlign; ctx.textBaseline = textBaseline; var rect = _getTextRect( text, x, y, textFont, textAlign, textBaseline ); text = (text + '').split('\n'); var lineHeight = area.getTextHeight('国', textFont); var x = x; var y; if (textBaseline == 'top') { y = rect.y; } else if (textBaseline == 'bottom') { y = rect.y + lineHeight; } else { y = rect.y + lineHeight / 2; } for (var i = 0, l = text.length; i < l; i++) { ctx.fillText(text[i], x, y); y += lineHeight; } } /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ function _getTextRect(text, x, y, textFont, textAlign, textBaseline) { var width = area.getTextWidth(text, textFont); var lineHeight = area.getTextHeight('国', textFont); text = (text + '').split('\n'); var textX = x; //默认start == left if (textAlign == 'end' || textAlign == 'right') { textX -= width; } else if (textAlign == 'center') { textX -= (width / 2); } var textY; if (textBaseline == 'top') { textY = y; } else if (textBaseline == 'bottom') { textY = y - lineHeight * text.length; } else { // middle textY = y - lineHeight * text.length / 2; } return { x : textX, y : textY, width : width, height : lineHeight * text.length }; } /** * 根据默认样式扩展高亮样式 * @param ctx Canvas 2D上下文 * @param {Object} style 默认样式 * @param {Object} highlightStyle 高亮样式 */ function getHighlightStyle(style, highlightStyle, brushTypeOnly) { var newStyle = {}; for (var k in style) { newStyle[k] = style[k]; } var color = require('../tool/color'); var highlightColor = color.getHighlightColor(); // 根据highlightStyle扩展 if (style.brushType != 'stroke') { // 带填充则用高亮色加粗边线 newStyle.strokeColor = highlightColor; newStyle.lineWidth = (style.lineWidth || 1) + this.getHighlightZoom(); newStyle.brushType = 'both'; } else { if (brushTypeOnly != 'stroke') { // 描边型的则用原色加工高亮 newStyle.strokeColor = highlightColor; newStyle.lineWidth = (style.lineWidth || 1) + this.getHighlightZoom(); } else { // 线型的则用原色加工高亮 newStyle.strokeColor = highlightStyle.strokeColor || color.mix( style.strokeColor, color.toRGB(highlightColor) ); } } // 可自定义覆盖默认值 for (var k in highlightStyle) { if (typeof highlightStyle[k] != 'undefined') { newStyle[k] = highlightStyle[k]; } } return newStyle; } /** * 高亮放大效果参数 * 当前统一设置为6,如有需要差异设置,通过this.type判断实例类型 */ function getHighlightZoom() { return this.type != 'text' ? 6 : 2; } /** * 默认漂移 * @param e 图形实体 * @param dx 横坐标变化 * @param dy 纵坐标变化 */ function drift(e, dx, dy) { e.position[0] += dx; e.position[1] += dy; } /** * 默认区域包含判断 * @param e 图形实体 * @param x 横坐标 * @param y 纵坐标 */ function isCover(e, x, y) { //对鼠标的坐标也做相同的变换 if(e.__needTransform && e._transform){ var inverseMatrix = []; matrix.invert(inverseMatrix, e._transform); var originPos = [x, y]; matrix.mulVector(originPos, inverseMatrix, [x, y, 1]); if (x == originPos[0] && y == originPos[1]) { // 避免外部修改导致的__needTransform不准确 if (Math.abs(e.rotation[0]) > 0.0001 || Math.abs(e.position[0]) > 0.0001 || Math.abs(e.position[1]) > 0.0001 || Math.abs(e.scale[0] - 1) > 0.0001 || Math.abs(e.scale[1] - 1) > 0.0001 ) { e.__needTransform = true; } else { e.__needTransform = false; } } x = originPos[0]; y = originPos[1]; } // 快速预判并保留判断矩形 var rect; if (e.style.__rect) { rect = e.style.__rect; } else { rect = this.getRect(e.style); e.style.__rect = rect; } if (x >= rect.x && x <= (rect.x + rect.width) && y >= rect.y && y <= (rect.y + rect.height) ) { // 矩形内 return area.isInside(this, e.style, x, y); } else { return false; } } function updateTransform(e) { var _transform = e._transform || matrix.create(); matrix.identity(_transform); if (e.scale && (e.scale[0] !== 1 || e.scale[1] !== 1)) { var originX = e.scale[2] || 0; var originY = e.scale[3] || 0; if (originX || originY ) { matrix.translate( _transform, _transform, [-originX, -originY] ); } matrix.scale(_transform, _transform, e.scale); if ( originX || originY ) { matrix.translate( _transform, _transform, [originX, originY] ); } } if (e.rotation) { if (e.rotation instanceof Array) { if (e.rotation[0] !== 0) { var originX = e.rotation[1] || 0, originY = e.rotation[2] || 0; if (originX || originY ) { matrix.translate( _transform, _transform, [-originX, -originY] ); } matrix.rotate(_transform, _transform, e.rotation[0]); if (originX || originY ) { matrix.translate( _transform, _transform, [originX, originY] ); } } }else{ if (e.rotation !== 0) { matrix.rotate(_transform, _transform, e.rotation); } } } if (e.position && (e.position[0] !==0 || e.position[1] !== 0)) { matrix.translate(_transform, _transform, e.position); } // 保存这个变换矩阵 e._transform = _transform; return _transform; } self = { derive : derive, brush : brush, setContext : setContext, dashedLineTo : dashedLineTo, smoothBezier : smoothBezier, smoothSpline : smoothSpline, drawText : drawText, getHighlightStyle : getHighlightStyle, getHighlightZoom : getHighlightZoom, drift : drift, isCover : isCover, updateTransform : updateTransform }; return self; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:圆 * 可配图形属性: { // 基础属性 shape : 'circle', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,圆心横坐标 y : {number}, // 必须,圆心纵坐标 r : {number}, // 必须,圆半径 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'circle', id : '123456', zlevel : 1, style : { x : 200, y : 100, r : 50, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/circle',['require','./base','../shape'],function(require) { function Circle() { this.type = 'circle'; } Circle.prototype = { /** * 创建圆形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { ctx.arc(style.x, style.y, style.r, 0, Math.PI * 2, true); return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } return { x : Math.round(style.x - style.r - lineWidth / 2), y : Math.round(style.y - style.r - lineWidth / 2), width : style.r * 2 + lineWidth, height : style.r * 2 + lineWidth }; } }; var base = require('./base'); base.derive(Circle); var shape = require('../shape'); shape.define('circle', new Circle()); return Circle; } ); /** * zrender * * author: loutongbing@baidu.com * * shape类:椭圆 * Todo:excanvas bug ~ 连续scale保持?? IE8下不建议使用 * 可配图形属性: { // 基础属性 shape : 'ellipse', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,椭圆心横坐标 y : {number}, // 必须,椭圆心纵坐标 a : {number}, // 必须,椭圆横轴半径 b : {number}, // 必须,椭圆纵轴半径 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'ellipse', id : '123456', zlevel : 1, style : { x : 200, y : 100, a : 100, b : 50, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/ellipse',['require','./base','../shape'],function(require) { function Ellipse() { this.type = 'ellipse'; } Ellipse.prototype = { /** * 创建圆形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { var k = 0.5522848; var x = style.x; var y = style.y; var a =style.a; var b = style.b; var ox = a * k; // 水平控制点偏移量 var oy = b * k; // 垂直控制点偏移量 //从椭圆的左端点开始顺时针绘制四条三次贝塞尔曲线 ctx.moveTo(x - a, y); ctx.bezierCurveTo(x - a, y - oy, x - ox, y - b, x, y - b); ctx.bezierCurveTo(x + ox, y - b, x + a, y - oy, x + a, y); ctx.bezierCurveTo(x + a, y + oy, x + ox, y + b, x, y + b); ctx.bezierCurveTo(x - ox, y + b, x - a, y + oy, x - a, y); return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } return { x : Math.round(style.x - style.a - lineWidth / 2), y : Math.round(style.y - style.b - lineWidth / 2), width : style.a * 2 + lineWidth, height : style.b * 2 + lineWidth }; } }; var base = require('./base'); base.derive(Ellipse); var shape = require('../shape'); shape.define('ellipse', new Ellipse()); return Ellipse; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:直线 * 可配图形属性: { // 基础属性 shape : 'line', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { xStart : {number}, // 必须,起点横坐标 yStart : {number}, // 必须,起点纵坐标 xEnd : {number}, // 必须,终点横坐标 yEnd : {number}, // 必须,终点纵坐标 strokeColor : {color}, // 默认为'#000',线条颜色(轮廓),支持rgba lineType : {string}, // 默认为solid,线条类型,solid | dashed | dotted lineWidth : {number}, // 默认为1,线条宽度 lineCap : {string}, // 默认为butt,线帽样式。butt | round | square opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为end,附加文本位置。 // inside | start | end textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#000' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'line', id : '123456', zlevel : 1, style : { xStart : 100, yStart : 100, xEnd : 200, yEnd : 200, strokeColor : '#eee', lineWidth : 20, text : 'Baidu' }, myName : 'kener', //可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/line',['require','./base','../shape'],function(require) { function Line() { this.type = 'line'; this.brushTypeOnly = 'stroke'; //线条只能描边,填充后果自负 this.textPosition = 'end'; } Line.prototype = { /** * 创建线条路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { if (!style.lineType || style.lineType == 'solid') { //默认为实线 ctx.moveTo(style.xStart, style.yStart); ctx.lineTo(style.xEnd, style.yEnd); } else if (style.lineType == 'dashed' || style.lineType == 'dotted' ) { var dashLength =(style.lineWidth || 1) * (style.lineType == 'dashed' ? 5 : 1); this.dashedLineTo( ctx, style.xStart, style.yStart, style.xEnd, style.yEnd, dashLength ); } }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var lineWidth = style.lineWidth || 1; return { x : Math.min(style.xStart, style.xEnd) - lineWidth, y : Math.min(style.yStart, style.yEnd) - lineWidth, width : Math.abs(style.xStart - style.xEnd) + lineWidth, height : Math.abs(style.yStart - style.yEnd) + lineWidth }; } }; var base = require('./base'); base.derive(Line); var shape = require('../shape'); shape.define('line', new Line()); return Line; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:多边形 * 可配图形属性: { // 基础属性 shape : 'polygon', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { pointList : {Array}, // 必须,多边形各个顶角坐标 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'polygon', id : '123456', zlevel : 1, style : { pointList : [[10, 10], [300, 20], [298, 400], [50, 450]] color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/polygon',['require','./base','../shape'],function(require) { function Polygon() { this.type = 'polygon'; } Polygon.prototype = { /** * 画刷 * @param ctx 画布句柄 * @param e 形状实体 * @param isHighlight 是否为高亮状态 * @param updateCallback 需要异步加载资源的shape可以通过这个callback(e) * 让painter更新视图,base.brush没用,需要的话重载brush */ brush : function (ctx, e, isHighlight) { var style = e.style || {}; if (isHighlight) { // 根据style扩展默认高亮样式 style = this.getHighlightStyle( style, e.highlightStyle || {} ); } ctx.save(); this.setContext(ctx, style); // 设置transform if (e.__needTransform) { ctx.transform.apply(ctx,this.updateTransform(e)); } // 先fill再stroke var hasPath = false; if (style.brushType == 'fill' || style.brushType == 'both' || typeof style.brushType == 'undefined' // 默认为fill ) { ctx.beginPath(); if (style.lineType == 'dashed' || style.lineType == 'dotted' ) { // 特殊处理,虚线围不成path,实线再build一次 this.buildPath( ctx, { lineType: 'solid', lineWidth: style.lineWidth, pointList: style.pointList } ); hasPath = false; // 这个path不能用 } else { this.buildPath(ctx, style); hasPath = true; // 这个path能用 } ctx.closePath(); ctx.fill(); } if (style.lineWidth > 0 && (style.brushType == 'stroke' || style.brushType == 'both') ) { if (!hasPath) { ctx.beginPath(); this.buildPath(ctx, style); ctx.closePath(); } ctx.stroke(); } if (style.text) { this.drawText(ctx, style, e.style); } ctx.restore(); return; }, /** * 创建多边形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { // 虽然能重用brokenLine,但底层图形基于性能考虑,重复代码减少调用吧 var pointList = style.pointList; // 开始点和结束点重复 var start = pointList[0]; var end = pointList[pointList.length-1]; if (start && end) { if (start[0] == end[0] && start[1] == end[1]) { // 移除最后一个点 pointList.pop(); } } if (pointList.length < 2) { // 少于2个点就不画了~ return; } if (style.smooth && style.smooth !== 'spline') { var controlPoints = this.smoothBezier( pointList, style.smooth, true ); ctx.moveTo(pointList[0][0], pointList[0][1]); var cp1; var cp2; var p; var len = pointList.length; for (var i = 0; i < len; i++) { cp1 = controlPoints[i * 2]; cp2 = controlPoints[i * 2 + 1]; p = pointList[(i + 1) % len]; ctx.bezierCurveTo( cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1] ); } } else { if (style.smooth === 'spline') { pointList = this.smoothSpline(pointList, true); } if (!style.lineType || style.lineType == 'solid') { //默认为实线 ctx.moveTo(pointList[0][0],pointList[0][1]); for (var i = 1, l = pointList.length; i < l; i++) { ctx.lineTo(pointList[i][0],pointList[i][1]); } ctx.lineTo(pointList[0][0], pointList[0][1]); } else if (style.lineType == 'dashed' || style.lineType == 'dotted' ) { var dashLength = style._dashLength || (style.lineWidth || 1) * (style.lineType == 'dashed' ? 5 : 1); style._dashLength = dashLength; ctx.moveTo(pointList[0][0],pointList[0][1]); for (var i = 1, l = pointList.length; i < l; i++) { this.dashedLineTo( ctx, pointList[i - 1][0], pointList[i - 1][1], pointList[i][0], pointList[i][1], dashLength ); } this.dashedLineTo( ctx, pointList[pointList.length - 1][0], pointList[pointList.length - 1][1], pointList[0][0], pointList[0][1], dashLength ); } } return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var minX = Number.MAX_VALUE; var maxX = Number.MIN_VALUE; var minY = Number.MAX_VALUE; var maxY = Number.MIN_VALUE; var pointList = style.pointList; for(var i = 0, l = pointList.length; i < l; i++) { if (pointList[i][0] < minX) { minX = pointList[i][0]; } if (pointList[i][0] > maxX) { maxX = pointList[i][0]; } if (pointList[i][1] < minY) { minY = pointList[i][1]; } if (pointList[i][1] > maxY) { maxY = pointList[i][1]; } } var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } return { x : Math.round(minX - lineWidth / 2), y : Math.round(minY - lineWidth / 2), width : maxX - minX + lineWidth, height : maxY - minY + lineWidth }; } }; var base = require('./base'); base.derive(Polygon); var shape = require('../shape'); shape.define('polygon', new Polygon()); return Polygon; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:折线 * 可配图形属性: { // 基础属性 shape : 'brokenLine', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { pointList : {Array}, // 必须,各个顶角坐标 smooth : {Number}, // 默认为0 strokeColor : {color}, // 默认为'#000',线条颜色(轮廓),支持rgba lineType : {string}, // 默认为solid,线条类型,solid | dashed | dotted lineWidth : {number}, // 默认为1,线条宽度 lineCap : {string}, // 默认为butt,线帽样式。butt | round | square lineJoin : {string}, // 默认为miter,线段连接样式。miter | round | bevel miterLimit : {number}, // 默认为10,最大斜接长度,仅当lineJoin为miter时生效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为end,附加文本位置。 // start | end textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#000' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'brokenLine', id : '123456', zlevel : 1, style : { pointList : [[10, 10], [300, 20], [298, 400], [50, 450]], strokeColor : '#eee', lineWidth : 20, text : 'Baidu' }, myName : 'kener', //可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/brokenLine',['require','../shape','./base','../shape'],function(require) { function BrokenLine() { this.type = 'brokenLine'; this.brushTypeOnly = 'stroke'; //线条只能描边,填充后果自负 this.textPosition = 'end'; } BrokenLine.prototype = { /** * 创建多边形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { var pointList = style.pointList; if (pointList.length < 2) { // 少于2个点就不画了~ return; } if (style.smooth && style.smooth !== 'spline') { var controlPoints = this.smoothBezier( pointList, style.smooth, false ); ctx.moveTo(pointList[0][0], pointList[0][1]); var cp1; var cp2; var p; for (var i = 0, l = pointList.length; i < l - 1; i++) { cp1 = controlPoints[i * 2]; cp2 = controlPoints[i * 2 + 1]; p = pointList[i + 1]; ctx.bezierCurveTo( cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1] ); } } else { if (style.smooth === 'spline') { pointList = this.smoothSpline(pointList, false); } if (!style.lineType || style.lineType == 'solid') { //默认为实线 ctx.moveTo(pointList[0][0],pointList[0][1]); for (var i = 1, l = pointList.length; i < l; i++) { ctx.lineTo(pointList[i][0],pointList[i][1]); } } else if (style.lineType == 'dashed' || style.lineType == 'dotted' ) { var dashLength = (style.lineWidth || 1) * (style.lineType == 'dashed' ? 5 : 1); ctx.moveTo(pointList[0][0],pointList[0][1]); for (var i = 1, l = pointList.length; i < l; i++) { this.dashedLineTo( ctx, pointList[i - 1][0], pointList[i - 1][1], pointList[i][0], pointList[i][1], dashLength ); } } } return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var shape = require('../shape'); return shape.get('polygon').getRect(style); } }; var base = require('./base'); base.derive(BrokenLine); var shape = require('../shape'); shape.define('brokenLine', new BrokenLine()); return BrokenLine; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) , * strwind (@劲风FEI, yaofeifei@baidu.com) * * shape类:矩形 * 可配图形属性: { // 基础属性 shape : 'rectangle', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,左上角横坐标 y : {number}, // 必须,左上角纵坐标 width : {number}, // 必须,宽度 height : {number}, // 必须,高度 radius : {array}, // 默认为[0],圆角 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'rectangle', id : '123456', zlevel : 1, style : { x : 200, y : 100, width : 150, height : 50, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/rectangle',['require','./base','../shape'],function(require) { function Rectangle() { this.type = 'rectangle'; } Rectangle.prototype = { /** * 绘制圆角矩形 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ _buildRadiusPath: function(ctx, style) { //左上、右上、右下、左下角的半径依次为r1、r2、r3、r4 //r缩写为1 相当于 [1, 1, 1, 1] //r缩写为[1] 相当于 [1, 1, 1, 1] //r缩写为[1, 2] 相当于 [1, 2, 1, 2] //r缩写为[1, 2, 3] 相当于 [1, 2, 3, 2] var x = style.x; var y = style.y; var width = style.width; var height = style.height; var r = style.radius; var r1; var r2; var r3; var r4; 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; } ctx.moveTo(x + r1, y); ctx.lineTo(x + width - r2, y); r2 !== 0 && ctx.quadraticCurveTo( x + width, y, x + width, y + r2 ); ctx.lineTo(x + width, y + height - r3); r3 !== 0 && ctx.quadraticCurveTo( x + width, y + height, x + width - r3, y + height ); ctx.lineTo(x + r4, y + height); r4 !== 0 && ctx.quadraticCurveTo( x, y + height, x, y + height - r4 ); ctx.lineTo(x, y + r1); r1 !== 0 && ctx.quadraticCurveTo(x, y, x + r1, y); }, /** * 创建矩形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { if(!style.radius) { ctx.moveTo(style.x, style.y); ctx.lineTo(style.x + style.width, style.y); ctx.lineTo(style.x + style.width, style.y + style.height); ctx.lineTo(style.x, style.y + style.height); ctx.lineTo(style.x, style.y); //ctx.rect(style.x, style.y, style.width, style.height); } else { this._buildRadiusPath(ctx, style); } return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } return { x : Math.round(style.x - lineWidth / 2), y : Math.round(style.y - lineWidth / 2), width : style.width + lineWidth, height : style.height + lineWidth }; } }; var base = require('./base'); base.derive(Rectangle); var shape = require('../shape'); shape.define('rectangle', new Rectangle()); return Rectangle; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:圆环 * 可配图形属性: { // 基础属性 shape : 'ring', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,圆心横坐标 y : {number}, // 必须,圆心纵坐标 r0 : {number}, // 必须,内圆半径 r : {number}, // 必须,外圆半径 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为outside,附加文本位置。 // outside | inside textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'ring', id : '123456', zlevel : 1, style : { x : 200, y : 100, r : 50, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/ring',['require','./base','../shape'],function(require) { function Ring() { this.type = 'ring'; } Ring.prototype = { /** * 创建圆环路径,依赖扇形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { // 非零环绕填充优化 ctx.arc(style.x, style.y, style.r, 0, Math.PI * 2, false); ctx.moveTo(style.x + style.r0, style.y); ctx.arc(style.x, style.y, style.r0, 0, Math.PI * 2, true); return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } return { x : Math.round(style.x - style.r - lineWidth / 2), y : Math.round(style.y - style.r - lineWidth / 2), width : style.r * 2 + lineWidth, height : style.r * 2 + lineWidth }; } }; var base = require('./base'); base.derive(Ring); var shape = require('../shape'); shape.define('ring', new Ring()); return Ring; } ); /** * zrender: 数学辅助类 * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * sin:正弦函数,自动缓存 * cos:余弦函数,自动缓存 * degreeToRadian:角度转弧度 * radianToDegree:弧度转角度 */ define( 'zrender/tool/math',[],function() { /* var _cache = { sin : {}, //sin缓存 cos : {} //cos缓存 }; */ var _radians = Math.PI / 180; /** * @param angle 弧度(角度)参数 * @param isDegrees angle参数是否为角度计算,默认为false,angle为以弧度计量的角度 */ function sin(angle, isDegrees) { return Math.sin(isDegrees ? angle * _radians : angle); /* angle = (isDegrees ? angle * _radians : angle).toFixed(4); if(typeof _cache.sin[angle] == 'undefined') { _cache.sin[angle] = Math.sin(angle); } return _cache.sin[angle]; */ } /** * @param radians 弧度参数 */ function cos(angle, isDegrees) { return Math.cos(isDegrees ? angle * _radians : angle); /* angle = (isDegrees ? angle * _radians : angle).toFixed(4); if(typeof _cache.cos[angle] == 'undefined') { _cache.cos[angle] = Math.cos(angle); } return _cache.cos[angle]; */ } /** * 角度转弧度 * @param {Object} angle */ function degreeToRadian(angle) { return angle * _radians; } /** * 弧度转角度 * @param {Object} angle */ function radianToDegree(angle) { return angle / _radians; } return { sin : sin, cos : cos, degreeToRadian : degreeToRadian, radianToDegree : radianToDegree }; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:扇形 * 可配图形属性: { // 基础属性 shape : 'sector', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,圆心横坐标 y : {number}, // 必须,圆心纵坐标 r0 : {number}, // 默认为0,内圆半径,指定后将出现内弧,同时扇边长度 = r - r0 r : {number}, // 必须,外圆半径 startAngle : {number}, // 必须,起始角度[0, 360) endAngle : {number}, // 必须,结束角度(0, 360] brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为outside,附加文本位置。 // outside | inside textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'sector', id : '123456', zlevel : 1, style : { x : 200, y : 100, r : 50, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/sector',['require','../tool/math','../shape','./base','../shape'],function(require) { var math = require('../tool/math'); function Sector() { this.type = 'sector'; } Sector.prototype = { /** * 创建扇形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { var x = style.x; // 圆心x var y = style.y; // 圆心y var r0 = typeof style.r0 == 'undefined' // 形内半径[0,r) ? 0 : style.r0; var r = style.r; // 扇形外半径(0,r] var startAngle = style.startAngle; // 起始角度[0,360) var endAngle = style.endAngle; // 结束角度(0,360] if (Math.abs(endAngle - startAngle) >= 360) { // 大于360度的扇形简化为圆环画法 ctx.arc(x, y, r, 0, Math.PI * 2, false); if (r0 !== 0) { ctx.moveTo(x + r0, y); ctx.arc(x, y, r0, 0, Math.PI * 2, true); } return; } startAngle = math.degreeToRadian(startAngle); endAngle = math.degreeToRadian(endAngle); var PI2 = Math.PI * 2; var cosStartAngle = math.cos(startAngle); var sinStartAngle = math.sin(startAngle); ctx.moveTo( cosStartAngle * r0 + x, y - sinStartAngle * r0 ); ctx.lineTo( cosStartAngle * r + x, y - sinStartAngle * r ); ctx.arc(x, y, r, PI2 - startAngle, PI2 - endAngle, true); ctx.lineTo( math.cos(endAngle) * r0 + x, y - math.sin(endAngle) * r0 ); if (r0 !== 0) { ctx.arc(x, y, r0, PI2 - endAngle, PI2 - startAngle, false); } return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var shape = require('../shape'); var x = style.x; // 圆心x var y = style.y; // 圆心y var r0 = typeof style.r0 == 'undefined' // 形内半径[0,r) ? 0 : style.r0; var r = style.r; // 扇形外半径(0,r] var startAngle = style.startAngle; // 起始角度[0,360) var endAngle = style.endAngle; // 结束角度(0,360] if (Math.abs(endAngle - startAngle) >= 360) { // 大于360度的扇形简化为圆环bbox return shape.get('ring').getRect(style);; } startAngle = (720 + startAngle) % 360; endAngle = (720 + endAngle) % 360; if (endAngle <= startAngle) { endAngle += 360; } var pointList = []; if (startAngle <= 90 && endAngle >= 90) { pointList.push([ x, y - r ]); } if (startAngle <= 180 && endAngle >= 180) { pointList.push([ x - r, y ]); } if (startAngle <= 270 && endAngle >= 270) { pointList.push([ x, y + r ]); } if (startAngle <= 360 && endAngle >= 360) { pointList.push([ x + r, y ]); } startAngle = math.degreeToRadian(startAngle); endAngle = math.degreeToRadian(endAngle); pointList.push([ math.cos(startAngle) * r0 + x, y - math.sin(startAngle) * r0 ]); pointList.push([ math.cos(startAngle) * r + x, y - math.sin(startAngle) * r ]); pointList.push([ math.cos(endAngle) * r + x, y - math.sin(endAngle) * r ]); pointList.push([ math.cos(endAngle) * r0 + x, y - math.sin(endAngle) * r0 ]); return shape.get('polygon').getRect({ brushType : style.brushType, lineWidth : style.lineWidth, pointList : pointList }); } }; var base = require('./base'); base.derive(Sector); var shape = require('../shape'); shape.define('sector', new Sector()); return Sector; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:文字 * 可配图形属性: { // 基础属性 shape : 'text', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,横坐标 y : {number}, // 必须,纵坐标 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',线条颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 必须,文本内容 textFont : {string}, // 默认为null,文本文字样式,eg:'bold 18px verdana' textAlign : {string}, // 默认为start,文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认为middle,文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic maxWidth : {number} // 默认为null,最大宽度 }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'text', id : '123456', zlevel : 1, style : { x : 200, y : 100, color : 'red', text : 'Baidu' }, myName : 'kener', //可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/text',['require','../tool/area','./base','../shape'],function(require) { var area = require('../tool/area'); function Text() { this.type = 'text'; } Text.prototype = { /** * 画刷,重载基类方法 * @param {Context2D} ctx Canvas 2D上下文 * @param e 图形形状实体 * @param isHighlight 是否为高亮状态 */ brush : function(ctx, e, isHighlight) { var style = e.style || {}; if (isHighlight) { // 根据style扩展默认高亮样式 style = this.getHighlightStyle( style, e.highlightStyle || {} ); } if (typeof style.text == 'undefined') { return; } ctx.save(); this.setContext(ctx, style); // 设置transform if (e.__needTransform) { ctx.transform.apply(ctx,this.updateTransform(e)); } if (style.textFont) { ctx.font = style.textFont; } ctx.textAlign = style.textAlign || 'start'; ctx.textBaseline = style.textBaseline || 'middle'; var text = (style.text + '').split('\n'); var lineHeight = area.getTextHeight('国', style.textFont); var rect = this.getRect(style); var x = style.x; var y; if (style.textBaseline == 'top') { y = rect.y; } else if (style.textBaseline == 'bottom') { y = rect.y + lineHeight; } else { y = rect.y + lineHeight / 2; } for (var i = 0, l = text.length; i < l; i++) { if (style.maxWidth) { switch (style.brushType) { case 'fill': ctx.fillText( text[i], x, y, style.maxWidth ); break; case 'stroke': ctx.strokeText( text[i], x, y, style.maxWidth ); break; case 'both': ctx.fillText( text[i], x, y, style.maxWidth ); ctx.strokeText( text[i], x, y, style.maxWidth ); break; default: ctx.fillText( text[i], x, y, style.maxWidth ); } } else{ switch (style.brushType) { case 'fill': ctx.fillText(text[i], x, y); break; case 'stroke': ctx.strokeText(text[i], x, y); break; case 'both': ctx.fillText(text[i], x, y); ctx.strokeText(text[i], x, y); break; default: ctx.fillText(text[i], x, y); } } y += lineHeight; } ctx.restore(); return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var width = area.getTextWidth(style.text, style.textFont); var height = area.getTextHeight(style.text, style.textFont); var textX = style.x; //默认start == left if (style.textAlign == 'end' || style.textAlign == 'right') { textX -= width; } else if (style.textAlign == 'center') { textX -= (width / 2); } var textY; if (style.textBaseline == 'top') { textY = style.y; } else if (style.textBaseline == 'bottom') { textY = style.y - height; } else { // middle textY = style.y - height / 2; } return { x : textX, y : textY, width : width, height : height }; } }; var base = require('./base'); base.derive(Text); var shape = require('../shape'); shape.define('text', new Text()); return Text; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:心形 * 可配图形属性: { // 基础属性 shape : 'heart', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,心形内部尖端横坐标 y : {number}, // 必须,心形内部尖端纵坐标 a : {number}, // 必须,心形横宽(中轴线到水平边缘最宽处距离) b : {number}, // 必须,心形纵高(内尖到外尖距离) brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为outside,附加文本位置。 // outside | inside textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'heart', id : '123456', zlevel : 1, style : { x : 200, y : 100, a : 50, b : 80, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/heart',['require','./base','../shape'],function(require) { function Heart() { this.type = 'heart'; } Heart.prototype = { /** * 创建扇形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { ctx.moveTo(style.x, style.y); ctx.bezierCurveTo( style.x + style.a / 2, style.y - style.b * 2 / 3, style.x + style.a * 2, style.y + style.b / 3, style.x, style.y + style.b ); ctx.bezierCurveTo( style.x - style.a * 2, style.y + style.b / 3, style.x - style.a / 2, style.y - style.b * 2 / 3, style.x, style.y ); return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } return { x : Math.round(style.x - style.a - lineWidth / 2), y : Math.round(style.y - style.b / 4 - lineWidth / 2), width : style.a * 2 + lineWidth, height : style.b * 5 / 4 + lineWidth }; } }; var base = require('./base'); base.derive(Heart); var shape = require('../shape'); shape.define('heart', new Heart()); return Heart; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:水滴 * 可配图形属性: { // 基础属性 shape : 'heart', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,水滴中心横坐标 y : {number}, // 必须,水滴中心纵坐标 a : {number}, // 必须,水滴横宽(中心到水平边缘最宽处距离) b : {number}, // 必须,水滴纵高(中心到尖端距离) brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为outside,附加文本位置。 // outside | inside textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'droplet', id : '123456', zlevel : 1, style : { x : 200, y : 100, a : 50, b : 80, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/droplet',['require','./base','../shape'],function(require) { function Droplet() { this.type = 'droplet'; } Droplet.prototype = { /** * 创建扇形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { ctx.moveTo(style.x, style.y + style.a); ctx.bezierCurveTo( style.x + style.a, style.y + style.a, style.x + style.a * 3 / 2, style.y - style.a / 3, style.x, style.y - style.b ); ctx.bezierCurveTo( style.x - style.a * 3 / 2, style.y - style.a / 3, style.x - style.a, style.y + style.a, style.x, style.y + style.a ); return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } return { x : Math.round(style.x - style.a - lineWidth / 2), y : Math.round(style.y - style.b - lineWidth / 2), width : style.a * 2 + lineWidth, height : style.a + style.b + lineWidth }; } }; var base = require('./base'); base.derive(Droplet); var shape = require('../shape'); shape.define('droplet', new Droplet()); return Droplet; } ); /** * zrender * * author: CrossDo (chenhuaimu@baidu.com) * * shape类:路径 * 可配图形属性: { // 基础属性 shape : 'path', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { path : {string},// 必须,路径。例如:M 0 0 L 0 10 L 10 10 Z (一个三角形) //M = moveto //L = lineto //H = horizontal lineto //V = vertical lineto //C = curveto //S = smooth curveto //Q = quadratic Belzier curve //T = smooth quadratic Belzier curveto //Z = closepath x : {number}, // 必须,x轴坐标 y : {number}, // 必须,y轴坐标 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } **/ define('zrender/shape/path',['require','./base','../shape'],function(require) { function Path() { this.type = 'path'; } Path.prototype = { _parsePathData : function(data) { if (!data) { return []; } // command string var cs = data; // command chars var cc = [ 'm', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z', 'c', 'C', 'q', 'Q', 't', 'T', 's', 'S', 'a', 'A' ]; cs = cs.replace(/-/g, ' -'); cs = cs.replace(/ /g, ' '); cs = cs.replace(/ /g, ','); cs = cs.replace(/,,/g, ','); var n; // create pipes so that we can split the data for (n = 0; n < cc.length; n++) { cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]); } // create array var arr = cs.split('|'); var ca = []; // init context point var cpx = 0; var cpy = 0; for (n = 1; n < arr.length; n++) { var str = arr[n]; var c = str.charAt(0); str = str.slice(1); str = str.replace(new RegExp('e,-', 'g'), 'e-'); var p = str.split(','); if (p.length > 0 && p[0] === '') { p.shift(); } for (var i = 0; i < p.length; i++) { p[i] = parseFloat(p[i]); } while (p.length > 0) { if (isNaN(p[0])) { break; } var cmd = null; var points = []; var ctlPtx; var ctlPty; var prevCmd; var rx; var ry; var psi; var fa; var fs; var x1 = cpx; var y1 = cpy; // convert l, H, h, V, and v to L switch (c) { case 'l': cpx += p.shift(); cpy += p.shift(); cmd = 'L'; points.push(cpx, cpy); break; case 'L': cpx = p.shift(); cpy = p.shift(); points.push(cpx, cpy); break; case 'm': cpx += p.shift(); cpy += p.shift(); cmd = 'M'; points.push(cpx, cpy); c = 'l'; break; case 'M': cpx = p.shift(); cpy = p.shift(); cmd = 'M'; points.push(cpx, cpy); c = 'L'; break; case 'h': cpx += p.shift(); cmd = 'L'; points.push(cpx, cpy); break; case 'H': cpx = p.shift(); cmd = 'L'; points.push(cpx, cpy); break; case 'v': cpy += p.shift(); cmd = 'L'; points.push(cpx, cpy); break; case 'V': cpy = p.shift(); cmd = 'L'; points.push(cpx, cpy); break; case 'C': points.push(p.shift(), p.shift(), p.shift(), p.shift()); cpx = p.shift(); cpy = p.shift(); points.push(cpx, cpy); break; case 'c': points.push( cpx + p.shift(), cpy + p.shift(), cpx + p.shift(), cpy + p.shift() ); cpx += p.shift(); cpy += p.shift(); cmd = 'C'; points.push(cpx, cpy); break; case 'S': ctlPtx = cpx; ctlPty = cpy; prevCmd = ca[ca.length - 1]; if (prevCmd.command === 'C') { ctlPtx = cpx + (cpx - prevCmd.points[2]); ctlPty = cpy + (cpy - prevCmd.points[3]); } points.push(ctlPtx, ctlPty, p.shift(), p.shift()); cpx = p.shift(); cpy = p.shift(); cmd = 'C'; points.push(cpx, cpy); break; case 's': ctlPtx = cpx, ctlPty = cpy; prevCmd = ca[ca.length - 1]; if (prevCmd.command === 'C') { ctlPtx = cpx + (cpx - prevCmd.points[2]); ctlPty = cpy + (cpy - prevCmd.points[3]); } points.push( ctlPtx, ctlPty, cpx + p.shift(), cpy + p.shift() ); cpx += p.shift(); cpy += p.shift(); cmd = 'C'; points.push(cpx, cpy); break; case 'Q': points.push(p.shift(), p.shift()); cpx = p.shift(); cpy = p.shift(); points.push(cpx, cpy); break; case 'q': points.push(cpx + p.shift(), cpy + p.shift()); cpx += p.shift(); cpy += p.shift(); cmd = 'Q'; points.push(cpx, cpy); break; case 'T': ctlPtx = cpx, ctlPty = cpy; prevCmd = ca[ca.length - 1]; if (prevCmd.command === 'Q') { ctlPtx = cpx + (cpx - prevCmd.points[0]); ctlPty = cpy + (cpy - prevCmd.points[1]); } cpx = p.shift(); cpy = p.shift(); cmd = 'Q'; points.push(ctlPtx, ctlPty, cpx, cpy); break; case 't': ctlPtx = cpx, ctlPty = cpy; prevCmd = ca[ca.length - 1]; if (prevCmd.command === 'Q') { ctlPtx = cpx + (cpx - prevCmd.points[0]); ctlPty = cpy + (cpy - prevCmd.points[1]); } cpx += p.shift(); cpy += p.shift(); cmd = 'Q'; points.push(ctlPtx, ctlPty, cpx, cpy); break; case 'A': rx = p.shift(); ry = p.shift(); psi = p.shift(); fa = p.shift(); fs = p.shift(); x1 = cpx, y1 = cpy; cpx = p.shift(), cpy = p.shift(); cmd = 'A'; points = this._convertPoint( x1, y1, cpx, cpy, fa, fs, rx, ry, psi ); break; case 'a': rx = p.shift(); ry = p.shift(); psi = p.shift(); fa = p.shift(); fs = p.shift(); x1 = cpx, y1 = cpy; cpx += p.shift(); cpy += p.shift(); cmd = 'A'; points = this._convertPoint( x1, y1, cpx, cpy, fa, fs, rx, ry, psi ); break; } ca.push({ command : cmd || c, points : points }); } if (c === 'z' || c === 'Z') { ca.push({ command : 'z', points : [] }); } } return ca; }, _convertPoint : function(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg) { var psi = psiDeg * (Math.PI / 180.0); var xp = Math.cos(psi) * (x1 - x2) / 2.0 + Math.sin(psi) * (y1 - y2) / 2.0; var yp = -1 * Math.sin(psi) * (x1 - x2) / 2.0 + Math.cos(psi) * (y1 - y2) / 2.0; var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry); if (lambda > 1) { rx *= Math.sqrt(lambda); ry *= Math.sqrt(lambda); } var f = Math.sqrt((((rx * rx) * (ry * ry)) - ((rx * rx) * (yp * yp)) - ((ry * ry) * (xp * xp))) / ((rx * rx) * (yp * yp) + (ry * ry) * (xp * xp)) ); if (fa === fs) { f *= -1; } if (isNaN(f)) { f = 0; } var cxp = f * rx * yp / ry; var cyp = f * -ry * xp / rx; var cx = (x1 + x2) / 2.0 + Math.cos(psi) * cxp - Math.sin(psi) * cyp; var cy = (y1 + y2) / 2.0 + Math.sin(psi) * cxp + Math.cos(psi) * cyp; var vMag = function(v) { return Math.sqrt(v[0] * v[0] + v[1] * v[1]); }; var vRatio = function(u, v) { return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v)); }; var vAngle = function(u, v) { return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * Math.acos(vRatio(u, v)); }; var theta = vAngle([ 1, 0 ], [ (xp - cxp) / rx, (yp - cyp) / ry ]); var u = [ (xp - cxp) / rx, (yp - cyp) / ry ]; var v = [ (-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry ]; var dTheta = vAngle(u, v); if (vRatio(u, v) <= -1) { dTheta = Math.PI; } if (vRatio(u, v) >= 1) { dTheta = 0; } if (fs === 0 && dTheta > 0) { dTheta = dTheta - 2 * Math.PI; } if (fs === 1 && dTheta < 0) { dTheta = dTheta + 2 * Math.PI; } return [ cx, cy, rx, ry, theta, dTheta, psi, fs ]; }, /** * 创建路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { var path = style.path; var pathArray = this._parsePathData(path); // 平移坐标 var x = style.x || 0; var y = style.y || 0; var p; // 记录边界点,用于判断inside var pointList = style.pointList = []; var singlePointList = []; for (var i = 0, l = pathArray.length; i < l; i++) { if (pathArray[i].command.toUpperCase() == 'M') { singlePointList.length > 0 && pointList.push(singlePointList); singlePointList = []; } p = pathArray[i].points; for (var j = 0, k = p.length; j < k; j += 2) { singlePointList.push([p[j] + x, p[j+1] + y]); } } singlePointList.length > 0 && pointList.push(singlePointList); var c; for (var i = 0, l = pathArray.length; i < l; i++) { c = pathArray[i].command; p = pathArray[i].points; // 平移变换 for (var j = 0, k = p.length; j < k; j++) { if (j % 2 === 0) { p[j] += x; } else { p[j] += y; } } switch (c) { case 'L': ctx.lineTo(p[0], p[1]); break; case 'M': ctx.moveTo(p[0], p[1]); break; case 'C': ctx.bezierCurveTo(p[0], p[1], p[2], p[3], p[4], p[5]); break; case 'Q': ctx.quadraticCurveTo(p[0], p[1], p[2], p[3]); break; case 'A': var cx = p[0]; var cy = p[1]; var rx = p[2]; var ry = p[3]; var theta = p[4]; var dTheta = p[5]; var psi = p[6]; var fs = p[7]; var r = (rx > ry) ? rx : ry; var scaleX = (rx > ry) ? 1 : rx / ry; var scaleY = (rx > ry) ? ry / rx : 1; ctx.translate(cx, cy); ctx.rotate(psi); ctx.scale(scaleX, scaleY); ctx.arc(0, 0, r, theta, theta + dTheta, 1 - fs); ctx.scale(1 / scaleX, 1 / scaleY); ctx.rotate(-psi); ctx.translate(-cx, -cy); break; case 'z': ctx.closePath(); break; } } return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style 样式 */ getRect : function(style) { var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } var minX = Number.MAX_VALUE; var maxX = Number.MIN_VALUE; var minY = Number.MAX_VALUE; var maxY = Number.MIN_VALUE; // 平移坐标 var x = style.x || 0; var y = style.y || 0; var pathArray = this._parsePathData(style.path); for (var i = 0; i < pathArray.length; i++) { var p = pathArray[i].points; for (var j = 0; j < p.length; j++) { if (j % 2 === 0) { if (p[j] + x < minX) { minX = p[j] + x; } if (p[j] + x > maxX) { maxX = p[j] + x; } } else { if (p[j] + y < minY) { minY = p[j] + y; } if (p[j] + y > maxY) { maxY = p[j] + y; } } } } var rect; if (minX === Number.MAX_VALUE || maxX === Number.MIN_VALUE || minY === Number.MAX_VALUE || maxY === Number.MIN_VALUE ) { rect = { x : 0, y : 0, width : 0, height : 0 }; } else { rect = { x : Math.round(minX - lineWidth / 2), y : Math.round(minY - lineWidth / 2), width : maxX - minX + lineWidth, height : maxY - minY + lineWidth }; } return rect; } }; var base = require('./base'); base.derive(Path); var shape = require('../shape'); shape.define('path', new Path()); return Path; }); /** * zrender * * @author lang( shenyi01@baidu.com ) * * shape类:图片 * 可配图形属性: { // 基础属性 shape : 'image', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,左上角横坐标 y : {number}, // 必须,左上角纵坐标 width : {number}, // 可选,宽度 height : {number}, // 可选,高度 sx : {number}, // 可选, 从图片中裁剪的x sy : {number}, // 可选, 从图片中裁剪的y sWidth : {number}, // 可选, 从图片中裁剪的宽度 sHeight : {number}, // 可选, 从图片中裁剪的高度 image : {string|Image} // 必须,图片url或者图片对象 lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'image', id : '123456', zlevel : 1, style : { x : 200, y : 100, width : 150, height : 50, image : 'tests.jpg', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/image',['require','./base','../shape'],function(require) { var _cache = {}; var _needsRefresh = []; var _refreshTimeout; function ZImage() { this.type = 'image'; } ZImage.prototype = { brush : function(ctx, e, isHighlight, refresh) { var style = e.style || {}; if (isHighlight) { // 根据style扩展默认高亮样式 style = this.getHighlightStyle( style, e.highlightStyle || {} ); } var image = style.image; if (typeof(image) === 'string') { var src = image; if (_cache[src]) { image = _cache[src]; } else { image = new Image();//document.createElement('image'); image.onload = function(){ image.onload = null; clearTimeout( _refreshTimeout ); _needsRefresh.push( e ); // 防止因为缓存短时间内触发多次onload事件 _refreshTimeout = setTimeout(function(){ refresh( _needsRefresh ); // 清空needsRefresh _needsRefresh = []; }, 10); }; _cache[ src ] = image; image.src = src; } } if (image) { //图片已经加载完成 if (window.ActiveXObject) { if (image.readyState != 'complete') { return; } } else { if (!image.complete) { return; } } ctx.save(); this.setContext(ctx, style); // 设置transform if (e.__needTransform) { ctx.transform.apply(ctx,this.updateTransform(e)); } var width = style.width || image.width; var height = style.height || image.height; var x = style.x; var y = style.y; 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); } // 如果没设置宽和高的话自动根据图片宽高设置 style.width = width; style.height = height; e.style.width = width; e.style.height = height; if (style.text) { this.drawText(ctx, style, e.style); } ctx.restore(); } return; }, /** * 创建路径,用于判断hover时调用isPointInPath~ * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { ctx.rect(style.x, style.y, style.width, style.height); return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { return { x : style.x, y : style.y, width : style.width, height : style.height }; } }; var base = require('./base'); base.derive(ZImage); var shape = require('../shape'); shape.define('image', new ZImage()); return ZImage; } ); /** * zrender * * @author Neil (杨骥, yangji01@baidu.com) * * shape类:贝塞尔曲线 * 可配图形属性: { // 基础属性 shape : 'beziercurve', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { xStart : {number}, // 必须,起点横坐标 yStart : {number}, // 必须,起点纵坐标 cpX1 : {number}, // 必须,第一个关联点横坐标 cpY1 : {number}, // 必须,第一个关联点纵坐标 cpX2 : {number}, // 可选,第二个关联点横坐标 缺省即为二次贝塞尔曲线 cpY2 : {number}, // 可选,第二个关联点纵坐标 xEnd : {number}, // 必须,终点横坐标 yEnd : {number}, // 必须,终点纵坐标 strokeColor : {color}, // 默认为'#000',线条颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度 lineCap : {string}, // 默认为butt,线帽样式。butt | round | square opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为end,附加文本位置。 // inside | start | end textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#000' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'beziercurve', id : '123456', zlevel : 1, style : { xStart : 100, yStart : 100, xEnd : 200, yEnd : 200, strokeColor : '#eee', lineWidth : 20, text : 'Baidu' }, myName : 'kener', //可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/beziercurve',['require','./base','../shape'],function(require) { function Beziercurve() { this.type = 'beziercurve'; this.brushTypeOnly = 'stroke'; //线条只能描边,填充后果自负 this.textPosition = 'end'; } Beziercurve.prototype = { /** * 创建线条路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { ctx.moveTo(style.xStart, style.yStart); if (typeof style.cpX2 != 'undefined' && typeof style.cpY2 != 'undefined' ) { ctx.bezierCurveTo( style.cpX1, style.cpY1, style.cpX2, style.cpY2, style.xEnd, style.yEnd ); } else { ctx.quadraticCurveTo( style.cpX1, style.cpY1, style.xEnd, style.yEnd ); } }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var _minX = Math.min(style.xStart, style.xEnd, style.cpX1); var _minY = Math.min(style.yStart, style.yEnd, style.cpY1); var _maxX = Math.max(style.xStart, style.xEnd, style.cpX1); var _maxY = Math.max(style.yStart, style.yEnd, style.cpY1); var _x2 = style.cpX2; var _y2 = style.cpY2; if (typeof _x2 != 'undefined' && typeof _y2 != 'undefined' ) { _minX = Math.min(_minX, _x2); _minY = Math.min(_minY, _y2); _maxX = Math.max(_maxX, _x2); _maxY = Math.max(_maxY, _y2); } var lineWidth = style.lineWidth || 1; return { x : _minX - lineWidth, y : _minY - lineWidth, width : _maxX - _minX + lineWidth, height : _maxY - _minY + lineWidth }; } }; var base = require('./base'); base.derive(Beziercurve); var shape = require('../shape'); shape.define('beziercurve', new Beziercurve()); return Beziercurve; } ); /** * zrender * * @author sushuang (宿爽, sushuang@baidu.com) * * shape类:n角星(n>3) * 可配图形属性: { // 基础属性 shape : 'star', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,n角星外接圆心横坐标 y : {number}, // 必须,n角星外接圆心纵坐标 r : {number}, // 必须,n角星外接圆半径 r0 : {number}, // n角星内部顶点(凹点)的外接圆半径, // 如果不指定此参数,则自动计算:取相隔外部顶点连线的交点作内部顶点 n : {number}, // 必须,指明几角星 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 lineJoin : {string}, // 默认为miter,线段连接样式。miter | round | bevel shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为outside,附加文本位置。 // outside | inside textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'star', id : '123456', zlevel : 1, style : { x : 200, y : 100, r : 150, n : 5, color : '#eee' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/star',['require','../tool/math','./base','../shape'],function(require) { var math = require('../tool/math'); var sin = math.sin; var cos = math.cos; var PI = Math.PI; function Star() { this.type = 'heart'; } Star.prototype = { /** * 创建n角星(n>3)路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { var n = style.n; if (!n || n < 2) { return; } var x = style.x; var y = style.y; var r = style.r; var r0 = style.r0; // 如果未指定内部顶点外接圆半径,则自动计算 if (r0 == null) { r0 = n > 4 // 相隔的外部顶点的连线的交点, // 被取为内部交点,以此计算r0 ? r * cos(2 * PI / n) / cos(PI / n) // 二三四角星的特殊处理 : r / 3; } var dStep = PI / n; var deg = -PI / 2; var xStart = x + r * cos(deg); var yStart = y + r * sin(deg); deg += dStep; // 记录边界点,用于判断inside var pointList = style.pointList = []; pointList.push([xStart, yStart]); for (var i = 0, end = n * 2 - 1, ri; i < end; i ++) { ri = i % 2 === 0 ? r0 : r; pointList.push([x + ri * cos(deg), y + ri * sin(deg)]); deg += dStep; } pointList.push([xStart, yStart]); // 绘制 ctx.moveTo(pointList[0][0], pointList[0][1]); for (var i = 0; i < pointList.length; i ++) { ctx.lineTo(pointList[i][0], pointList[i][1]); } return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } return { x : Math.round(style.x - style.r - lineWidth / 2), y : Math.round(style.y - style.r - lineWidth / 2), width : style.r * 2 + lineWidth, height : style.r * 2 + lineWidth }; } }; var base = require('./base'); base.derive(Star); var shape = require('../shape'); shape.define('star', new Star()); return Star; } ); /** * zrender * * @author sushuang (宿爽, sushuang@baidu.com) * * shape类:正n边形(n>=3) * 可配图形属性: { // 基础属性 shape : 'isogon', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,正n边形外接圆心横坐标 y : {number}, // 必须,正n边形外接圆心纵坐标 r : {number}, // 必须,正n边形外接圆半径 n : {number}, // 必须,指明正几边形 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 lineJoin : {string}, // 默认为miter,线段连接样式。miter | round | bevel shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为outside,附加文本位置。 // outside | inside textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'isogon', id : '123456', zlevel : 1, style : { x : 400, y : 100, r : 150, n : 7, color : '#eee' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'zrender/shape/isogon',['require','../tool/math','./base','../shape'],function(require) { var math = require('../tool/math'); var sin = math.sin; var cos = math.cos; var PI = Math.PI; function Isogon() { this.type = 'isogon'; } Isogon.prototype = { /** * 创建n角星(n>=3)路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { var n = style.n; if (!n || n < 2) { return; } var x = style.x; var y = style.y; var r = style.r; var dStep = 2 * PI / n; var deg = -PI / 2; var xStart = x + r * cos(deg); var yStart = y + r * sin(deg); deg += dStep; // 记录边界点,用于判断insight var pointList = style.pointList = []; pointList.push([xStart, yStart]); for (var i = 0, end = n - 1; i < end; i ++) { pointList.push([x + r * cos(deg), y + r * sin(deg)]); deg += dStep; } pointList.push([xStart, yStart]); // 绘制 ctx.moveTo(pointList[0][0], pointList[0][1]); for (var i = 0; i < pointList.length; i ++) { ctx.lineTo(pointList[i][0], pointList[i][1]); } return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } return { x : Math.round(style.x - style.r - lineWidth / 2), y : Math.round(style.y - style.r - lineWidth / 2), width : style.r * 2 + lineWidth, height : style.r * 2 + lineWidth }; } }; var base = require('./base'); base.derive(Isogon); var shape = require('../shape'); shape.define('isogon', new Isogon()); return Isogon; } ); /** * 缓动代码来自 https://github.com/sole/tween.js/blob/master/src/Tween.js * author: lang(shenyi01@baidu.com) */ define( 'zrender/animation/easing',[],function() { var Easing = { // 线性 Linear: function(k) { return k; }, // 二次方的缓动(t^2) QuadraticIn: function(k) { return k * k; }, QuadraticOut: function(k) { return k * (2 - k); }, QuadraticInOut: function(k) { if ((k *= 2) < 1) { return 0.5 * k * k; } return - 0.5 * (--k * (k - 2) - 1); }, // 三次方的缓动(t^3) CubicIn: function(k) { return k * k * k; }, CubicOut: function(k) { return --k * k * k + 1; }, CubicInOut: function(k) { if ((k *= 2) < 1) { return 0.5 * k * k * k; } return 0.5 * ((k -= 2) * k * k + 2); }, // 四次方的缓动(t^4) QuarticIn: function(k) { return k * k * k * k; }, QuarticOut: function(k) { return 1 - (--k * k * k * k); }, 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) QuinticIn: function(k) { return k * k * k * k * k; }, QuinticOut: function(k) { return --k * k * k * k * k + 1; }, 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)) SinusoidalIn: function(k) { return 1 - Math.cos(k * Math.PI / 2); }, SinusoidalOut: function(k) { return Math.sin(k * Math.PI / 2); }, SinusoidalInOut: function(k) { return 0.5 * (1 - Math.cos(Math.PI * k)); }, // 指数曲线的缓动(2^t) ExponentialIn: function(k) { return k === 0 ? 0 : Math.pow(1024, k - 1); }, ExponentialOut: function(k) { return k === 1 ? 1 : 1 - Math.pow(2, - 10 * k); }, 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)) CircularIn: function(k) { return 1 - Math.sqrt(1 - k * k); }, CircularOut: function(k) { return Math.sqrt(1 - (--k * k)); }, 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); }, // 创建类似于弹簧在停止前来回振荡的动画 ElasticIn: function(k) { var s, a = 0.1, 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)); }, ElasticOut: function(k) { var s, a = 0.1, 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); }, ElasticInOut: function(k) { var s, a = 0.1, 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; }, // 在某一动画开始沿指示的路径进行动画处理前稍稍收回该动画的移动 BackIn: function(k) { var s = 1.70158; return k * k * ((s + 1) * k - s); }, BackOut: function(k) { var s = 1.70158; return --k * k * ((s + 1) * k + s) + 1; }, 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); }, // 创建弹跳效果 BounceIn: function(k) { return 1 - Easing.BounceOut(1 - k); }, 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; } }, BounceInOut: function(k) { if (k < 0.5) { return Easing.BounceIn(k * 2) * 0.5; } return Easing.BounceOut(k * 2 - 1) * 0.5 + 0.5; } }; return Easing; } ); /** * 动画主控制器 * @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) */ define( 'zrender/animation/clip',['require','./easing'],function(require) { var Easing = require('./easing'); var Clip = function(options) { this._targetPool = options.target || {}; if (this._targetPool.constructor != Array) { this._targetPool = [this._targetPool]; } //生命周期 this._life = options.life || 1000; //延时 this._delay = options.delay || 0; //开始时间 this._startTime = new Date().getTime() + this._delay;//单位毫秒 //结束时间 this._endTime = this._startTime + this._life*1000; //是否循环 this.loop = typeof(options.loop) == 'undefined' ? false : options.loop; this.gap = options.gap || 0; this.easing = options.easing || 'Linear'; this.onframe = options.onframe || null; this.ondestroy = options.ondestroy || null; this.onrestart = options.onrestart || null; }; Clip.prototype = { step : function(time) { var percent = (time - this._startTime) / this._life; //还没开始 if (percent < 0) { return; } percent = Math.min(percent, 1); var easingFunc = typeof(this.easing) == 'string' ? Easing[this.easing] : this.easing; var schedule; if (typeof easingFunc === 'function') { schedule = easingFunc(percent); }else{ schedule = percent; } this.fire('frame', schedule); //结束 if (percent == 1) { if (this.loop) { this.restart(); // 重新开始周期 // 抛出而不是直接调用事件直到 stage.update 后再统一调用这些事件 return 'restart'; }else{ // 动画完成将这个控制器标识为待删除 // 在Animation.update中进行批量删除 this._needsRemove = true; return 'destroy'; } }else{ return null; } }, restart : function() { this._startTime = new Date().getTime() + this.gap; }, fire : function(eventType, arg) { for(var i = 0, len = this._targetPool.length; i < len; i++) { if (this['on' + eventType]) { this['on' + eventType](this._targetPool[i], arg); } } } }; Clip.prototype.constructor = Clip; return Clip; } ); /** * 动画主类, 调度和管理所有动画控制器 * * @author pissang(https://github.com/pissang) * * @class : Animation * @config : stage(optional) 绘制类, 需要提供update接口 * @config : onframe(optional) * @method : add * @method : remove * @method : update * @method : start * @method : stop */ define( 'zrender/animation/animation',['require','./clip'],function(require) { var Clip = require('./clip'); var requestAnimationFrame = window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(func){setTimeout(func, 16);}; var arraySlice = Array.prototype.slice; var Animation = function(options) { options = options || {}; this.stage = options.stage || {}; this.onframe = options.onframe || function() {}; // private properties this._clips = []; this._running = false; this._time = 0; }; Animation.prototype = { add : function(clip) { this._clips.push(clip); }, remove : function(clip) { var idx = this._clips.indexOf(clip); if (idx >= 0) { this._clips.splice(idx, 1); } }, update : function() { var time = new Date().getTime(); //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); // Throw out the events need to be called after // stage.update, like destroy if (e) { deferredEvents.push(e); deferredClips.push(clip); } } if (this.stage && this.stage.update && this._clips.length ) { this.stage.update(); } // 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(); }, start : function() { var self = this; this._running = true; function step() { if (self._running) { self.update(); requestAnimationFrame(step); } } requestAnimationFrame(step); }, stop : function() { this._running = false; }, clear : function() { this._clips = []; }, animate : function(target, options) { options = options || {}; var deferred = new Deferred( target, options.loop, options.getter, options.setter ); deferred.animation = this; return deferred; } }; Animation.prototype.constructor = Animation; function _defaultGetter(target, key) { return target[key]; } function _defaultSetter(target, key, value) { target[key] = value; } function _interpolateNumber(p0, p1, percent) { return (p1 - p0) * percent + p0; } 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 = 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 ); } } } } function _isArrayLike(data) { if (typeof(data) === 'undefined') { return false; } else if (typeof(data) == 'string') { return false; } else { return typeof(data.length) !== 'undefined'; } } 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 ); } } } } 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 Deferred(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 = []; } Deferred.prototype = { when : function(time /* ms */, props) { for (var propName in props) { if (! this._tracks[propName]) { this._tracks[propName] = []; // Initialize value this._tracks[propName].push({ time : 0, value : this._getter(this._target, propName) }); } this._tracks[propName].push({ time : parseInt(time, 10), value : props[propName] }); } return this; }, during : function(callback) { this._onframeList.push(callback); return this; }, start : function(easing) { var self = this; var setter = this._setter; var getter = this._getter; var onFrameListLen = self._onframeList.length; var useSpline = easing === 'spline'; var ondestroy = function() { self._clipCount--; if (self._clipCount === 0) { // Clear all tracks self._tracks = {}; var len = self._doneList.length; for (var i = 0; i < len; i++) { self._doneList[i].call(self); } } }; var createTrackClip = function(keyframes, propName) { var trackLen = keyframes.length; if (!trackLen) { return; } // Guess data type var firstVal = keyframes[0].value; var isValueArray = _isArrayLike(firstVal); // For vertices morphing var arrDim = ( isValueArray && _isArrayLike(firstVal[0]) ) ? 2 : 1; // Sort keyframe as ascending keyframes.sort(function(a, b) { return a.time - b.time; }); var trackMaxTime; if (trackLen) { trackMaxTime = keyframes[trackLen-1].time; }else{ return; } // Percents of each keyframe var kfPercents = []; // Value of each keyframe var kfValues = []; for (var i = 0; i < trackLen; i++) { kfPercents.push(keyframes[i].time / trackMaxTime); if (isValueArray) { if (arrDim == 2) { kfValues[i] = []; for (var j = 0; j < firstVal.length; j++) { kfValues[i].push( arraySlice.call(keyframes[i].value[j]) ); } } else { kfValues.push(arraySlice.call(keyframes[i].value)); } } else { kfValues.push(keyframes[i].value); } } // Cache the key of last frame to speed up when // animation playback is sequency var cacheKey = 0; var cachePercent = 0; var start; var i, w; var p0, p1, p2, p3; var onframe = function(target, percent) { // Find the range keyframes // kf1-----kf2---------current--------kf3 // find kf2 and kf3 and do interpolation if (percent < cachePercent) { // Start from next key start = Math.min(cacheKey + 1, trackLen - 1); for (i = start; i >= 0; i--) { if (kfPercents[i] <= percent) { break; } } i = Math.min(i, trackLen-2); } else { for (i = cacheKey; i < trackLen; i++) { if (kfPercents[i] > percent) { break; } } i = Math.min(i-1, trackLen-2); } cacheKey = i; cachePercent = percent; var range = (kfPercents[i+1] - kfPercents[i]); if (range === 0) { return; } else { w = (percent - kfPercents[i]) / range; } if (w < 0) { console.log(w); } if (useSpline) { p1 = kfValues[i]; p0 = kfValues[i === 0 ? i : i - 1]; p2 = kfValues[i > trackLen - 2 ? trackLen - 1 : i + 1]; p3 = kfValues[i > trackLen - 3 ? trackLen - 1 : i + 2]; if (isValueArray) { _catmullRomInterpolateArray( p0, p1, p2, p3, w, w*w, w*w*w, getter(target, propName), arrDim ); } else { setter( target, propName, _catmullRomInterpolate( p0, p1, p2, p3, w, w*w, w*w*w ) ); } } else { if (isValueArray) { _interpolateArray( kfValues[i], kfValues[i+1], w, getter(target, propName), arrDim ); } else { setter( target, propName, _interpolateNumber(kfValues[i], kfValues[i+1], w) ); } } for (i = 0; i < onFrameListLen; i++) { self._onframeList[i](target, percent); } }; var clip = new Clip({ target : self._target, life : trackMaxTime, loop : self._loop, delay : self._delay, onframe : onframe, ondestroy : ondestroy }); if (easing && easing !== 'spline') { clip.easing = easing; } self._clipList.push(clip); self._clipCount++; self.animation.add(clip); }; for (var propName in this._tracks) { createTrackClip(this._tracks[propName], propName); } return this; }, stop : function() { for (var i = 0; i < this._clipList.length; i++) { var clip = this._clipList[i]; this.animation.remove(clip); } this._clipList = []; }, delay : function(time){ this._delay = time; return this; }, done : function(func) { this._doneList.push(func); return this; } }; return Animation; } ); /** * zrender: config默认配置项 * * @desc zrender是一个轻量级的Canvas类库,MVC封装,数据驱动,提供类Dom事件模型。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define( 'zrender/config',{ loadingEffect : 'spin', // 默认loading特效 EVENT : { // 支持事件列表 RESIZE : 'resize', // 窗口大小变化 CLICK : 'click', // 鼠标按钮被(手指)按下,事件对象是:目标图形元素或空 MOUSEWHEEL : 'mousewheel', // 鼠标滚轮变化,事件对象是:目标图形元素或空 MOUSEMOVE : 'mousemove', // 鼠标(手指)被移动,事件对象是:目标图形元素或空 MOUSEOVER : 'mouseover', // 鼠标移到某图形元素之上,事件对象是:目标图形元素 MOUSEOUT : 'mouseout', // 鼠标从某图形元素移开,事件对象是:目标图形元素 MOUSEDOWN : 'mousedown', // 鼠标按钮(手指)被按下,事件对象是:目标图形元素或空 MOUSEUP : 'mouseup', // 鼠标按键(手指)被松开,事件对象是:目标图形元素或空 // GLOBALOUT : 'globalout', // 全局离开,MOUSEOUT触发比较频繁,一次离开优化绑定 // 一次成功元素拖拽的行为事件过程是: // dragstart > dragenter > dragover [> dragleave] > drop > dragend DRAGSTART : 'dragstart', // 开始拖拽时触发,事件对象是:被拖拽图形元素 DRAGEND : 'dragend', // 拖拽完毕时触发(在drop之后触发),事件对象是:被拖拽图形元素 DRAGENTER : 'dragenter', // 拖拽图形元素进入目标图形元素时触发,事件对象是:目标图形元素 DRAGOVER : 'dragover', // 拖拽图形元素在目标图形元素上移动时触发,事件对象是:目标图形元素 DRAGLEAVE : 'dragleave', // 拖拽图形元素离开目标图形元素时触发,事件对象是:目标图形元素 DROP : 'drop', // 拖拽图形元素放在目标图形元素内时触发,事件对象是:目标图形元素 touchClickDelay : 300 // touch end - start < delay is click } } ); /** * zrender: loading特效 * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * 扩展loading effect: * getBackgroundShape:获取背景图形 * getTextShape:获取文字 * define : 定义效果 * * 内置效果 * bar:进度条 * whirling:旋转水滴 * dynamicLine:动态线条 * bubble:气泡 */ define( 'zrender/tool/loadingEffect',['require','./util','./color','./color','./color','./color','./color','./math'],function(require) { var util = require('./util'); var self; var _defaultText = 'Loading...'; var _defaultTextFont = 'normal 16px Arial'; var _width; var _height; function define(name, fun) { self[name] = fun; } /** * 获取loading文字图形 * @param {Object} textStyle 文字style,同shape/text.style */ function getTextShape(textStyle) { return { shape : 'text', highlightStyle : util.merge( { x : _width / 2, y : _height / 2, text : _defaultText, textAlign : 'center', textBaseline : 'middle', textFont : _defaultTextFont, color: '#333', brushType : 'fill' }, textStyle, {'overwrite': true, 'recursive': true} ) }; } /** * 获取loading背景图形 * @param {color} color 背景颜色 */ function getBackgroundShape (color) { return { shape : 'rectangle', highlightStyle : { x : 0, y : 0, width : _width, height : _height, brushType : 'fill', color : color } }; } // 调整值区间 function _adjust(value, region) { if (value <= region[0]) { value = region[0]; } else if (value >= region[1]) { value = region[1]; } return value; } /** * 进度条 * @param {Object} loadingOption * @param {Object} addShapeHandle * @param {Object} refreshHandle */ function bar(loadingOption, addShapeHandle, refreshHandle) { var zrColor = require('./color'); // 特效默认配置 loadingOption = util.merge( loadingOption, { textStyle : { color : '#888' }, backgroundColor : 'rgba(250, 250, 250, 0.8)', effectOption : { x : 0, y : _height / 2 - 30, width : _width, height : 5, brushType : 'fill', timeInterval : 100 } }, {'overwrite': false, 'recursive': true} ); var textShape = getTextShape(loadingOption.textStyle); var background = getBackgroundShape(loadingOption.backgroundColor); var effectOption = loadingOption.effectOption; // 初始化动画元素 var barShape = { shape : 'rectangle', highlightStyle : util.clone(effectOption) }; barShape.highlightStyle.color = effectOption.color || zrColor.getLinearGradient( effectOption.x, effectOption.y, effectOption.x + effectOption.width, effectOption.y + effectOption.height, [[0, '#ff6400'], [0.5, '#ffe100'], [1, '#b1ff00']] ); if (typeof loadingOption.progress != 'undefined') { // 指定进度 addShapeHandle(background); barShape.highlightStyle.width = _adjust(loadingOption.progress, [0,1]) * loadingOption.effectOption.width; addShapeHandle(barShape); addShapeHandle(textShape); refreshHandle(); return; } else { // 循环显示 barShape.highlightStyle.width = 0; return setInterval( function() { addShapeHandle(background); if (barShape.highlightStyle.width < loadingOption.effectOption.width ) { barShape.highlightStyle.width += 8; } else { barShape.highlightStyle.width = 0; } addShapeHandle(barShape); addShapeHandle(textShape); refreshHandle(); }, effectOption.timeInterval ); } } /** * 旋转水滴 * @param {Object} loadingOption * @param {Object} addShapeHandle * @param {Object} refreshHandle */ function whirling(loadingOption, addShapeHandle, refreshHandle) { // 特效默认配置 loadingOption.effectOption = util.merge( loadingOption.effectOption || {}, { x : _width / 2 - 80, y : _height / 2, r : 18, colorIn : '#fff', colorOut : '#555', colorWhirl : '#6cf', timeInterval : 50 } ); var effectOption = loadingOption.effectOption; loadingOption = util.merge( loadingOption, { textStyle : { color : '#888', x : effectOption.x + effectOption.r + 10, y : effectOption.y, textAlign : 'start' }, backgroundColor : 'rgba(250, 250, 250, 0.8)' }, {'overwrite': false, 'recursive': true} ); var textShape = getTextShape(loadingOption.textStyle); var background = getBackgroundShape(loadingOption.backgroundColor); // 初始化动画元素 var droplet = { shape : 'droplet', highlightStyle : { a : Math.round(effectOption.r / 2), b : Math.round(effectOption.r - effectOption.r / 6), brushType : 'fill', color : effectOption.colorWhirl } }; var circleIn = { shape : 'circle', highlightStyle : { r : Math.round(effectOption.r / 6), brushType : 'fill', color : effectOption.colorIn } }; var circleOut = { shape : 'ring', highlightStyle : { r0 : Math.round(effectOption.r - effectOption.r / 3), r : effectOption.r, brushType : 'fill', color : effectOption.colorOut } }; var pos = [0, effectOption.x, effectOption.y]; droplet.highlightStyle.x = circleIn.highlightStyle.x = circleOut.highlightStyle.x = pos[1]; droplet.highlightStyle.y = circleIn.highlightStyle.y = circleOut.highlightStyle.y = pos[2]; return setInterval( function() { addShapeHandle(background); addShapeHandle(circleOut); pos[0] -= 0.3; droplet.rotation = pos; addShapeHandle(droplet); addShapeHandle(circleIn); addShapeHandle(textShape); refreshHandle(); }, effectOption.timeInterval ); } /** * 动态线 * @param {Object} loadingOption * @param {Object} addShapeHandle * @param {Object} refreshHandle */ function dynamicLine(loadingOption, addShapeHandle, refreshHandle) { var zrColor = require('./color'); // 特效默认配置 loadingOption = util.merge( loadingOption, { textStyle : { color : '#fff' }, backgroundColor : 'rgba(0, 0, 0, 0.8)', effectOption : { n : 30, lineWidth : 1, color : 'random', timeInterval : 100 } }, {'overwrite': false, 'recursive': true} ); var textShape = getTextShape(loadingOption.textStyle); var background = getBackgroundShape(loadingOption.backgroundColor); var effectOption = loadingOption.effectOption; var n = effectOption.n; var lineWidth = effectOption.lineWidth; var shapeList = []; var pos; var len; var xStart; var color; // 初始化动画元素 for(var i = 0; i < n; i++) { xStart = -Math.ceil(Math.random() * 1000); len = Math.ceil(Math.random() * 400); pos = Math.ceil(Math.random() * _height); if (effectOption.color == 'random') { color = zrColor.random(); } else { color = effectOption.color; } shapeList[i] = { shape : 'line', highlightStyle : { xStart : xStart, yStart : pos, xEnd : xStart + len, yEnd : pos, strokeColor : color, lineWidth : lineWidth }, animationX : Math.ceil(Math.random() * 100), len : len }; } return setInterval( function() { addShapeHandle(background); var style; for(var i = 0; i < n; i++) { style = shapeList[i].highlightStyle ; if (style.xStart >= _width){ shapeList[i].len = Math.ceil(Math.random() * 400); shapeList[i].highlightStyle .xStart = -400; shapeList[i].highlightStyle .xEnd = -400 + shapeList[i].len; shapeList[i].highlightStyle .yStart = Math.ceil(Math.random() * _height); shapeList[i].highlightStyle .yEnd = shapeList[i].highlightStyle.yStart; } shapeList[i].highlightStyle.xStart += shapeList[i].animationX; shapeList[i].highlightStyle.xEnd += shapeList[i].animationX; addShapeHandle(shapeList[i]); } addShapeHandle(textShape); refreshHandle(); }, effectOption.timeInterval ); } /** * 泡泡 * @param {Object} loadingOption * @param {Object} addShapeHandle * @param {Object} refreshHandle */ function bubble(loadingOption, addShapeHandle, refreshHandle) { var zrColor = require('./color'); // 特效默认配置 loadingOption = util.merge( loadingOption, { textStyle : { color : '#888' }, backgroundColor : 'rgba(250, 250, 250, 0.8)', effectOption : { n : 50, lineWidth : 2, brushType : 'stroke', color : 'random', timeInterval : 100 } }, {'overwrite': false, 'recursive': true} ); var textShape = getTextShape(loadingOption.textStyle); var background = getBackgroundShape(loadingOption.backgroundColor); var effectOption = loadingOption.effectOption; var n = effectOption.n; var brushType = effectOption.brushType; var lineWidth = effectOption.lineWidth; var shapeList = []; var color; // 初始化动画元素 for(var i = 0; i < n; i++) { if (effectOption.color == 'random') { color = zrColor.alpha(zrColor.random(), 0.3); } else { color = effectOption.color; } shapeList[i] = { shape : 'circle', highlightStyle : { x : Math.ceil(Math.random() * _width), y : Math.ceil(Math.random() * _height), r : Math.ceil(Math.random() * 40), brushType : brushType, color : color, strokeColor : color, lineWidth : lineWidth }, animationY : Math.ceil(Math.random() * 20) }; } return setInterval( function () { addShapeHandle(background); var style; for(var i = 0; i < n; i++) { style = shapeList[i].highlightStyle; if (style.y - shapeList[i].animationY + style.r <= 0){ shapeList[i].highlightStyle.y = _height + style.r; shapeList[i].highlightStyle.x = Math.ceil( Math.random() * _width ); } shapeList[i].highlightStyle.y -= shapeList[i].animationY; addShapeHandle(shapeList[i]); } addShapeHandle(textShape); refreshHandle(); }, effectOption.timeInterval ); } /** * 旋转 * @param {Object} loadingOption * @param {Object} addShapeHandle * @param {Object} refreshHandle */ function spin(loadingOption, addShapeHandle, refreshHandle) { var zrColor = require('./color'); // 特效默认配置 loadingOption.effectOption = util.merge( loadingOption.effectOption || {}, { x : _width / 2 - 80, y : _height / 2, r0 : 9, r : 15, n : 18, color : '#fff', timeInterval : 100 } ); var effectOption = loadingOption.effectOption; loadingOption = util.merge( loadingOption, { textStyle : { color : '#fff', x : effectOption.x + effectOption.r + 10, y : effectOption.y, textAlign : 'start' }, backgroundColor : 'rgba(0, 0, 0, 0.8)' }, {'overwrite': false, 'recursive': true} ); var textShape = getTextShape(loadingOption.textStyle); var background = getBackgroundShape(loadingOption.backgroundColor); var n = effectOption.n; var x = effectOption.x; var y = effectOption.y; var r0 = effectOption.r0; var r = effectOption.r; var color = effectOption.color; // 初始化动画元素 var shapeList = []; var preAngle = Math.round(180 / n); for(var i = 0; i < n; i++) { shapeList[i] = { shape : 'sector', highlightStyle : { x : x, y : y, r0 : r0, r : r, startAngle : preAngle * i * 2, endAngle : preAngle * i * 2 + preAngle, color : zrColor.alpha(color, (i + 1) / n), brushType: 'fill' } }; } var pos = [0, x, y]; return setInterval( function() { addShapeHandle(background); pos[0] -= 0.3; for(var i = 0; i < n; i++) { shapeList[i].rotation = pos; addShapeHandle(shapeList[i]); } addShapeHandle(textShape); refreshHandle(); }, effectOption.timeInterval ); } /** * 圆环 * @param {Object} loadingOption * @param {Object} addShapeHandle * @param {Object} refreshHandle */ function ring(loadingOption, addShapeHandle, refreshHandle) { var zrColor = require('./color'); var zrMath = require('./math'); // 特效默认配置 loadingOption = util.merge( loadingOption, { textStyle : { color : '#07a' }, backgroundColor : 'rgba(250, 250, 250, 0.8)', effectOption : { x : _width / 2, y : _height / 2, r0 : 60, r : 100, color : '#bbdcff', brushType: 'fill', textPosition : 'inside', textFont : 'normal 30px verdana', textColor : 'rgba(30, 144, 255, 0.6)', timeInterval : 100 } }, {'overwrite': false, 'recursive': true} ); var effectOption = loadingOption.effectOption; var textStyle = loadingOption.textStyle; textStyle.x = typeof textStyle.x != 'undefined' ? textStyle.x : effectOption.x; textStyle.y = typeof textStyle.y != 'undefined' ? textStyle.y : (effectOption.y + (effectOption.r0 + effectOption.r) / 2 - 5); var textShape = getTextShape(loadingOption.textStyle); var background = getBackgroundShape(loadingOption.backgroundColor); var x = effectOption.x; var y = effectOption.y; var r0 = effectOption.r0 + 6; var r = effectOption.r - 6; var color = effectOption.color; var darkColor = zrColor.lift(color, 0.1); var shapeRing = { shape : 'ring', highlightStyle : util.clone(effectOption) }; // 初始化动画元素 var shapeList = []; var clolrList = zrColor.getGradientColors( ['#ff6400', '#ffe100', '#97ff00'], 25 ); var preAngle = 15; var endAngle = 240; for(var i = 0; i < 16; i++) { shapeList.push({ shape : 'sector', highlightStyle : { x : x, y : y, r0 : r0, r : r, startAngle : endAngle - preAngle, endAngle : endAngle, brushType: 'fill', color : darkColor }, _color : zrColor.getLinearGradient( x + r0 * zrMath.cos(endAngle, true), y - r0 * zrMath.sin(endAngle, true), x + r0 * zrMath.cos(endAngle - preAngle, true), y - r0 * zrMath.sin(endAngle - preAngle, true), [ [0, clolrList[i * 2]], [1, clolrList[i * 2 + 1]] ] ) }); endAngle -= preAngle; } endAngle = 360; for(var i = 0; i < 4; i++) { shapeList.push({ shape : 'sector', highlightStyle : { x : x, y : y, r0 : r0, r : r, startAngle : endAngle - preAngle, endAngle : endAngle, brushType: 'fill', color : darkColor }, _color : zrColor.getLinearGradient( x + r0 * zrMath.cos(endAngle, true), y - r0 * zrMath.sin(endAngle, true), x + r0 * zrMath.cos(endAngle - preAngle, true), y - r0 * zrMath.sin(endAngle - preAngle, true), [ [0, clolrList[i * 2 + 32]], [1, clolrList[i * 2 + 33]] ] ) }); endAngle -= preAngle; } var n = 0; if (typeof loadingOption.progress != 'undefined') { // 指定进度 addShapeHandle(background); n = _adjust(loadingOption.progress, [0,1]).toFixed(2) * 100 / 5; shapeRing.highlightStyle.text = n * 5 + '%'; addShapeHandle(shapeRing); for(var i = 0; i < 20; i++) { shapeList[i].highlightStyle.color = i < n ? shapeList[i]._color : darkColor; addShapeHandle(shapeList[i]); } addShapeHandle(textShape); refreshHandle(); return; } else { // 循环显示 return setInterval( function() { addShapeHandle(background); n += n >= 20 ? -20 : 1; //shapeRing.highlightStyle.text = n * 5 + '%'; addShapeHandle(shapeRing); for(var i = 0; i < 20; i++) { shapeList[i].highlightStyle.color = i < n ? shapeList[i]._color : darkColor; addShapeHandle(shapeList[i]); } addShapeHandle(textShape); refreshHandle(); }, effectOption.timeInterval ); } } function start(loadingOption, addShapeHandle, refreshHandle) { var loadingEffect = self.ring; // 默认特效 if (typeof loadingOption.effect == 'function') { // 自定义特效 loadingEffect = loadingOption.effect; } else if (typeof self[loadingOption.effect] == 'function'){ // 指定特效 loadingEffect = self[loadingOption.effect]; } _width = loadingOption.canvasSize.width; _height = loadingOption.canvasSize.height; return loadingEffect( loadingOption, addShapeHandle, refreshHandle ); } function stop(loadingTimer) { clearInterval(loadingTimer); } self = { // 这三个方法用于扩展loading effect getBackgroundShape : getBackgroundShape, getTextShape : getTextShape, define : define, // 内置特效 bar : bar, whirling : whirling, dynamicLine : dynamicLine, bubble : bubble, spin : spin, ring : ring, // 方法 start : start, stop : stop }; return self; } ); /** * zrender: 事件辅助类 * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * getX:获取事件横坐标 * getY:或者事件纵坐标 * getDelta:或者鼠标滚轮变化 * stop:停止事件传播 * Dispatcher:事件分发器 */ define( 'zrender/tool/event',[],function() { /** * 提取鼠标(手指)x坐标 * @param {event} e 事件. * @return {number} 鼠标(手指)x坐标. */ function getX(e) { return typeof e.zrenderX != 'undefined' && e.zrenderX || typeof e.offsetX != 'undefined' && e.offsetX || typeof e.layerX != 'undefined' && e.layerX || typeof e.clientX != 'undefined' && e.clientX; } /** * 提取鼠标y坐标 * @param {event} e 事件. * @return {number} 鼠标(手指)y坐标. */ function getY(e) { return typeof e.zrenderY != 'undefined' && e.zrenderY || typeof e.offsetY != 'undefined' && e.offsetY || typeof e.layerY != 'undefined' && e.layerY || typeof e.clientY != 'undefined' && e.clientY; } /** * 提取鼠标滚轮变化 * @param {event} e 事件. * @return {number} 滚轮变化,正值说明滚轮是向上滚动,如果是负值说明滚轮是向下滚动 */ function getDelta(e) { return typeof e.wheelDelta != 'undefined' && e.wheelDelta || typeof e.detail != 'undefined' && -e.detail; } /** * 停止冒泡和阻止默认行为 * @param {Object} e : event对象 */ function stop(e) { if (e.preventDefault) { e.preventDefault(); e.stopPropagation(); } else { e.returnValue = false; e.cancelBubble = true; } } /** * 事件分发器 */ function Dispatcher() { var _self = this; var _h = {}; /** * 单次触发绑定,dispatch后销毁 * @param {string} event 事件字符串 * @param {function} handler 响应函数 */ function one(event, handler) { if(!handler || !event) { return _self; } if(!_h[event]) { _h[event] = []; } _h[event].push({ h : handler, one : true }); return _self; } /** * 事件绑定 * @param {string} event 事件字符串 * @param {function} handler : 响应函数 */ function bind(event, handler) { if(!handler || !event) { return _self; } if(!_h[event]) { _h[event] = []; } _h[event].push({ h : handler, one : false }); return _self; } /** * 事件解绑定 * @param {string} event 事件字符串 * @param {function} handler : 响应函数 */ function unbind(event, handler) { if(!event) { _h = {}; return _self; } 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 _self; } /** * 事件分发 * @param {string} type : 事件类型 * @param {Object} event : event对象 * @param {Object} [attachment] : 附加信息 */ function dispatch(type, event, attachment) { if(_h[type]) { var newList = []; var eventPacket = attachment || {}; eventPacket.type = type; eventPacket.event = event; //eventPacket._target = self; for (var i = 0, l = _h[type].length; i < l; i++) { _h[type][i]['h'](eventPacket); if (!_h[type][i]['one']) { newList.push(_h[type][i]); } } if (newList.length != _h[type].length) { _h[type] = newList; } } return _self; } _self.one = one; _self.bind = bind; _self.unbind = unbind; _self.dispatch = dispatch; } return { getX : getX, getY : getY, getDelta : getDelta, stop : stop, Dispatcher : Dispatcher }; } ); /*! * ZRender, a lightweight canvas library with a MVC architecture, data-driven * and provides an event model like DOM. * * Copyright (c) 2013, Baidu Inc. * All rights reserved. * * LICENSE * https://github.com/ecomfe/zrender/blob/master/LICENSE.txt */ /** * zrender: core核心类 * * @desc zrender是一个轻量级的Canvas类库,MVC封装,数据驱动,提供类Dom事件模型。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define( 'zrender/zrender',['require','./lib/excanvas','./tool/util','./tool/env','./shape','./shape/circle','./shape/ellipse','./shape/line','./shape/polygon','./shape/brokenLine','./shape/rectangle','./shape/ring','./shape/sector','./shape/text','./shape/heart','./shape/droplet','./shape/path','./shape/image','./shape/beziercurve','./shape/star','./shape/isogon','./animation/animation','./config','./tool/loadingEffect','./tool/loadingEffect','./config','./tool/env','./tool/event'],function(require) { /* * HTML5 Canvas for Internet Explorer! * Modern browsers like Firefox, Safari, Chrome and Opera support * the HTML5 canvas tag to allow 2D command-based drawing. * ExplorerCanvas brings the same functionality to Internet Explorer. * To use, web developers only need to include a single script tag * in their existing web pages. * * https://code.google.com/p/explorercanvas/ * http://explorercanvas.googlecode.com/svn/trunk/excanvas.js */ // 核心代码会生成一个全局变量 G_vmlCanvasManager,模块改造后借用于快速判断canvas支持 require('./lib/excanvas'); var util = require('./tool/util'); var self = {}; var zrender = self; // 提供MVC内部反向使用静态方法; var _idx = 0; //ZRender instance's id var _instances = {}; //ZRender实例map索引 self.version = '1.1.1'; /** * zrender初始化 * 不让外部直接new ZRender实例,为啥? * 不为啥,提供全局可控同时减少全局污染和降低命名冲突的风险! * * @param {HTMLElement} dom dom对象,不帮你做document.getElementById了 * @param {Object=} params 个性化参数,如自定义shape集合,带进来就好 * * @return {ZRender} ZRender实例 */ self.init = function(dom, params) { var zi = new ZRender(++_idx + '', dom, params || {}); _instances[_idx] = zi; return zi; }; /** * zrender实例销毁,记在_instances里的索引也会删除了 * 管生就得管死,可以通过zrender.dispose(zi)销毁指定ZRender实例 * 当然也可以直接zi.dispose()自己销毁 * * @param {ZRender=} zi ZRender对象,不传则销毁全部 */ self.dispose = function(zi) { if (zi) { zi.dispose(); } else { for (var z in _instances) { _instances[z].dispose(); } _instances = {}; } return self; }; /** * 获取zrender实例 * * @param {string} id ZRender对象索引 */ self.getInstance = function(id) { return _instances[id]; }; /** * 删除zrender实例,ZRender实例dispose时会调用, * 删除后getInstance则返回undefined * ps: 仅是删除,删除的实例不代表已经dispose了~~ * 这是一个摆脱全局zrender.dispose()自动销毁的后门, * take care of yourself~ * * @param {string} id ZRender对象索引 */ self.delInstance = function(id) { if (_instances[id]) { //只是对垃圾回收上的友好照顾,不写也大不了~ _instances[id] = null; delete _instances[id]; } return self; }; // 是否异常捕获 self.catchBrushException = false; /** * debug日志选项:catchBrushException为true下有效 * 0 : 不生成debug数据,发布用 * 1 : 异常抛出,调试用 * 2 : 控制台输出,调试用 */ self.debugMode = 0; self.log = function() { if (self.debugMode === 0) { return; } else if (self.debugMode == 1) { for (var k in arguments) { throw new Error(arguments[k]); } } else if (self.debugMode > 1) { for (var k in arguments) { console.log(arguments[k]); } } return self; }; /* for debug self.log = function(mes) { document.getElementById('wrong-message').innerHTML = mes + ' ' + (new Date() - 0) + '
' + document.getElementById('wrong-message').innerHTML; }; */ /** * ZRender接口类,对外可用的所有接口都在这里!! * storage(M)、painter(V)、handler(C)为内部私有类,外部接口不可见 * 非get接口统一返回self支持链式调用~ * * @param {string} id 唯一标识 * @param {HTMLElement} dom dom对象,不帮你做document.getElementById * @param {Object=} params 个性化参数,如自定义shape集合,带进来就好 * * @return {ZRender} ZRender实例 */ function ZRender(id, dom, params) { var self = this; self.env = require('./tool/env'); var shape = require('./shape'); // 内置图形注册 require('./shape/circle'); require('./shape/ellipse'); require('./shape/line'); require('./shape/polygon'); require('./shape/brokenLine'); require('./shape/rectangle'); require('./shape/ring'); require('./shape/sector'); require('./shape/text'); require('./shape/heart'); require('./shape/droplet'); require('./shape/path'); require('./shape/image'); require('./shape/beziercurve'); require('./shape/star'); require('./shape/isogon'); var shapeLibrary; if (typeof params.shape == 'undefined') { //默认图形库 shapeLibrary = shape; } else { //自定义图形库,私有化,实例独占 shapeLibrary = {}; for (var s in params.shape) { shapeLibrary[s] = params.shape[s]; } shapeLibrary.get = function(name) { return shapeLibrary[name] || shape.get(name); }; } var storage = new Storage(shapeLibrary); var painter = new Painter(dom, storage, shapeLibrary); var handler = new Handler(dom, storage, painter, shapeLibrary); // 动画控制 var Animation = require('./animation/animation'); var animatingShapes = []; var animation = new Animation({ stage : { update : function(){ var shapes = animatingShapes; for (var i = 0, l = shapes.length; i < l; i++) { storage.mod(shapes[i].id); } if (shapes.length > 0) { painter.refresh(); } } } }); animation.start(); /** * 获取实例唯一标识 */ self.getId = function() { return id; }; /** * 添加图形形状 * @param {Object} shape 形状对象,可用属性全集,详见各shape */ self.addShape = function(shape) { storage.add(shape); return self; }; /** * 删除图形形状 * @param {string} shapeId 形状对象唯一标识 */ self.delShape = function(shapeId) { storage.del(shapeId); return self; }; /** * 修改图形形状 * @param {string} shapeId 形状对象唯一标识 * @param {Object} shape 形状对象 * @param {fast} boolean 默认为false, 如果为true的话会在merge中省略部分判断 */ self.modShape = function(shapeId, shape, fast) { storage.mod(shapeId, shape, fast); return self; }; /** * 修改指定zlevel的绘制配置项,例如clearColor * @param {string} zLevel * @param {Object} config 配置对象, 目前支持clearColor */ self.modLayer = function(zLevel, config) { painter.modLayer(zLevel, config); } /** * 添加额外高亮层显示,仅提供添加方法,每次刷新后高亮层图形均被清空 * @param {Object} shape 形状对象 */ self.addHoverShape = function(shape) { storage.addHover(shape); return self; }; /** * 渲染 * @param {Function} callback 渲染结束后回调函数 * todo:增加缓动函数 */ self.render = function(callback) { painter.render(callback); return self; }; /** * 视图更新 * @param {Function} callback 视图更新后回调函数 */ self.refresh = function(callback) { painter.refresh(callback); return self; }; /** * 高亮层更新 * @param {Function} callback 视图更新后回调函数 */ self.refreshHover = function(callback) { painter.refreshHover(callback); return self; }; /** * 视图更新 * @param {Array} shapeList 需要更新的图形元素列表 * @param {Function} callback 视图更新后回调函数 */ self.update = function(shapeList, callback) { painter.update(shapeList, callback); return self; }; self.resize = function() { painter.resize(); return self; }; /** * 动画 * @param {string} shapeId 形状对象唯一标识 * @param {string} path 需要添加动画的属性获取路径,可以通过a.b.c来获取深层的属性 * @param {boolean} loop 动画是否循环 * @return {Object} 动画的Deferred对象 * Example: * zr.animate( circleId, 'style', false) * .when(1000, { x: 10} ) * .done( function(){ console.log('Animation done')}) * .start() */ self.animate = function(shapeId, path, loop) { var shape = storage.get(shapeId); if (shape) { var target; if (path) { var pathSplitted = path.split('.'); var prop = shape; for (var i = 0, l = pathSplitted.length; i < l; i++) { if (!prop) { continue; } prop = prop[pathSplitted[i]]; } if (prop) { target = prop; } } else { target = shape; } if (!target) { zrender.log( 'Property "' + path + '" is not existed in shape ' + shapeId ); return; } if (typeof(shape.__aniCount) === 'undefined') { // 正在进行的动画记数 shape.__aniCount = 0; } if (shape.__aniCount === 0) { animatingShapes.push(shape); } shape.__aniCount++; return animation.animate(target, {loop : loop}) .done(function() { shape.__aniCount --; if( shape.__aniCount === 0){ // 从animatingShapes里移除 var idx = util.indexOf(animatingShapes, shape); animatingShapes.splice(idx, 1); } }); } else { zrender.log('Shape "'+ shapeId + '" not existed'); } }; /** * 停止所有动画 */ self.clearAnimation = function() { animation.clear(); }; /** * loading显示 * @param {Object} loadingOption 参数 * { * effect, * //loading话术 * text:'', * // 水平安放位置,默认为 'center',可指定x坐标 * x:'center' || 'left' || 'right' || {number}, * // 垂直安放位置,默认为'top',可指定y坐标 * y:'top' || 'bottom' || {number}, * * textStyle:{ * textFont: 'normal 20px Arial' || {textFont}, //文本字体 * color: {color} * } * } */ self.showLoading = function(loadingOption) { painter.showLoading(loadingOption); return self; }; /** * loading结束 */ self.hideLoading = function() { painter.hideLoading(); return self; }; /** * 生成形状唯一ID * @param {string} [idPrefix] id前缀 * @return {string} 不重复ID */ self.newShapeId = function(idPrefix) { return storage.newShapeId(idPrefix); }; /** * 获取视图宽度 */ self.getWidth = function() { return painter.getWidth(); }; /** * 获取视图高度 */ self.getHeight = function() { return painter.getHeight(); }; /** * 图像导出 */ self.toDataURL = function(type, backgroundColor, args) { return painter.toDataURL(type, backgroundColor, args); }; /** * 将常规shape转成image shape */ self.shapeToImage = function(e, width, height) { var id = self.newShapeId('image'); return painter.shapeToImage(id, e, width, height); }; /** * 事件绑定 * @param {string} eventName 事件名称 * @param {Function} eventHandler 响应函数 */ self.on = function(eventName, eventHandler) { handler.on(eventName, eventHandler); return self; }; /** * 事件解绑定,参数为空则解绑所有自定义事件 * @param {string} eventName 事件名称 * @param {Function} eventHandler 响应函数 */ self.un = function(eventName, eventHandler) { handler.un(eventName, eventHandler); return self; }; /** * 事件触发 * @param {string} event 事件名称,resize,hover,drag,etc~ * @param {event=} event event dom事件对象 */ self.trigger = function(eventName, event) { handler.trigger(eventName, event); return self; }; /** * 清除当前ZRender下所有类图的数据和显示,clear后MVC和已绑定事件均还存在在,ZRender可用 */ self.clear = function() { storage.del(); painter.clear(); return self; }; /** * 释放当前ZR实例(删除包括dom,数据、显示和事件绑定),dispose后ZR不可用 */ self.dispose = function() { animation.stop(); animation = null; animatingShapes = null; self.clear(); self = null; storage.dispose(); storage = null; painter.dispose(); painter = null; handler.dispose(); handler = null; //释放后告诉全局删除对自己的索引,没想到啥好方法 zrender.delInstance(id); return; }; } /** * 内容仓库 (M) * @param {Object} shape 图形库 */ function Storage(shape) { var self = this; var _idBase = 0; //图形数据id自增基础 // 所有常规形状,id索引的map var _elements = {}; // 所有形状的z轴方向排列,提高遍历性能,zElements[0]的形状在zElements[1]形状下方 var _zElements = []; // 高亮层形状,不稳定,动态增删,数组位置也是z轴方向,靠前显示在下方 var _hoverElements = []; var _maxZlevel = 0; // 最大zlevel var _changedZlevel = {}; // 有数据改变的zlevel /** * 快速判断标志~ * e.__silent 是否需要hover判断 * e.__needTransform 是否需要进行transform * e.style.__rect 区域矩阵缓存,修改后清空,重新计算一次 */ function _mark(e) { if (e.hoverable || e.onclick || e.draggable || e.onmousemove || e.onmouseover || e.onmouseout || e.onmousedown || e.onmouseup || e.ondragenter || e.ondragover || e.ondragleave || e.ondrop ) { e.__silent = false; } else { e.__silent = true; } if (Math.abs(e.rotation[0]) > 0.0001 || Math.abs(e.position[0]) > 0.0001 || Math.abs(e.position[1]) > 0.0001 || Math.abs(e.scale[0] - 1) > 0.0001 || Math.abs(e.scale[1] - 1) > 0.0001 ) { e.__needTransform = true; } else { e.__needTransform = false; } e.style = e.style || {}; e.style.__rect = null; } /** * 唯一标识id生成 * @param {string=} idHead 标识前缀 */ function newShapeId(idHead) { return (idHead || '') + (++_idBase); } /** * 添加 * @param {Object} params 参数 */ function add(params) { // 默认&必须的参数 var e = { 'shape': 'circle', // 形状 'id': params.id || self.newShapeId(), // 唯一标识 'zlevel': 0, // z轴位置 'draggable': false, // draggable可拖拽 'clickable': false, // clickable可点击响应 'hoverable': true, // hoverable可悬浮响应 'position': [0, 0], 'rotation' : [0, 0, 0], 'scale' : [1, 1, 0, 0] }; util.merge( e, params, { 'overwrite': true, 'recursive': true } ); _mark(e); _elements[e.id] = e; _zElements[e.zlevel] = _zElements[e.zlevel] || []; _zElements[e.zlevel].push(e); _maxZlevel = Math.max(_maxZlevel,e.zlevel); _changedZlevel[e.zlevel] = true; return self; } /** * 根据指定的shapeId获取相应的shape属性 * @param {string=} idx 唯一标识 */ function get(shapeId) { return _elements[shapeId]; } /** * 删除,shapeId不指定则全清空 * @param {string= | Array} idx 唯一标识 */ function del(shapeId) { if (typeof shapeId != 'undefined') { var delMap = {}; if (!(shapeId instanceof Array)) { // 单个 delMap[shapeId] = true; } else { // 批量删除 if (shapeId.lenth < 1) { // 空数组 return; } for (var i = 0, l = shapeId.length; i < l; i++) { delMap[shapeId[i].id] = true; } } var newList; var oldList; var zlevel; var zChanged = {}; for (var sId in delMap) { if (_elements[sId]) { zlevel = _elements[sId].zlevel; _changedZlevel[zlevel] = true; if (!zChanged[zlevel]) { oldList = _zElements[zlevel]; newList = []; for (var i = 0, l = oldList.length; i < l; i++){ if (!delMap[oldList[i].id]) { newList.push(oldList[i]); } } _zElements[zlevel] = newList; zChanged[zlevel] = true; } delete _elements[sId]; } } } else{ //不指定shapeId清空 _elements = {}; _zElements = []; _hoverElements = []; _maxZlevel = 0; //最大zlevel _changedZlevel = { //有数据改变的zlevel all : true }; } return self; } /** * 修改 * @param {string} idx 唯一标识 * @param {Object} params]参数 * @param {boolean} fast */ function mod(shapeId, params, fast) { var e = _elements[shapeId]; if (e) { _changedZlevel[e.zlevel] = true; // 可能修改前后不在一层 if (params) { if (fast) { util.mergeFast( e, params, true, true ); } else { util.merge( e, params, { 'overwrite': true, 'recursive': true } ); } } _mark(e); _changedZlevel[e.zlevel] = true; // 可能修改前后不在一层 _maxZlevel = Math.max(_maxZlevel,e.zlevel); } return self; } /** * 常规形状位置漂移,形状自身定义漂移函数 * @param {string} idx 形状唯一标识 * */ function drift(shapeId, dx, dy) { var e = _elements[shapeId]; if (!e) { return; } e.__needTransform = true; if (!e.ondrift //ondrift //有onbrush并且调用执行返回false或undefined则继续 || (e.ondrift && !e.ondrift(e, dx, dy)) ) { if (zrender.catchBrushException) { try { shape.get(e.shape).drift(e, dx, dy); } catch(error) { zrender.log(error, 'drift error of ' + e.shape, e); } } else { shape.get(e.shape).drift(e, dx, dy); } } _changedZlevel[e.zlevel] = true; return self; } /** * 添加高亮层数据 * @param {Object} params 参数 */ function addHover(params) { if ((params.rotation && Math.abs(params.rotation[0]) > 0.0001) || (params.position && (Math.abs(params.position[0]) > 0.0001 || Math.abs(params.position[1]) > 0.0001)) || (params.scale && (Math.abs(params.scale[0] - 1) > 0.0001 || Math.abs(params.scale[1] - 1) > 0.0001)) ) { params.__needTransform = true; } else { params.__needTransform = false; } _hoverElements.push(params); return self; } /** * 删除高亮层数据 */ function delHover() { _hoverElements = []; return self; } function hasHoverShape() { return _hoverElements.length > 0; } /** * 遍历迭代器 * @param {Function} fun 迭代回调函数,return true终止迭代 * @param {Object=} option 迭代参数,缺省为仅降序遍历常规形状 * hover : true 是否迭代高亮层数据 * normal : 'down' | 'up' | 'free' 是否迭代常规数据,迭代时是否指定及z轴顺序 */ function iterShape(fun, option) { if (!option) { option = { hover: false, normal: 'down' }; } if (option.hover) { //高亮层数据遍历 for (var i = 0, l = _hoverElements.length; i < l; i++) { if (fun(_hoverElements[i])) { return self; } } } var zlist; var len; if (typeof option.normal != 'undefined') { //z轴遍历: 'down' | 'up' | 'free' switch (option.normal) { case 'down': //降序遍历,高层优先 for (var l = _zElements.length - 1; l >= 0; l--) { zlist = _zElements[l]; if (zlist) { len = zlist.length; while (len--) { if (fun(zlist[len])) { return self; } } } } break; case 'up': //升序遍历,底层优先 for (var i = 0, l = _zElements.length; i < l; i++) { zlist = _zElements[i]; if (zlist) { len = zlist.length; for (var k = 0; k < len; k++) { if (fun(zlist[k])) { return self; } } } } break; // case 'free': default: //无序遍历 for (var i in _elements) { if (fun(_elements[i])) { return self; } } break; } } return self; } function getMaxZlevel() { return _maxZlevel; } function getChangedZlevel() { return _changedZlevel; } function clearChangedZlevel() { _changedZlevel = {}; return self; } function setChangedZlevle(level){ _changedZlevel[level] = true; return self; } /** * 释放 */ function dispose() { _elements = null; _zElements = null; _hoverElements = null; self = null; return; } self.newShapeId = newShapeId; self.add = add; self.get = get; self.del = del; self.addHover = addHover; self.delHover = delHover; self.hasHoverShape = hasHoverShape; self.mod = mod; self.drift = drift; self.iterShape = iterShape; self.getMaxZlevel = getMaxZlevel; self.getChangedZlevel = getChangedZlevel; self.clearChangedZlevel = clearChangedZlevel; self.setChangedZlevle = setChangedZlevle; self.dispose = dispose; } /** * 绘图类 (V) * @param {HTMLElement} root 绘图区域 * @param {storage} storage Storage实例 * @param {Object} shape 图形库 */ function Painter(root, storage, shape) { var config = require('./config'); var self = this; var _domList = {}; //canvas dom元素 var _ctxList = {}; //canvas 2D context对象,与domList对应 var _domListBack = {}; var _ctxListBack = {}; // 每个zLevel 的配置 // @config clearColor var _zLevelConfig = {}; var _maxZlevel = 0; //最大zlevel,缓存记录 var _loadingTimer; var _domRoot = document.createElement('div'); // 避免页面选中的尴尬 _domRoot.onselectstart = function() { return false; }; //宽,缓存记录 var _width; //高,缓存记录 var _height; //retina 屏幕优化 var _devicePixelRatio = window.devicePixelRatio || 1; function _getWidth() { var stl = root.currentStyle || document.defaultView.getComputedStyle(root); return (root.clientWidth || (stl.style.width.replace(/\D/g,''))) - stl.paddingLeft.replace(/\D/g,'') // 请原谅我这比较粗暴 - stl.paddingRight.replace(/\D/g,''); } function _getHeight(){ var stl = root.currentStyle || document.defaultView.getComputedStyle(root); return (root.clientHeight || (stl.style.height.replace(/\D/g,''))) - stl.paddingTop.replace(/\D/g,'') // 请原谅我这比较粗暴 - stl.paddingBottom.replace(/\D/g,''); } function _init() { _domRoot.innerHTML = ''; root.innerHTML = ''; _width = _getWidth(); _height = _getHeight(); //没append呢,原谅我这样写,清晰~ _domRoot.style.position = 'relative'; _domRoot.style.overflow = 'hidden'; _domRoot.style.width = _width + 'px'; _domRoot.style.height = _height + 'px'; root.appendChild(_domRoot); _domList = {}; _ctxList = {}; _domListBack = {}; _ctxListBack = {}; _maxZlevel = storage.getMaxZlevel(); //创建各层canvas //背景 _domList['bg'] = _createDom('bg','div'); _domRoot.appendChild(_domList['bg']); //实体 for (var i = 0; i <= _maxZlevel; i++) { _domList[i] = _createDom(i,'canvas'); _domRoot.appendChild(_domList[i]); if (G_vmlCanvasManager) { G_vmlCanvasManager.initElement(_domList[i]); } _ctxList[i] = _domList[i].getContext('2d'); _devicePixelRatio != 1 && _ctxList[i].scale(_devicePixelRatio, _devicePixelRatio); } //高亮 _domList['hover'] = _createDom('hover','canvas'); _domList['hover'].id = '_zrender_hover_'; _domRoot.appendChild(_domList['hover']); if (G_vmlCanvasManager) { G_vmlCanvasManager.initElement(_domList['hover']); } _ctxList['hover'] = _domList['hover'].getContext('2d'); _devicePixelRatio != 1 && _ctxList['hover'].scale( _devicePixelRatio, _devicePixelRatio ); } /** * 检查_maxZlevel是否变大,如是则同步创建需要的Canvas */ function _syncMaxZlevelCanvase(){ var curMaxZlevel = storage.getMaxZlevel(); if (_maxZlevel < curMaxZlevel) { //实体 for (var i = _maxZlevel + 1; i <= curMaxZlevel; i++) { _domList[i] = _createDom(i,'canvas'); _domRoot.insertBefore(_domList[i], _domList['hover']); if (G_vmlCanvasManager) { G_vmlCanvasManager.initElement(_domList[i]); } _ctxList[i] = _domList[i].getContext('2d'); _devicePixelRatio != 1 && _ctxList[i].scale( _devicePixelRatio, _devicePixelRatio ); } _maxZlevel = curMaxZlevel; } } /** * 创建dom * @param {string} id dom id 待用 * @param {string} type : dom type, such as canvas, div etc. */ function _createDom(id, type) { var newDom = document.createElement(type); //没append呢,请原谅我这样写,清晰~ newDom.style.position = 'absolute'; newDom.style.left = 0; newDom.style.top = 0; newDom.style.width = _width + 'px'; newDom.style.height = _height + 'px'; newDom.setAttribute('width', _width * _devicePixelRatio); newDom.setAttribute('height', _height * _devicePixelRatio); //id不作为索引用,避免可能造成的重名,定义为私有属性 newDom.setAttribute('data-id', id); return newDom; } /** * 刷画图形 * @param {Object} changedZlevel 需要更新的zlevel索引 */ function _brush(changedZlevel) { return function(e) { if ((changedZlevel.all || changedZlevel[e.zlevel]) && !e.invisible ) { var ctx = _ctxList[e.zlevel]; if (ctx) { if (!e.onbrush //没有onbrush //有onbrush并且调用执行返回false或undefined则继续粉刷 || (e.onbrush && !e.onbrush(ctx, e, false)) ) { if (zrender.catchBrushException) { try { shape.get(e.shape).brush( ctx, e, false, update ); } catch(error) { zrender.log( error, 'brush error of ' + e.shape, e ); } } else { shape.get(e.shape).brush( ctx, e, false, update ); } } } else { zrender.log( 'can not find the specific zlevel canvas!' ); } } }; } /** * 鼠标悬浮刷画 */ function _brushHover(e) { var ctx = _ctxList['hover']; if (!e.onbrush //没有onbrush //有onbrush并且调用执行返回false或undefined则继续粉刷 || (e.onbrush && !e.onbrush(ctx, e, true)) ) { // Retina 优化 if (zrender.catchBrushException) { try { shape.get(e.shape).brush(ctx, e, true, update); } catch(error) { zrender.log( error, 'hoverBrush error of ' + e.shape, e ); } } else { shape.get(e.shape).brush(ctx, e, true, update); } } } /** * 首次绘图,创建各种dom和context * @param {Function=} callback 绘画结束后的回调函数 */ function render(callback) { if (isLoading()) { hideLoading(); } //检查_maxZlevel是否变大,如是则同步创建需要的Canvas _syncMaxZlevelCanvase(); //清空已有内容,render默认为首次渲染 clear(); //升序遍历,shape上的zlevel指定绘画图层的z轴层叠 storage.iterShape( _brush({ all : true }), { normal: 'up' } ); //update到最新则清空标志位 storage.clearChangedZlevel(); if (typeof callback == 'function') { callback(); } return self; } /** * 刷新 * @param {Function=} callback 刷新结束后的回调函数 */ function refresh(callback) { //检查_maxZlevel是否变大,如是则同步创建需要的Canvas _syncMaxZlevelCanvase(); //仅更新有修改的canvas var changedZlevel = storage.getChangedZlevel(); //擦除有修改的canvas if (changedZlevel.all){ clear(); } else { for (var k in changedZlevel) { if (_ctxList[k]) { clearLayer(k); } } } //重绘内容,升序遍历,shape上的zlevel指定绘画图层的z轴层叠 storage.iterShape( _brush(changedZlevel), { normal: 'up'} ); //update到最新则清空标志位 storage.clearChangedZlevel(); if (typeof callback == 'function') { callback(); } return self; } /** * 视图更新 * @param {Array} shapeList 需要更新的图形元素列表 * @param {Function} callback 视图更新后回调函数 */ function update(shapeList, callback) { var shape; for (var i = 0, l = shapeList.length; i < l; i++) { shape = shapeList[i]; storage.mod(shape.id, shape); } refresh(callback); return self; } /** * 清除hover层外所有内容 */ function clear() { for (var k in _ctxList) { if (k == 'hover') { continue; } clearLayer(k); } return self; } /** * 清除单独的一个层 */ function clearLayer(k) { if (_zLevelConfig[k]) { var haveClearColor = typeof(_zLevelConfig[k].clearColor) !== 'undefined'; var haveMotionBLur = _zLevelConfig[k].motionBlur; var lastFrameAlpha = _zLevelConfig[k].lastFrameAlpha; if (typeof(lastFrameAlpha) == 'undefined') { lastFrameAlpha = 0.7; } if (haveMotionBLur) { if (typeof(_domListBack[k]) === 'undefined') { var backDom = _createDom('back-' + k, 'canvas'); backDom.width = _domList[k].width; backDom.height = _domList[k].height; backDom.style.width = _domList[k].style.width; backDom.style.height = _domList[k].style.height; _domListBack[k] = backDom; _ctxListBack[k] = backDom.getContext('2d'); _devicePixelRatio != 1 && _ctxListBack[k].scale( _devicePixelRatio, _devicePixelRatio ); } _ctxListBack[k].globalCompositeOperation = 'copy'; _ctxListBack[k].drawImage( _domList[k], 0, 0, _domList[k].width / _devicePixelRatio, _domList[k].height / _devicePixelRatio ); } if (haveClearColor) { _ctxList[k].save(); _ctxList[k].fillStyle = _zLevelConfig[k].clearColor; _ctxList[k].fillRect( 0, 0, _width * _devicePixelRatio, _height * _devicePixelRatio ); _ctxList[k].restore(); } else { _ctxList[k].clearRect( 0, 0, _width * _devicePixelRatio, _height * _devicePixelRatio ); } if (haveMotionBLur) { var backDom = _domListBack[k]; var ctx = _ctxList[k]; ctx.save(); ctx.globalAlpha = lastFrameAlpha; ctx.drawImage( backDom, 0, 0, backDom.width / _devicePixelRatio, backDom.height / _devicePixelRatio ); ctx.restore(); } } else { _ctxList[k].clearRect( 0, 0, _width * _devicePixelRatio, _height * _devicePixelRatio ); } } /** * 修改指定zlevel的绘制参数 * @return {[type]} [description] */ function modLayer(zLevel, config) { if (config) { if (typeof(_zLevelConfig[zLevel]) === 'undefined' ) { _zLevelConfig[zLevel] = {}; } util.merge(_zLevelConfig[zLevel], config, { recursive : true, overwrite : true }); } } /** * 刷新hover层 */ function refreshHover() { clearHover(); storage.iterShape(_brushHover, { hover: true }); storage.delHover(); return self; } /** * 清除hover层所有内容 */ function clearHover() { _ctxList && _ctxList['hover'] && _ctxList['hover'].clearRect( 0, 0, _width * _devicePixelRatio, _height * _devicePixelRatio ); return self; } /** * 显示loading * @param {Object} loadingOption 选项,内容见下 * @param {color} -.backgroundColor 背景颜色 * @param {Object} -.textStyle 文字样式,同shape/text.style * @param {number=} -.progress 进度参数,部分特效有用 * @param {Object=} -.effectOption 特效参数,部分特效有用 * @param {string | function} -.effect 特效依赖tool/loadingEffect, * 可传入自定义特效function */ function showLoading(loadingOption) { var effect = require('./tool/loadingEffect'); effect.stop(_loadingTimer); loadingOption = loadingOption || {}; loadingOption.effect = loadingOption.effect || config.loadingEffect; loadingOption.canvasSize = { width : _width, height : _height }; _loadingTimer = effect.start( loadingOption, storage.addHover, refreshHover ); self.loading = true; return self; } /** * loading结束 * 乱来的,待重写 */ function hideLoading() { var effect = require('./tool/loadingEffect'); effect.stop(_loadingTimer); clearHover(); self.loading = false; return self; } /** * loading结束判断 */ function isLoading() { return self.loading; } /** * 获取绘图区域宽度 */ function getWidth() { return _width; } /** * 获取绘图区域高度 */ function getHeight() { return _height; } /** * 区域大小变化后重绘 */ function resize() { var width; var height; var dom; _domRoot.style.display = 'none'; width = _getWidth(); height = _getHeight(); _domRoot.style.display = ''; //优化没有实际改变的resize if (_width != width || height != _height){ _width = width; _height = height; _domRoot.style.width = _width + 'px'; _domRoot.style.height = _height + 'px'; for (var i in _domList) { dom = _domList[i]; dom.setAttribute('width', _width); dom.setAttribute('height', _height); dom.style.width = _width + 'px'; dom.style.height = _height + 'px'; } storage.setChangedZlevle('all'); refresh(); } return self; } /** * 释放 */ function dispose() { if (isLoading()) { hideLoading(); } root.innerHTML = ''; root = null; storage = null; shape = null; _domRoot = null; _domList = null; _ctxList = null; _ctxListBack = null; _domListBack = null; self = null; return; } function getDomHover() { return _domList['hover']; } function toDataURL(type, backgroundColor, args) { if (G_vmlCanvasManager) { return null; } var imageDom = _createDom('image','canvas'); _domList['bg'].appendChild(imageDom); var ctx = imageDom.getContext('2d'); _devicePixelRatio != 1 && ctx.scale(_devicePixelRatio, _devicePixelRatio); ctx.fillStyle = backgroundColor || '#fff'; ctx.rect( 0, 0, _width * _devicePixelRatio, _height * _devicePixelRatio ); ctx.fill(); //升序遍历,shape上的zlevel指定绘画图层的z轴层叠 storage.iterShape( function (e) { if (!e.invisible) { if (!e.onbrush //没有onbrush //有onbrush并且调用执行返回false或undefined则继续粉刷 || (e.onbrush && !e.onbrush(ctx, e, false)) ) { if (zrender.catchBrushException) { try { shape.get(e.shape).brush( ctx, e, false, update ); } catch(error) { zrender.log( error, 'brush error of ' + e.shape, e ); } } else { shape.get(e.shape).brush( ctx, e, false, update ); } } } }, { normal: 'up' } ); var image = imageDom.toDataURL(type, args); ctx = null; _domList['bg'].removeChild(imageDom); return image; } var shapeToImage = (function() { if (G_vmlCanvasManager) { return function(){}; } var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var devicePixelRatio = window.devicePixelRatio || 1; return function(id, e, width, height) { canvas.style.width = width + 'px'; canvas.style.height = height + 'px'; canvas.setAttribute('width', width * devicePixelRatio); canvas.setAttribute('height', height * devicePixelRatio); ctx.clearRect(0, 0, width * devicePixelRatio, height * devicePixelRatio); var brush = shape.get(e.shape); var shapeTransform = { position : e.position, rotation : e.rotation, scale : e.scale }; e.position = [0, 0, 0]; e.rotation = 0; e.scale = [1, 1]; if (brush) { brush.brush(ctx, e, false); } var imgShape = { shape : 'image', id : id, style : { x : 0, y : 0, // TODO 直接使用canvas而不是通过base64 image : canvas.toDataURL() } } if (typeof(shapeTransform.position) !== 'undefined') { imgShape.position = e.position = shapeTransform.position; } if (typeof(shapeTransform.rotation) !== 'undefined') { imgShape.rotation = e.rotation = shapeTransform.rotation; } if (typeof(shapeTransform.scale) !== 'undefined') { imgShape.scale = e.scale = shapeTransform.scale; } return imgShape; } })(); self.render = render; self.refresh = refresh; self.update = update; self.clear = clear; self.modLayer = modLayer; self.refreshHover = refreshHover; self.clearHover = clearHover; self.showLoading = showLoading; self.hideLoading = hideLoading; self.isLoading = isLoading; self.getWidth = getWidth; self.getHeight = getHeight; self.resize = resize; self.dispose = dispose; self.getDomHover = getDomHover; self.toDataURL = toDataURL; self.shapeToImage = shapeToImage; _init(); } /** * 控制类 (C) * @param {HTMLElement} root 绘图区域 * @param {storage} storage Storage实例 * @param {painter} painter Painter实例 * @param {Object} shape 图形库 * * 分发事件支持详见config.EVENT */ function Handler(root, storage, painter, shape) { var config = require('./config'); var env = require('./tool/env'); //添加事件分发器特性 var eventTool = require('./tool/event'); eventTool.Dispatcher.call(this); var self = this; //常用函数加速 var getX = eventTool.getX; var getY = eventTool.getY; //各种事件标识的私有变量 var _event; //原生dom事件 var _hasfound = false; //是否找到hover图形元素 var _lastHover = null; //最后一个hover图形元素 var _mouseDownTarget = null; var _draggingTarget = null; //当前被拖拽的图形元素 var _isMouseDown = false; var _isDragging = false; var _lastMouseDownMoment; var _lastTouchMoment; var _lastDownButton; var _lastX = 0; var _lastY = 0; var _mouseX = 0; var _mouseY = 0; var _domHover = painter.getDomHover(); /** * 初始化,事件绑定,支持的所有事件都由如下原生事件计算得来 */ function _init() { if (window.addEventListener) { window.addEventListener('resize', _resizeHandler); if (!env.os.tablet && !env.os.phone) { // mobile的click/move/up/down自己模拟 root.addEventListener('click', _clickHandler); root.addEventListener('mousewheel', _mouseWheelHandler); root.addEventListener('mousemove', _mouseMoveHandler); root.addEventListener('mousedown', _mouseDownHandler); root.addEventListener('mouseup', _mouseUpHandler); } else { // mobile支持 root.addEventListener('touchstart', _touchStartHandler); root.addEventListener('touchmove', _touchMoveHandler); root.addEventListener('touchend', _touchEndHandler); } root.addEventListener('DOMMouseScroll', _mouseWheelHandler); root.addEventListener('mouseout', _mouseOutHandler); } else { window.attachEvent('onresize', _resizeHandler); root.attachEvent('onclick', _clickHandler); root.attachEvent('onmousewheel', _mouseWheelHandler); root.attachEvent('onmousemove', _mouseMoveHandler); root.attachEvent('onmouseout', _mouseOutHandler); root.attachEvent('onmousedown', _mouseDownHandler); root.attachEvent('onmouseup', _mouseUpHandler); } } /** * 窗口大小改变响应函数 * @param {event} event dom事件对象 */ function _resizeHandler(event) { _event = event || window.event; _lastHover = null; _isMouseDown = false; //分发config.EVENT.RESIZE事件,global self.dispatch(config.EVENT.RESIZE, _event); } /** * 点击事件 * @param {event} event dom事件对象 */ function _clickHandler(event) { _event = _zrenderEventFixed(event); //分发config.EVENT.CLICK事件 if (!_lastHover) { _dispatchAgency(_lastHover, config.EVENT.CLICK); } else if (_lastHover && _lastHover.clickable) { _dispatchAgency(_lastHover, config.EVENT.CLICK); } _mouseMoveHandler(_event); } /** * 鼠标滚轮响应函数 * @param {event} event dom事件对象 */ function _mouseWheelHandler(event) { _event = _zrenderEventFixed(event); //分发config.EVENT.MOUSEWHEEL事件 _dispatchAgency(_lastHover, config.EVENT.MOUSEWHEEL); _mouseMoveHandler(_event); } /** * 鼠标(手指)移动响应函数 * @param {event} event dom事件对象 */ function _mouseMoveHandler(event) { if (painter.isLoading()) { return; } _event = _zrenderEventFixed(event); _lastX = _mouseX; _lastY = _mouseY; _mouseX = getX(_event); _mouseY = getY(_event); // 可能出现config.EVENT.DRAGSTART事件 // 避免手抖点击误认为拖拽 //if (_mouseX - _lastX > 1 || _mouseY - _lastY > 1) { _dragStartHandler(); //} _hasfound = false; storage.iterShape(_findHover, { normal: 'down'}); //找到的在迭代函数里做了处理,没找到得在迭代完后处理 if (!_hasfound) { //过滤首次拖拽产生的mouseout和dragLeave if (!_draggingTarget || (_lastHover && _lastHover.id != _draggingTarget.id) ) { //可能出现config.EVENT.MOUSEOUT事件 _outShapeHandler(); //可能出现config.EVENT.DRAGLEAVE事件 _dragLeaveHandler(); } _lastHover = null; storage.delHover(); painter.clearHover(); } //如果存在拖拽中元素,被拖拽的图形元素最后addHover if (_draggingTarget) { storage.drift( _draggingTarget.id, _mouseX - _lastX, _mouseY - _lastY ); storage.addHover(_draggingTarget); } if (_draggingTarget || (_hasfound && _lastHover.draggable)) { root.style.cursor = 'move'; } else if (_hasfound && _lastHover.clickable) { root.style.cursor = 'pointer'; } else { root.style.cursor = 'default'; } //分发config.EVENT.MOUSEMOVE事件 _dispatchAgency(_lastHover, config.EVENT.MOUSEMOVE); if (_draggingTarget || _hasfound || storage.hasHoverShape()) { painter.refreshHover(); } } /** * 鼠标(手指)离开响应函数 * @param {event} event dom事件对象 */ function _mouseOutHandler(event) { _event = _zrenderEventFixed(event); var element = _event.toElement || _event.relatedTarget; if (element != root) { while (element && element.nodeType != 9) { if (element == root) { // 忽略包含在root中的dom引起的mouseOut _mouseMoveHandler(event); return; } element = element.parentNode; } } _event.zrenderX = _lastX; _event.zrenderY = _lastY; root.style.cursor = 'default'; _isMouseDown = false; _outShapeHandler(); _dropHandler(); _dragEndHandler(); if (!painter.isLoading()) { painter.refreshHover(); } self.dispatch(config.EVENT.GLOBALOUT, _event); } /** * 鼠标在某个图形元素上移动 */ function _overShapeHandler() { //分发config.EVENT.MOUSEOVER事件 _dispatchAgency(_lastHover, config.EVENT.MOUSEOVER); } /** * 鼠标离开某个图形元素 */ function _outShapeHandler() { //分发config.EVENT.MOUSEOUT事件 _dispatchAgency(_lastHover, config.EVENT.MOUSEOUT); } /** * 鼠标(手指)按下响应函数 * @param {event} event dom事件对象 */ function _mouseDownHandler(event) { if (_lastDownButton == 2) { _lastDownButton = event.button; _mouseDownTarget = null; // 仅作为关闭右键菜单使用 return; } _lastMouseDownMoment = new Date(); _event = _zrenderEventFixed(event); _isMouseDown = true; //分发config.EVENT.MOUSEDOWN事件 _mouseDownTarget = _lastHover; _dispatchAgency(_lastHover, config.EVENT.MOUSEDOWN); _lastDownButton = event.button; } /** * 鼠标(手指)抬起响应函数 * @param {event} event dom事件对象 */ function _mouseUpHandler(event) { _event = _zrenderEventFixed(event); root.style.cursor = 'default'; _isMouseDown = false; _mouseDownTarget = null; //分发config.EVENT.MOUSEUP事件 _dispatchAgency(_lastHover, config.EVENT.MOUSEUP); _dropHandler(); _dragEndHandler(); } /** * Touch开始响应函数 * @param {event} event dom事件对象 */ function _touchStartHandler(event) { //eventTool.stop(event);// 阻止浏览器默认事件,重要 _event = _zrenderEventFixed(event, true); _lastTouchMoment = new Date(); //平板补充一次findHover _mobildFindFixed(); _mouseDownHandler(_event); } /** * Touch移动响应函数 * @param {event} event dom事件对象 */ function _touchMoveHandler(event) { _event = _zrenderEventFixed(event, true); _mouseMoveHandler(_event); if (_isDragging) { eventTool.stop(event);// 阻止浏览器默认事件,重要 } } /** * Touch结束响应函数 * @param {event} event dom事件对象 */ function _touchEndHandler(event) { //eventTool.stop(event);// 阻止浏览器默认事件,重要 _event = _zrenderEventFixed(event, true); _mouseUpHandler(_event); if (new Date() - _lastTouchMoment < config.EVENT.touchClickDelay ) { _mobildFindFixed(); _clickHandler(_event); } painter.clearHover(); } /** * 拖拽开始 */ function _dragStartHandler() { if (_isMouseDown && _lastHover && _lastHover.draggable && !_draggingTarget && _mouseDownTarget == _lastHover ) { // 拖拽点击生效时长阀门,某些场景需要降低拖拽敏感度 if (_lastHover.dragEnableTime && new Date() - _lastMouseDownMoment < _lastHover.dragEnableTime ) { return; } _draggingTarget = _lastHover; _isDragging = true; _draggingTarget.invisible = true; storage.mod(_draggingTarget.id,_draggingTarget); //分发config.EVENT.DRAGSTART事件 _dispatchAgency( _draggingTarget, config.EVENT.DRAGSTART ); painter.refresh(); } } /** * 拖拽进入目标元素 */ function _dragEnterHandler() { if (_draggingTarget) { //分发config.EVENT.DRAGENTER事件 _dispatchAgency( _lastHover, config.EVENT.DRAGENTER, _draggingTarget ); } } /** * 拖拽在目标元素上移动 */ function _dragOverHandler() { if (_draggingTarget) { //分发config.EVENT.DRAGOVER事件 _dispatchAgency( _lastHover, config.EVENT.DRAGOVER, _draggingTarget ); } } /** * 拖拽离开目标元素 */ function _dragLeaveHandler() { if (_draggingTarget) { //分发config.EVENT.DRAGLEAVE事件 _dispatchAgency( _lastHover, config.EVENT.DRAGLEAVE, _draggingTarget ); } } /** * 拖拽在目标元素上完成 */ function _dropHandler() { if (_draggingTarget) { _draggingTarget.invisible = false; storage.mod(_draggingTarget.id,_draggingTarget); painter.refresh(); //分发config.EVENT.DROP事件 _dispatchAgency( _lastHover, config.EVENT.DROP, _draggingTarget ); } } /** * 拖拽结束 */ function _dragEndHandler() { if (_draggingTarget) { //分发config.EVENT.DRAGEND事件 _dispatchAgency( _draggingTarget, config.EVENT.DRAGEND ); _lastHover = null; } _isDragging = false; _draggingTarget = null; } /** * 事件分发代理 * @param {Object} targetShape 目标图形元素 * @param {string} eventName 事件名称 * @param {Object=} draggedShape 拖拽事件特有,当前被拖拽图形元素 */ function _dispatchAgency(targetShape, eventName, draggedShape) { var eventHandler = 'on' + eventName; var eventPacket = { type : eventName, event : _event, target : targetShape }; if (draggedShape) { eventPacket.dragged = draggedShape; } if (targetShape) { //“不存在shape级事件”或“存在shape级事件但事件回调返回非true” if (!targetShape[eventHandler] || !targetShape[eventHandler](eventPacket) ) { self.dispatch( eventName, _event, eventPacket ); } } else if (!draggedShape) { //无hover目标,无拖拽对象,原生事件分发 self.dispatch(eventName, _event); } } // touch有指尖错觉,四向尝试,让touch上的点击更好触发事件 function _mobildFindFixed() { _lastHover = null; _mouseX = _event.zrenderX; _mouseY = _event.zrenderY; storage.iterShape(_findHover, { normal: 'down'}); if (!_lastHover) { _mouseX += 10; storage.iterShape(_findHover, { normal: 'down'}); } if (!_lastHover) { _mouseX -= 20; storage.iterShape(_findHover, { normal: 'down'}); } if (!_lastHover) { _mouseX += 10; _mouseY += 10; storage.iterShape(_findHover, { normal: 'down'}); } if (!_lastHover) { _mouseY -= 20; storage.iterShape(_findHover, { normal: 'down'}); } if (_lastHover) { _event.zrenderX = _mouseX; _event.zrenderY = _mouseY; } } /** * 迭代函数,查找hover到的图形元素并即时做些事件分发 * @param {Object} e 图形元素 */ function _findHover(e) { if (_draggingTarget && _draggingTarget.id == e.id) { //迭代到当前拖拽的图形上 return false; } //打酱油的路过,啥都不响应的shape~ if (e.__silent) { return false; } var shapeInstance = shape.get(e.shape); if (shapeInstance.isCover(e, _mouseX, _mouseY)) { if (e.hoverable) { storage.addHover(e); } if (_lastHover != e) { _outShapeHandler(); //可能出现config.EVENT.DRAGLEAVE事件 _dragLeaveHandler(); _lastHover = e; //可能出现config.EVENT.DRAGENTER事件 _dragEnterHandler(); } _overShapeHandler(); //可能出现config.EVENT.DRAGOVER _dragOverHandler(); _hasfound = true; return true; //找到则中断迭代查找 } return false; } // 如果存在第三方嵌入的一些dom触发的事件,或touch事件,需要转换一下事件坐标 function _zrenderEventFixed(event, isTouch) { if (!isTouch) { _event = event || window.event; // 进入对象优先~ var target = _event.toElement || _event.relatedTarget || _event.srcElement || _event.target; if (target && target != _domHover) { _event.zrenderX = (typeof _event.offsetX != 'undefined' ? _event.offsetX : _event.layerX) + target.offsetLeft; _event.zrenderY = (typeof _event.offsetY != 'undefined' ? _event.offsetY : _event.layerY) + target.offsetTop; } } else { _event = event; var touch = _event.type != 'touchend' ? _event.targetTouches[0] : _event.changedTouches[0]; if (touch) { // touch事件坐标是全屏的~ _event.zrenderX = touch.clientX - root.offsetLeft + document.body.scrollLeft; _event.zrenderY = touch.clientY - root.offsetTop + document.body.scrollTop; } } return _event; } /** * 自定义事件绑定 * @param {string} eventName 事件名称,resize,hover,drag,etc~ * @param {Function} handler 响应函数 */ function on(eventName, handler) { self.bind(eventName, handler); return self; } /** * 自定义事件解绑 * @param {string} event 事件名称,resize,hover,drag,etc~ * @param {Function} handler 响应函数 */ function un(eventName, handler) { self.unbind(eventName, handler); return self; } /** * 事件触发 * @param {string} event 事件名称,resize,hover,drag,etc~ * @param {event=} event event dom事件对象 */ function trigger(eventName, event) { switch (eventName) { case config.EVENT.RESIZE : _resizeHandler(event); break; case config.EVENT.CLICK : _clickHandler(event); break; case config.EVENT.MOUSEWHEEL : _mouseWheelHandler(event); break; case config.EVENT.MOUSEMOVE : _mouseMoveHandler(event); break; case config.EVENT.MOUSEDOWN : _mouseDownHandler(event); break; case config.EVENT.MOUSEUP : _mouseUpHandleru(event); break; case config.EVENT.MOUSEOUT : _mouseOutHandler(event); break; } } /** * 释放 */ function dispose() { if (window.removeEventListener) { window.removeEventListener('resize', _resizeHandler); if (!env.os.tablet && !env.os.phone) { // mobile的click自己模拟 root.removeEventListener( 'click', _clickHandler ); root.removeEventListener( 'mousewheel', _mouseWheelHandler ); root.removeEventListener( 'mousemove', _mouseMoveHandler ); root.removeEventListener( 'mousedown', _mouseDownHandler ); root.removeEventListener( 'mouseup', _mouseUpHandler ); } else { // mobile支持 root.removeEventListener( 'touchstart', _touchStartHandler ); root.removeEventListener( 'touchmove', _touchMoveHandler ); root.removeEventListener( 'touchend', _touchEndHandler ); } root.removeEventListener( 'DOMMouseScroll', _mouseWheelHandler ); root.removeEventListener( 'mouseout', _mouseOutHandler ); } else { window.detachEvent('onresize', _resizeHandler); root.detachEvent('onclick', _clickHandler); root.detachEvent('onmousewheel', _mouseWheelHandler); root.detachEvent('onmousemove', _mouseMoveHandler); root.detachEvent('onmouseout', _mouseOutHandler); root.detachEvent('onmousedown', _mouseDownHandler); root.detachEvent('onmouseup', _mouseUpHandler); } root = null; _domHover = null; storage = null; painter = null; shape = null; un(); self = null; return; } self.on = on; self.un = un; self.trigger = trigger; self.dispose = dispose; _init(); } return self; } ); define('zrender', ['zrender/zrender'], function (main) { return main; }); /** * echarts扩展zrender shape * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:icon * 可配图形属性: { // 基础属性 shape : 'icon', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,左上角横坐标 y : {number}, // 必须,左上角纵坐标 width : {number}, // 必须,宽度 height : {number}, // 必须,高度 iconType : {string}, // 必须,icon类型 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'icon', id : '123456', zlevel : 1, style : { x : 200, y : 100, width : 150, height : 50, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'echarts/util/shape/icon',['require','zrender/tool/matrix','zrender/shape','zrender/shape','zrender/shape','zrender/shape','zrender/shape/base','zrender/shape'],function(require) { var matrix = require('zrender/tool/matrix'); function Icon() { this.type = 'icon'; this._iconLibrary = { mark : _iconMark, markUndo : _iconMarkUndo, markClear : _iconMarkClear, dataZoom : _iconDataZoom, dataZoomReset : _iconDataZoomReset, restore : _iconRestore, lineChart : _iconLineChart, barChart : _iconBarChart, stackChart : _iconStackChart, tiledChart : _iconTiledChart, dataView : _iconDataView, saveAsImage : _iconSave, cross : _iconCross, circle : _iconCircle, rectangle : _iconRectangle, triangle : _iconTriangle, diamond : _iconDiamond, arrow : _iconArrow, star : _iconStar, heart : _iconHeart, droplet : _iconDroplet, pin : _iconPin, image : _iconImage }; } function _iconMark(ctx, style) { var dx = style.width / 16; var dy = style.height / 16; ctx.moveTo(style.x, style.y + style.height); ctx.lineTo(style.x + 5 * dx, style.y + 14 * dy); ctx.lineTo(style.x + style.width, style.y + 3 * dy); ctx.lineTo(style.x + 13 * dx, style.y); ctx.lineTo(style.x + 2 * dx, style.y + 11 * dy); ctx.lineTo(style.x, style.y + style.height); ctx.moveTo(style.x + 6 * dx, style.y + 10 * dy); ctx.lineTo(style.x + 14 * dx, style.y + 2 * dy); ctx.moveTo(style.x + 10 * dx, style.y + 13 * dy); ctx.lineTo(style.x + style.width, style.y + 13 * dy); ctx.moveTo(style.x + 13 * dx, style.y + 10 * dy); ctx.lineTo(style.x + 13 * dx, style.y + style.height); } function _iconMarkUndo(ctx, style) { var dx = style.width / 16; var dy = style.height / 16; ctx.moveTo(style.x, style.y + style.height); ctx.lineTo(style.x + 5 * dx, style.y + 14 * dy); ctx.lineTo(style.x + style.width, style.y + 3 * dy); ctx.lineTo(style.x + 13 * dx, style.y); ctx.lineTo(style.x + 2 * dx, style.y + 11 * dy); ctx.lineTo(style.x, style.y + style.height); ctx.moveTo(style.x + 6 * dx, style.y + 10 * dy); ctx.lineTo(style.x + 14 * dx, style.y + 2 * dy); ctx.moveTo(style.x + 10 * dx, style.y + 13 * dy); ctx.lineTo(style.x + style.width, style.y + 13 * dy); } function _iconMarkClear(ctx, style) { var dx = style.width / 16; var dy = style.height / 16; ctx.moveTo(style.x + 4 * dx, style.y + 15 * dy); ctx.lineTo(style.x + 9 * dx, style.y + 13 * dy); ctx.lineTo(style.x + 14 * dx, style.y + 8 * dy); ctx.lineTo(style.x + 11 * dx, style.y + 5 * dy); ctx.lineTo(style.x + 6 * dx, style.y + 10 * dy); ctx.lineTo(style.x + 4 * dx, style.y + 15 * dy); ctx.moveTo(style.x + 5 * dx, style.y); ctx.lineTo(style.x + 11 * dx, style.y); ctx.moveTo(style.x + 5 * dx, style.y + dy); ctx.lineTo(style.x + 11 * dx, style.y + dy); ctx.moveTo(style.x, style.y + 2 * dy); ctx.lineTo(style.x + style.width, style.y + 2 * dy); ctx.moveTo(style.x, style.y + 5 * dy); ctx.lineTo(style.x + 3 * dx, style.y + style.height); ctx.lineTo(style.x + 13 * dx, style.y + style.height); ctx.lineTo(style.x + style.width, style.y + 5 * dy); } function _iconDataZoom(ctx, style) { var dx = style.width / 16; var dy = style.height / 16; ctx.moveTo(style.x, style.y + 3 * dy); ctx.lineTo(style.x + 6 * dx, style.y + 3 * dy); ctx.moveTo(style.x + 3 * dx, style.y); ctx.lineTo(style.x + 3 * dx, style.y + 6 * dy); ctx.moveTo(style.x + 3 * dx, style.y + 8 * dy); ctx.lineTo(style.x + 3 * dx, style.y + style.height); ctx.lineTo(style.x + style.width, style.y + style.height); ctx.lineTo(style.x + style.width, style.y + 3 * dy); ctx.lineTo(style.x + 8 * dx, style.y + 3 * dy); ctx.moveTo(style.x, style.y); // 避免closePath ctx.lineTo(style.x, style.y); // 避免closePath } function _iconDataZoomReset(ctx, style) { var dx = style.width / 16; var dy = style.height / 16; ctx.moveTo(style.x + 6 * dx, style.y); ctx.lineTo(style.x + 2 * dx, style.y + 3 * dy); ctx.lineTo(style.x + 6 * dx, style.y + 6 * dy); ctx.moveTo(style.x + 2 * dx, style.y + 3 * dy); ctx.lineTo(style.x + 14 * dx, style.y + 3 * dy); ctx.lineTo(style.x + 14 * dx, style.y + 11 * dy); ctx.moveTo(style.x + 2 * dx, style.y + 5 * dy); ctx.lineTo(style.x + 2 * dx, style.y + 13 * dy); ctx.lineTo(style.x + 14 * dx, style.y + 13 * dy); ctx.moveTo(style.x + 10 * dx, style.y + 10 * dy); ctx.lineTo(style.x + 14 * dx, style.y + 13 * dy); ctx.lineTo(style.x + 10 * dx, style.y + style.height); ctx.moveTo(style.x, style.y); // 避免closePath ctx.lineTo(style.x, style.y); // 避免closePath } function _iconRestore(ctx, style) { var dx = style.width / 16; var dy = style.height / 16; var r = style.width / 2; ctx.lineWidth = 1.5; ctx.arc(style.x + r, style.y + r, r - dx, 0, Math.PI * 2 / 3); ctx.moveTo(style.x + 3 * dx, style.y + style.height); ctx.lineTo(style.x + 0 * dx, style.y + 12 * dy); ctx.lineTo(style.x + 5 * dx, style.y + 11 * dy); ctx.moveTo(style.x, style.y + 8 * dy); ctx.arc(style.x + r, style.y + r, r - dx, Math.PI, Math.PI * 5 / 3); ctx.moveTo(style.x + 13 * dx, style.y); ctx.lineTo(style.x + style.width, style.y + 4 * dy); ctx.lineTo(style.x + 11 * dx, style.y + 5 * dy); ctx.moveTo(style.x, style.y); // 避免closePath ctx.lineTo(style.x, style.y); // 避免closePath } function _iconLineChart(ctx, style) { var dx = style.width / 16; var dy = style.height / 16; ctx.moveTo(style.x, style.y); ctx.lineTo(style.x, style.y + style.height); ctx.lineTo(style.x + style.width, style.y + style.height); ctx.moveTo(style.x + 2 * dx, style.y + 14 * dy); ctx.lineTo(style.x + 7 * dx, style.y + 6 * dy); ctx.lineTo(style.x + 11 * dx, style.y + 11 * dy); ctx.lineTo(style.x + 15 * dx, style.y + 2 * dy); ctx.moveTo(style.x, style.y); // 避免closePath ctx.lineTo(style.x, style.y); // 避免closePath } function _iconBarChart(ctx, style) { var dx = style.width / 16; var dy = style.height / 16; ctx.moveTo(style.x, style.y); ctx.lineTo(style.x, style.y + style.height); ctx.lineTo(style.x + style.width, style.y + style.height); ctx.moveTo(style.x + 3 * dx, style.y + 14 * dy); ctx.lineTo(style.x + 3 * dx, style.y + 6 * dy); ctx.lineTo(style.x + 4 * dx, style.y + 6 * dy); ctx.lineTo(style.x + 4 * dx, style.y + 14 * dy); ctx.moveTo(style.x + 7 * dx, style.y + 14 * dy); ctx.lineTo(style.x + 7 * dx, style.y + 2 * dy); ctx.lineTo(style.x + 8 * dx, style.y + 2 * dy); ctx.lineTo(style.x + 8 * dx, style.y + 14 * dy); ctx.moveTo(style.x + 11 * dx, style.y + 14 * dy); ctx.lineTo(style.x + 11 * dx, style.y + 9 * dy); ctx.lineTo(style.x + 12 * dx, style.y + 9 * dy); ctx.lineTo(style.x + 12 * dx, style.y + 14 * dy); } function _iconStackChart(ctx, style) { var x = style.x; var y = style.y; var width = style.width; var height = style.height; var dy = Math.round(height / 3); var len = 3; while (len--) { ctx.rect(x, y + dy * len + 2, width, 2); } } function _iconTiledChart(ctx, style) { var x = style.x; var y = style.y; var width = style.width; var height = style.height; var dx = Math.round(width / 3); var len = 3; while (len--) { ctx.rect(x + dx * len, y, 2, height); } } function _iconDataView(ctx, style) { var dx = style.width / 16; ctx.moveTo(style.x + dx, style.y); ctx.lineTo(style.x + dx, style.y + style.height); ctx.lineTo(style.x + 15 * dx, style.y + style.height); ctx.lineTo(style.x + 15 * dx, style.y); ctx.lineTo(style.x + dx, style.y); ctx.moveTo(style.x + 3 * dx, style.y + 3 * dx); ctx.lineTo(style.x + 13 * dx, style.y + 3 * dx); ctx.moveTo(style.x + 3 * dx, style.y + 6 * dx); ctx.lineTo(style.x + 13 * dx, style.y + 6 * dx); ctx.moveTo(style.x + 3 * dx, style.y + 9 * dx); ctx.lineTo(style.x + 13 * dx, style.y + 9 * dx); ctx.moveTo(style.x + 3 * dx, style.y + 12 * dx); ctx.lineTo(style.x + 9 * dx, style.y + 12 * dx); } function _iconSave(ctx, style) { var dx = style.width / 16; var dy = style.height / 16; ctx.moveTo(style.x, style.y); ctx.lineTo(style.x, style.y + style.height); ctx.lineTo(style.x + style.width, style.y + style.height); ctx.lineTo(style.x + style.width, style.y); ctx.lineTo(style.x, style.y); ctx.moveTo(style.x + 4 * dx, style.y); ctx.lineTo(style.x + 4 * dx, style.y + 8 * dy); ctx.lineTo(style.x + 12 * dx, style.y + 8 * dy); ctx.lineTo(style.x + 12 * dx, style.y); ctx.moveTo(style.x + 6 * dx, style.y + 11 * dy); ctx.lineTo(style.x + 6 * dx, style.y + 13 * dy); ctx.lineTo(style.x + 10 * dx, style.y + 13 * dy); ctx.lineTo(style.x + 10 * dx, style.y + 11 * dy); ctx.lineTo(style.x + 6 * dx, style.y + 11 * dy); ctx.moveTo(style.x, style.y); // 避免closePath ctx.lineTo(style.x, style.y); // 避免closePath } function _iconCross(ctx, style) { var x = style.x; var y = style.y; var width = style.width; var height = style.height; ctx.moveTo(x, y + height / 2); ctx.lineTo(x + width, y + height / 2); ctx.moveTo(x + width / 2, y); ctx.lineTo(x + width / 2, y + height); } function _iconCircle(ctx, style) { var width = style.width / 2; var height = style.height / 2; var r = Math.min(width, height); ctx.moveTo( style.x + width + r, style.y + height ); ctx.arc( style.x + width, style.y + height, r, 0, Math.PI * 2 ); } function _iconRectangle(ctx, style) { ctx.rect(style.x, style.y, style.width, style.height); } function _iconTriangle(ctx, style) { var width = style.width / 2; var height = style.height / 2; var x = style.x + width; var y = style.y + height; var symbolSize = Math.min(width, height); ctx.moveTo(x, y - symbolSize); ctx.lineTo(x + symbolSize, y + symbolSize); ctx.lineTo(x - symbolSize, y + symbolSize); ctx.lineTo(x, y - symbolSize); } function _iconDiamond(ctx, style) { var width = style.width / 2; var height = style.height / 2; var x = style.x + width; var y = style.y + height; var symbolSize = Math.min(width, height); ctx.moveTo(x, y - symbolSize); ctx.lineTo(x + symbolSize, y); ctx.lineTo(x, y + symbolSize); ctx.lineTo(x - symbolSize, y); ctx.lineTo(x, y - symbolSize); } function _iconArrow(ctx, style) { var x = style.x; var y = style.y; var dx = style.width / 16; ctx.moveTo(x + 8 * dx, y); ctx.lineTo(x + dx, y + style.height); ctx.lineTo(x + 8 * dx, y + style.height / 4 * 3); ctx.lineTo(x + 15 * dx, y + style.height); ctx.lineTo(x + 8 * dx, y); } function _iconStar(ctx, style) { var width = style.width / 2; var height = style.height / 2; var star = require('zrender/shape').get('star'); star.buildPath(ctx, { x : style.x + width, y : style.y + height, r : Math.min(width, height), n : style.n || 5 }); } function _iconHeart(ctx, style) { var heart = require('zrender/shape').get('heart'); heart.buildPath(ctx, { x : style.x + style.width / 2, y : style.y + style.height * 0.2, a : style.width / 2, b : style.height * 0.8 }); } function _iconDroplet(ctx, style) { var droplet = require('zrender/shape').get('droplet'); droplet.buildPath(ctx, { x : style.x + style.width * 0.5, y : style.y + style.height * 0.5, a : style.width * 0.5, b : style.height * 0.8 }); } function _iconPin(ctx, style) { var x = style.x; var y = style.y - style.height / 2 * 1.5; var width = style.width / 2; var height = style.height / 2; var r = Math.min(width, height); ctx.arc( x + width, y + height, r, Math.PI / 5 * 4, Math.PI / 5 ); ctx.lineTo(x + width, y + height + r * 1.5); } function _iconImage(ctx, style) { setTimeout(function(){ require('zrender/shape').get('image').brush(ctx, { style : style }); },100); } Icon.prototype = { /** * 创建矩形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { if (this._iconLibrary[style.iconType]) { this._iconLibrary[style.iconType](ctx, style); } else { ctx.moveTo(style.x, style.y); ctx.lineTo(style.x + style.width, style.y); ctx.lineTo(style.x + style.width, style.y + style.height); ctx.lineTo(style.x, style.y + style.height); ctx.lineTo(style.x, style.y); } return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { // pin比较特殊,让尖端在目标x,y上 return { x : Math.round(style.x), y : Math.round(style.y - (style.iconType == 'pin' ? (style.height / 2 * 1.5) : 0) ), width : style.width, height : style.height }; }, isCover : function(e, x, y) { //对鼠标的坐标也做相同的变换 if(e.__needTransform && e._transform){ var inverseMatrix = []; matrix.invert(inverseMatrix, e._transform); var originPos = [x, y]; matrix.mulVector(originPos, inverseMatrix, [x, y, 1]); if (x == originPos[0] && y == originPos[1]) { // 避免外部修改导致的__needTransform不准确 if (Math.abs(e.rotation[0]) > 0.0001 || Math.abs(e.position[0]) > 0.0001 || Math.abs(e.position[1]) > 0.0001 || Math.abs(e.scale[0] - 1) > 0.0001 || Math.abs(e.scale[1] - 1) > 0.0001 ) { e.__needTransform = true; } else { e.__needTransform = false; } } x = originPos[0]; y = originPos[1]; } // 快速预判并保留判断矩形 var rect; if (e.style.__rect) { rect = e.style.__rect; } else { rect = this.getRect(e.style); e.style.__rect = rect; } // 提高交互体验,太小的图形包围盒四向扩大4px var delta = (rect.height < 8 || rect.width < 8 ) ? 4 : 0; if (x >= rect.x - delta && x <= (rect.x + rect.width + delta) && y >= rect.y - delta && y <= (rect.y + rect.height + delta) ) { // 矩形内 return true; } else { return false; } }, define : function(iconType, pathMethod) { this._iconLibrary[iconType] = pathMethod; }, get : function(iconType) { return this._iconLibrary[iconType]; } }; require('zrender/shape/base').derive(Icon); require('zrender/shape').define('icon', new Icon()); return Icon; } ); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:标线 */ define( 'echarts/util/shape/markLine',['require','zrender/tool/matrix','zrender/shape','zrender/shape','zrender/shape/base','zrender/shape'],function(require) { var matrix = require('zrender/tool/matrix'); function MarkLine() { this.type = 'markLine'; } MarkLine.prototype = { /** * 画刷 * @param ctx 画布句柄 * @param e 形状实体 * @param isHighlight 是否为高亮状态 * @param updateCallback 需要异步加载资源的shape可以通过这个callback(e) * 让painter更新视图,base.brush没用,需要的话重载brush */ brush : function(ctx, e, isHighlight) { var style = e.style || {}; if (isHighlight) { // 根据style扩展默认高亮样式 style = this.getHighlightStyle( style, e.highlightStyle || {} ); } ctx.save(); this.setContext(ctx, style); // 设置transform if (e.__needTransform) { ctx.transform.apply(ctx,this.updateTransform(e)); } ctx.beginPath(); this.buildLinePath(ctx, style); ctx.stroke(); this.brushSymbol(e, ctx, style, 0); this.brushSymbol(e, ctx, style, 1); if (typeof style.text != 'undefined') { this.drawText(ctx, style, e.style); } ctx.restore(); return; }, /** * 创建线条路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildLinePath : function(ctx, style) { var pointList = style.pointList || this.getPointList(style); style.pointList = pointList; if (typeof style.pointListLength == 'undefined') { style.pointListLength = pointList.length; } var len = Math.round(style.pointListLength); if (!style.lineType || style.lineType == 'solid') { //默认为实线 ctx.moveTo(pointList[0][0],pointList[0][1]); for (var i = 1; i < len; i++) { ctx.lineTo(pointList[i][0],pointList[i][1]); } } else if (style.lineType == 'dashed' || style.lineType == 'dotted' ) { if (style.smooth !== 'spline') { // 直线 var dashLength = (style.lineWidth || 1) * (style.lineType == 'dashed' ? 5 : 1); ctx.moveTo(pointList[0][0],pointList[0][1]); for (var i = 1; i < len; i++) { this.dashedLineTo( ctx, pointList[i - 1][0], pointList[i - 1][1], pointList[i][0], pointList[i][1], dashLength ); } } else { // 曲线 for (var i = 0; i < len - 1; i += 2) { ctx.moveTo(pointList[i][0],pointList[i][1]); ctx.lineTo(pointList[i + 1][0],pointList[i + 1][1]); } } } }, /** * 标线始末标注 */ brushSymbol : function(e, ctx, style, idx) { if (style.symbol[idx] == 'none') { return; } ctx.save(); ctx.beginPath(); ctx.lineWidth = style.symbolBorder; ctx.strokeStyle = style.symbolBorderColor; // symbol style.iconType = style.symbol[idx].replace('empty', '') .toLowerCase(); if (style.symbol[idx].match('empty')) { ctx.fillStyle = '#fff'; //'rgba(0, 0, 0, 0)'; } // symbolRotate var len = Math.round(style.pointListLength || style.pointList.length); var x = idx === 0 ? style.pointList[0][0] : style.pointList[len - 1][0]; var y = idx === 0 ? style.pointList[0][1] : style.pointList[len - 1][1]; var rotate = typeof style.symbolRotate[idx] != 'undefined' ? (style.symbolRotate[idx] - 0) : 0; var transform; if (rotate !== 0) { transform = matrix.create(); matrix.identity(transform); if (x || y ) { matrix.translate(transform, transform, [-x, -y]); } matrix.rotate( transform, transform, rotate * Math.PI / 180 ); if (x || y ) { matrix.translate(transform, transform, [x, y]); } ctx.transform.apply(ctx, transform); } if (style.iconType == 'arrow' && rotate === 0) { // 箭头自动旋转,手动画 this.buildArrawPath(ctx, style, idx); } else { // symbolSize var symbolSize = style.symbolSize[idx]; style.x = x - symbolSize; style.y = y - symbolSize, style.width = symbolSize * 2; style.height = symbolSize * 2; require('zrender/shape').get('icon').buildPath(ctx, style); } ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.restore(); }, buildArrawPath : function (ctx, style, idx) { var len = Math.round(style.pointListLength || style.pointList.length); var symbolSize = style.symbolSize[idx] * 2; var xStart = style.pointList[0][0]; var xEnd = style.pointList[len - 1][0]; var yStart = style.pointList[0][1]; var yEnd = style.pointList[len - 1][1]; var delta = 0; if (style.smooth === 'spline') { delta = 0.2; // 偏移0.2弧度 } // 原谅我吧,这三角函数实在没想明白,只能这么笨了 var rotate = Math.atan( Math.abs((yEnd - yStart) / (xStart - xEnd) )); if (idx === 0) { if (xEnd > xStart) { if (yEnd > yStart) { rotate = Math.PI * 2 - rotate + delta; } else { rotate += delta; } } else { if (yEnd > yStart) { rotate += Math.PI - delta; } else { rotate = Math.PI - rotate - delta; } } } else { if (xStart > xEnd) { if (yStart > yEnd) { rotate = Math.PI * 2 - rotate + delta; } else { rotate += delta; } } else { if (yStart > yEnd) { rotate += Math.PI - delta; } else { rotate = Math.PI - rotate - delta; } } } var halfRotate = Math.PI / 8; // 夹角 var x = idx === 0 ? xStart : xEnd; var y = idx === 0 ? yStart : yEnd; var point= [ [ x + symbolSize * Math.cos(rotate - halfRotate), y - symbolSize * Math.sin(rotate - halfRotate), ], [ x + symbolSize * 0.6 * Math.cos(rotate), y - symbolSize * 0.6 * Math.sin(rotate), ], [ x + symbolSize * Math.cos(rotate + halfRotate), y - symbolSize * Math.sin(rotate + halfRotate), ] ]; ctx.moveTo(x, y); for (var i = 0, l = point.length; i 1 ? ('.' + x[1]) : ''); } return { parsePercent : parsePercent, parseCenter : parseCenter, parseRadius : parseRadius, addCommas : addCommas }; }); /** * echarts组件基类 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/base',['require','../util/ecData','../util/ecQuery','../util/number','zrender/tool/util','zrender/tool/area','zrender/tool/env'],function(require) { function Base(ecConfig, zr){ var ecData = require('../util/ecData'); var ecQuery = require('../util/ecQuery'); var number = require('../util/number'); var zrUtil = require('zrender/tool/util'); var zrArea = require('zrender/tool/area'); //var zrColor = require('zrender/tool/color'); var self = this; self.zr =zr; self.shapeList = []; self.effectList = []; var EFFECT_ZLEVEL = 7; var _canvasSupported = require('zrender/tool/env').canvasSupported; var _aniMap = {}; _aniMap[ecConfig.CHART_TYPE_LINE] = true; _aniMap[ecConfig.CHART_TYPE_BAR] = true; _aniMap[ecConfig.CHART_TYPE_SCATTER] = true; _aniMap[ecConfig.CHART_TYPE_PIE] = true; _aniMap[ecConfig.CHART_TYPE_RADAR] = true; _aniMap[ecConfig.CHART_TYPE_MAP] = true; _aniMap[ecConfig.CHART_TYPE_K] = true; _aniMap[ecConfig.CHART_TYPE_CHORD] = true; /** * 获取zlevel基数配置 * @param {Object} contentType */ function getZlevelBase(contentType) { contentType = contentType || self.type + ''; switch (contentType) { case ecConfig.COMPONENT_TYPE_GRID : case ecConfig.COMPONENT_TYPE_AXIS_CATEGORY : case ecConfig.COMPONENT_TYPE_AXIS_VALUE : return 0; case ecConfig.CHART_TYPE_LINE : case ecConfig.CHART_TYPE_BAR : case ecConfig.CHART_TYPE_SCATTER : case ecConfig.CHART_TYPE_PIE : case ecConfig.CHART_TYPE_RADAR : case ecConfig.CHART_TYPE_MAP : case ecConfig.CHART_TYPE_K : case ecConfig.CHART_TYPE_CHORD: return 2; case ecConfig.COMPONENT_TYPE_LEGEND : case ecConfig.COMPONENT_TYPE_DATARANGE: case ecConfig.COMPONENT_TYPE_DATAZOOM : return 4; case ecConfig.CHART_TYPE_ISLAND : return 5; case ecConfig.COMPONENT_TYPE_TOOLBOX : case ecConfig.COMPONENT_TYPE_TITLE : return 6; // EFFECT_ZLEVEL = 7; case ecConfig.COMPONENT_TYPE_TOOLTIP : return 8; default : return 0; } } /** * 参数修正&默认值赋值 * @param {Object} opt 参数 * * @return {Object} 修正后的参数 */ function reformOption(opt) { return zrUtil.merge( opt || {}, zrUtil.clone(ecConfig[self.type] || {}), { 'overwrite': false, 'recursive': true } ); } /** * css类属性数组补全,如padding,margin等~ */ function reformCssArray(p) { if (p instanceof Array) { switch (p.length + '') { case '4': return p; case '3': return [p[0], p[1], p[2], p[1]]; case '2': return [p[0], p[1], p[0], p[1]]; case '1': return [p[0], p[0], p[0], p[0]]; case '0': return [0, 0, 0, 0]; } } else { return [p, p, p, p]; } } /** * 获取自定义和默认配置合并后的字体设置 */ function getFont(textStyle) { var finalTextStyle = zrUtil.merge( zrUtil.clone(textStyle) || {}, ecConfig.textStyle, { 'overwrite': false} ); return finalTextStyle.fontStyle + ' ' + finalTextStyle.fontWeight + ' ' + finalTextStyle.fontSize + 'px ' + finalTextStyle.fontFamily; } /** * 添加文本 */ function addLabel(tarShape, serie, data, name, orient) { // 多级控制 var queryTarget = [data, serie]; var nLabel = self.deepMerge(queryTarget, 'itemStyle.normal.label'); var eLabel = self.deepMerge(queryTarget, 'itemStyle.emphasis.label'); var nTextStyle = nLabel.textStyle || {}; var eTextStyle = eLabel.textStyle || {}; if (nLabel.show) { tarShape.style.text = _getLabelText( serie, data, name, 'normal' ); tarShape.style.textPosition = typeof nLabel.position == 'undefined' ? (orient == 'horizontal' ? 'right' : 'top') : nLabel.position; tarShape.style.textColor = nTextStyle.color; tarShape.style.textFont = self.getFont(nTextStyle); } if (eLabel.show) { tarShape.highlightStyle.text = _getLabelText( serie, data, name, 'emphasis' ); tarShape.highlightStyle.textPosition = nLabel.show ? tarShape.style.textPosition : (typeof eLabel.position == 'undefined' ? (orient == 'horizontal' ? 'right' : 'top') : eLabel.position); tarShape.highlightStyle.textColor = eTextStyle.color; tarShape.highlightStyle.textFont = self.getFont(eTextStyle); } return tarShape; } /** * 根据lable.format计算label text */ function _getLabelText(serie, data, name, status) { var formatter = self.deepQuery( [data, serie], 'itemStyle.' + status + '.label.formatter' ); if (!formatter && status == 'emphasis') { // emphasis时需要看看normal下是否有formatter formatter = self.deepQuery( [data, serie], 'itemStyle.normal.label.formatter' ); } var value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; if (formatter) { if (typeof formatter == 'function') { return formatter( serie.name, name, value ); } else if (typeof formatter == 'string') { formatter = formatter.replace('{a}','{a0}') .replace('{b}','{b0}') .replace('{c}','{c0}'); formatter = formatter.replace('{a0}', serie.name) .replace('{b0}', name) .replace('{c0}', value); return formatter; } } else { return value; } } function buildMark( serie, seriesIndex, component, markCoordParams, attachStyle ) { if (self.selectedMap[serie.name]) { serie.markPoint && _buildMarkPoint( serie, seriesIndex, component, markCoordParams, attachStyle ); serie.markLine && _buildMarkLine( serie, seriesIndex, component, markCoordParams, attachStyle ); } } function _buildMarkPoint( serie, seriesIndex, component, markCoordParams, attachStyle ) { var _zlevelBase = self.getZlevelBase(); var mpData; var pos; var markPoint = zrUtil.clone(serie.markPoint); for (var i = 0, l = markPoint.data.length; i < l; i++) { mpData = markPoint.data[i]; pos = self.getMarkCoord( serie, seriesIndex, mpData, markCoordParams ); markPoint.data[i].x = typeof mpData.x != 'undefined' ? mpData.x : pos[0]; markPoint.data[i].y = typeof mpData.y != 'undefined' ? mpData.y : pos[1]; if (mpData.type && (mpData.type == 'max' || mpData.type == 'min') ) { // 特殊值内置支持 markPoint.data[i].value = pos[3]; markPoint.data[i].name = mpData.name || mpData.type; markPoint.data[i].symbolSize = markPoint.data[i].symbolSize || (zrArea.getTextWidth(pos[3], self.getFont()) / 2 + 5); } } var shapeList = _markPoint( serie, seriesIndex, markPoint, component ); for (var i = 0, l = shapeList.length; i < l; i++) { shapeList[i].zlevel = _zlevelBase + 1; /* shapeList[i]._mark = 'point'; shapeList[i]._x = shapeList[i].style.x + shapeList[i].style.width / 2; shapeList[i]._y = shapeList[i].style.y + shapeList[i].style.height / 2; */ for (var key in attachStyle) { shapeList[i][key] = attachStyle[key]; } self.shapeList.push(shapeList[i]); } // 个别特殊图表需要自己addShape if (self.type == ecConfig.CHART_TYPE_FORCE || self.type == ecConfig.CHART_TYPE_CHORD ) { for (var i = 0, l = shapeList.length; i < l; i++) { shapeList[i].id = self.zr.newShapeId(self.type); self.zr.addShape(shapeList[i]); } } } function _buildMarkLine( serie, seriesIndex, component, markCoordParams, attachStyle ) { var _zlevelBase = self.getZlevelBase(); var mlData; var pos; var markLine = zrUtil.clone(serie.markLine); for (var i = 0, l = markLine.data.length; i < l; i++) { mlData = markLine.data[i]; if (mlData.type && (mlData.type == 'max' || mlData.type == 'min' || mlData.type == 'average') ) { // 特殊值内置支持 pos = self.getMarkCoord(serie, seriesIndex, mlData, markCoordParams); markLine.data[i] = [zrUtil.clone(mlData), {}]; markLine.data[i][0].name = mlData.name || mlData.type; markLine.data[i][0].value = pos[3]; pos = pos[2]; mlData = [{},{}]; } else { pos = [ self.getMarkCoord( serie, seriesIndex, mlData[0], markCoordParams ), self.getMarkCoord( serie, seriesIndex, mlData[1], markCoordParams ) ]; } markLine.data[i][0].x = typeof mlData[0].x != 'undefined' ? mlData[0].x : pos[0][0]; markLine.data[i][0].y = typeof mlData[0].y != 'undefined' ? mlData[0].y : pos[0][1]; markLine.data[i][1].x = typeof mlData[1].x != 'undefined' ? mlData[1].x : pos[1][0]; markLine.data[i][1].y = typeof mlData[1].y != 'undefined' ? mlData[1].y : pos[1][1]; } var shapeList = _markLine( serie, seriesIndex, markLine, component ); for (var i = 0, l = shapeList.length; i < l; i++) { shapeList[i].zlevel = _zlevelBase + 1; for (var key in attachStyle) { shapeList[i][key] = attachStyle[key]; } self.shapeList.push(shapeList[i]); } // 个别特殊图表需要自己addShape if (self.type == ecConfig.CHART_TYPE_FORCE || self.type == ecConfig.CHART_TYPE_CHORD ) { for (var i = 0, l = shapeList.length; i < l; i++) { shapeList[i].id = self.zr.newShapeId(self.type); self.zr.addShape(shapeList[i]); } } } function _markPoint(serie, seriesIndex, mpOption, component) { zrUtil.merge( mpOption, ecConfig.markPoint, { 'overwrite': false, 'recursive': true } ); mpOption.name = serie.name; var pList = []; var data = mpOption.data; var itemShape; var dataRange = component.dataRange; var legend = component.legend; var color; var value; var queryTarget; var nColor; var eColor; var effect; var zrWidth = self.zr.getWidth(); var zrHeight = self.zr.getHeight(); for (var i = 0, l = data.length; i < l; i++) { // 图例 if (legend) { color = legend.getColor(serie.name); } // 值域 if (dataRange) { value = typeof data[i] != 'undefined' ? (typeof data[i].value != 'undefined' ? data[i].value : data[i]) : '-'; color = isNaN(value) ? color : dataRange.getColor(value); queryTarget = [data[i], mpOption]; nColor = self.deepQuery( queryTarget, 'itemStyle.normal.color' ) || color; eColor = self.deepQuery( queryTarget, 'itemStyle.emphasis.color' ) || nColor; // 有值域,并且值域返回null且用户没有自己定义颜色,则隐藏这个mark if (nColor == null && eColor == null) { continue; } } // 标准化一些参数 data[i].tooltip = {trigger:'item'}; // tooltip.trigger指定为item data[i].name = typeof data[i].name != 'undefined' ? data[i].name : ''; data[i].value = typeof data[i].value != 'undefined' ? data[i].value : ''; // 复用getSymbolShape itemShape = getSymbolShape( mpOption, seriesIndex, // 系列 data[i], i, data[i].name, // 数据 self.parsePercent(data[i].x, zrWidth), // 坐标 self.parsePercent(data[i].y, zrHeight), // 坐标 'pin', color, // 默认symbol和color 'rgba(0,0,0,0)', 'horizontal' // 走向,用于默认文字定位 ); effect = self.deepMerge( [data[i], mpOption], 'effect' ); if (effect.show) { itemShape.effect = effect; } // 重新pack一下数据 ecData.pack( itemShape, serie, seriesIndex, data[i], 0, data[i].name ); pList.push(itemShape); } //console.log(pList); return pList; } function _markLine(serie, seriesIndex, mlOption, component) { zrUtil.merge( mlOption, ecConfig.markLine, { 'overwrite': false, 'recursive': true } ); // 标准化一些同时支持Array和String的参数 mlOption.symbol = mlOption.symbol instanceof Array ? mlOption.symbol.length > 1 ? mlOption.symbol : [mlOption.symbol[0], mlOption.symbol[0]] : [mlOption.symbol, mlOption.symbol]; mlOption.symbolSize = mlOption.symbolSize instanceof Array ? mlOption.symbolSize.length > 1 ? mlOption.symbolSize : [mlOption.symbolSize[0], mlOption.symbolSize[0]] : [mlOption.symbolSize, mlOption.symbolSize]; mlOption.symbolRotate = mlOption.symbolRotate instanceof Array ? mlOption.symbolRotate.length > 1 ? mlOption.symbolRotate : [mlOption.symbolRotate[0], mlOption.symbolRotate[0]] : [mlOption.symbolRotate, mlOption.symbolRotate]; mlOption.name = serie.name; var pList = []; var data = mlOption.data; var itemShape; var dataRange = component.dataRange; var legend = component.legend; var color; var value; var queryTarget; var nColor; var eColor; var effect; var zrWidth = self.zr.getWidth(); var zrHeight = self.zr.getHeight(); var mergeData; for (var i = 0, l = data.length; i < l; i++) { // 图例 if (legend) { color = legend.getColor(serie.name); } // 组装一个mergeData mergeData = self.deepMerge(data[i]); // 值域 if (dataRange) { value = typeof mergeData != 'undefined' ? (typeof mergeData.value != 'undefined' ? mergeData.value : mergeData) : '-'; color = isNaN(value) ? color : dataRange.getColor(value); queryTarget = [mergeData, mlOption]; nColor = self.deepQuery( queryTarget, 'itemStyle.normal.color' ) || color; eColor = self.deepQuery( queryTarget, 'itemStyle.emphasis.color' ) || nColor; // 有值域,并且值域返回null且用户没有自己定义颜色,则隐藏这个mark if (nColor == null && eColor == null) { continue; } } // 标准化一些参数 data[i][0].tooltip = mergeData.tooltip || {trigger:'item'}; // tooltip.trigger指定为item data[i][0].name = typeof data[i][0].name != 'undefined' ? data[i][0].name : ''; data[i][1].name = typeof data[i][1].name != 'undefined' ? data[i][1].name : ''; data[i][0].value = typeof data[i][0].value != 'undefined' ? data[i][0].value : ''; itemShape = getLineMarkShape( mlOption, // markLine seriesIndex, data[i], // 数据 i, self.parsePercent(data[i][0].x, zrWidth), // 坐标 self.parsePercent(data[i][0].y, zrHeight), // 坐标 self.parsePercent(data[i][1].x, zrWidth), // 坐标 self.parsePercent(data[i][1].y, zrHeight), // 坐标 color // 默认symbol和color ); effect = self.deepMerge( [mergeData, mlOption], 'effect' ); if (effect.show) { itemShape.effect = effect; } // 重新pack一下数据 ecData.pack( itemShape, serie, seriesIndex, data[i][0], 0, data[i][0].name + (data[i][1].name !== '' ? (' > ' + data[i][1].name) : '') ); pList.push(itemShape); } //console.log(pList); return pList; } function getMarkCoord() { // 无转换位置 return [0, 0]; } function getSymbolShape( serie, seriesIndex, // 系列 data, dataIndex, name, // 数据 x, y, // 坐标 symbol, color, // 默认symbol和color,来自legend或dataRange全局分配 emptyColor, // 折线的emptySymbol用白色填充 orient // 走向,用于默认文字定位 ) { var queryTarget = [data, serie]; var value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; symbol = self.deepQuery(queryTarget, 'symbol') || symbol; var symbolSize = self.deepQuery(queryTarget, 'symbolSize'); symbolSize = typeof symbolSize == 'function' ? symbolSize(value) : symbolSize; var symbolRotate = self.deepQuery(queryTarget, 'symbolRotate'); var normal = self.deepMerge( queryTarget, 'itemStyle.normal' ); var emphasis = self.deepMerge( queryTarget, 'itemStyle.emphasis' ); var nBorderWidth = typeof normal.borderWidth != 'undefined' ? normal.borderWidth : (normal.lineStyle && normal.lineStyle.width); if (typeof nBorderWidth == 'undefined') { nBorderWidth = 0; } var eBorderWidth = typeof emphasis.borderWidth != 'undefined' ? emphasis.borderWidth : (emphasis.lineStyle && emphasis.lineStyle.width); if (typeof eBorderWidth == 'undefined') { eBorderWidth = nBorderWidth + 2; } var itemShape = { shape : 'icon', style : { iconType : symbol.replace('empty', '').toLowerCase(), x : x - symbolSize, y : y - symbolSize, width : symbolSize * 2, height : symbolSize * 2, brushType : 'both', color : symbol.match('empty') ? emptyColor : (self.getItemStyleColor(normal.color, seriesIndex, dataIndex, data) || color), strokeColor : normal.borderColor || self.getItemStyleColor(normal.color, seriesIndex, dataIndex, data) || color, lineWidth: nBorderWidth }, highlightStyle : { color : symbol.match('empty') ? emptyColor : self.getItemStyleColor(emphasis.color, seriesIndex, dataIndex, data), strokeColor : emphasis.borderColor || normal.borderColor || self.getItemStyleColor(normal.color, seriesIndex, dataIndex, data) || color, lineWidth: eBorderWidth }, clickable : true }; if (symbol.match('image')) { itemShape.style.image = symbol.replace(new RegExp('^image:\\/\\/'), ''); itemShape.shape = 'image'; } if (typeof symbolRotate != 'undefined') { itemShape.rotation = [ symbolRotate * Math.PI / 180, x, y ]; } if (symbol.match('star')) { itemShape.style.iconType = 'star'; itemShape.style.n = (symbol.replace('empty', '').replace('star','') - 0) || 5; } if (symbol == 'none') { itemShape.invisible = true; itemShape.hoverable = false; } /* if (self.deepQuery([data, serie, option], 'calculable')) { self.setCalculable(itemShape); itemShape.draggable = true; } */ itemShape = self.addLabel( itemShape, serie, data, name, orient ); if (symbol.match('empty')) { if (typeof itemShape.style.textColor == 'undefined') { itemShape.style.textColor = itemShape.style.strokeColor; } if (typeof itemShape.highlightStyle.textColor == 'undefined') { itemShape.highlightStyle.textColor = itemShape.highlightStyle.strokeColor; } } ecData.pack( itemShape, serie, seriesIndex, data, dataIndex, name ); itemShape._mark = 'point'; // 复用animationMark itemShape._x = x; itemShape._y = y; itemShape._dataIndex = dataIndex; itemShape._seriesIndex = seriesIndex; return itemShape; } function getLineMarkShape( mlOption, // 系列 seriesIndex, // 系列索引 data, // 数据 dataIndex, // 数据索引 xStart, yStart, // 坐标 xEnd, yEnd, // 坐标 color // 默认color,来自legend或dataRange全局分配 ) { var value0 = typeof data[0] != 'undefined' ? (typeof data[0].value != 'undefined' ? data[0].value : data[0]) : '-'; var value1 = typeof data[1] != 'undefined' ? (typeof data[1].value != 'undefined' ? data[1].value : data[1]) : '-'; var symbol = [ self.query(data[0], 'symbol') || mlOption.symbol[0], self.query(data[1], 'symbol') || mlOption.symbol[1] ]; var symbolSize = [ self.query(data[0], 'symbolSize') || mlOption.symbolSize[0], self.query(data[1], 'symbolSize') || mlOption.symbolSize[1] ]; symbolSize[0] = typeof symbolSize[0] == 'function' ? symbolSize[0](value0) : symbolSize[0]; symbolSize[1] = typeof symbolSize[1] == 'function' ? symbolSize[1](value1) : symbolSize[1]; var symbolRotate = [ self.query(data[0], 'symbolRotate') || mlOption.symbolRotate[0], self.query(data[1], 'symbolRotate') || mlOption.symbolRotate[1] ]; //console.log(symbol, symbolSize, symbolRotate); var queryTarget = [data[0], mlOption]; var normal = self.deepMerge( queryTarget, 'itemStyle.normal' ); normal.color = self.getItemStyleColor(normal.color, seriesIndex, dataIndex, data); var emphasis = self.deepMerge( queryTarget, 'itemStyle.emphasis' ); emphasis.color = self.getItemStyleColor(emphasis.color, seriesIndex, dataIndex, data); var nlineStyle = normal.lineStyle; var elineStyle = emphasis.lineStyle; var nBorderWidth = nlineStyle.width; if (typeof nBorderWidth == 'undefined') { nBorderWidth = normal.borderWidth; } var eBorderWidth = elineStyle.width; if (typeof eBorderWidth == 'undefined') { if (typeof emphasis.borderWidth != 'undefined') { eBorderWidth = emphasis.borderWidth; } else { eBorderWidth = nBorderWidth + 2; } } var itemShape = { shape : 'markLine', style : { smooth : mlOption.smooth ? 'spline' : false, symbol : symbol, symbolSize : symbolSize, symbolRotate : symbolRotate, //data : [data[0].name,data[1].name], xStart : xStart, yStart : yStart, // 坐标 xEnd : xEnd, yEnd : yEnd, // 坐标 brushType : 'both', lineType : nlineStyle.type, shadowColor : nlineStyle.shadowColor, shadowBlur: nlineStyle.shadowBlur, shadowOffsetX: nlineStyle.shadowOffsetX, shadowOffsetY: nlineStyle.shadowOffsetY, color : normal.color || color, strokeColor : nlineStyle.color || normal.borderColor || normal.color || color, lineWidth: nBorderWidth, symbolBorderColor: normal.borderColor || normal.color || color, symbolBorder: normal.borderWidth }, highlightStyle : { shadowColor : elineStyle.shadowColor, shadowBlur: elineStyle.shadowBlur, shadowOffsetX: elineStyle.shadowOffsetX, shadowOffsetY: elineStyle.shadowOffsetY, color : emphasis.color|| normal.color || color, strokeColor : elineStyle.color || nlineStyle.color || emphasis.borderColor || normal.borderColor || emphasis.color || normal.color || color, lineWidth: eBorderWidth, symbolBorderColor: emphasis.borderColor || normal.borderColor || emphasis.color || normal.color || color, symbolBorder: typeof emphasis.borderWidth == 'undefined' ? (normal.borderWidth + 2) : (emphasis.borderWidth) }, clickable : true }; itemShape = self.addLabel( itemShape, mlOption, data[0], data[0].name + ' : ' + data[1].name ); itemShape._mark = 'line'; itemShape._x = xEnd; itemShape._y = yEnd; return itemShape; } function getItemStyleColor(itemColor, seriesIndex, dataIndex, data) { return typeof itemColor == 'function' ? itemColor(seriesIndex, dataIndex, data) : itemColor; } // 亚像素优化 function subPixelOptimize(position, lineWidth) { if (lineWidth % 2 == 1) { //position += position == Math.ceil(position) ? 0.5 : 0; position = Math.floor(position) + 0.5; } else { position = Math.round(position); } return position; } /** * 动画设定 */ function animation() { if (_aniMap[self.type]) { self.animationMark(ecConfig.animationDuration); } else { self.animationEffect(); } } function animationMark(duration , easing) { var x; var y; for (var i = 0, l = self.shapeList.length; i < l; i++) { if (!self.shapeList[i]._mark) { continue; } x = self.shapeList[i]._x || 0; y = self.shapeList[i]._y || 0; if (self.shapeList[i]._mark == 'point') { zr.modShape( self.shapeList[i].id, { scale : [0, 0, x, y] }, true ); zr.animate(self.shapeList[i].id, '') .when( duration, {scale : [1, 1, x, y]} ) .start(easing || 'QuinticOut'); } else if (self.shapeList[i]._mark == 'line') { if (!self.shapeList[i].style.smooth) { zr.modShape( self.shapeList[i].id, { style : { pointList : [ [ self.shapeList[i].style.xStart, self.shapeList[i].style.yStart ], [ self.shapeList[i].style.xStart, self.shapeList[i].style.yStart ] ] } }, true ); zr.animate(self.shapeList[i].id, 'style') .when( duration, { pointList : [ [ self.shapeList[i].style.xStart, self.shapeList[i].style.yStart ], [ x, y ] ] } ) .start(easing || 'QuinticOut'); } else { // 曲线动画 zr.modShape( self.shapeList[i].id, { style : { pointListLength : 1 } }, true ); zr.animate(self.shapeList[i].id, 'style') .when( duration, { pointListLength : self.shapeList[i].style.pointList.length } ) .start(easing || 'QuinticOut'); } } } self.animationEffect(); } function animationEffect() { clearAnimationShape(); var zlevel = EFFECT_ZLEVEL; if (_canvasSupported) { zr.modLayer( zlevel, { motionBlur : true, lastFrameAlpha : 0.95 } ); } var color; var shadowColor; var size; var effect; for (var i = 0, l = self.shapeList.length; i < l; i++) { shape = self.shapeList[i]; if (!shape._mark || !shape.effect || !shape.effect.show) { continue; } //console.log(shape) effect = shape.effect; color = effect.color || shape.style.strokeColor || shape.style.color; shadowColor = effect.shadowColor || color; var effectShape; var Offset; switch (shape._mark) { case 'point': size = effect.scaleSize; shadowBlur = typeof effect.shadowBlur != 'undefined' ? effect.shadowBlur : size; effectShape = { shape : shape.shape, id : zr.newShapeId(), zlevel : zlevel, style : { brushType : 'stroke', iconType : (shape.style.iconType != 'pin' && shape.style.iconType != 'droplet') ? shape.style.iconType : 'circle', x : shadowBlur + 1, // 线宽 y : shadowBlur + 1, n : shape.style.n, width : shape.style.width * size, height : shape.style.height * size, lineWidth : 1, strokeColor : color, shadowColor : shadowColor, shadowBlur : shadowBlur }, draggable : false, hoverable : false }; if (_canvasSupported) { // 提高性能,换成image effectShape.style.image = zr.shapeToImage( effectShape, effectShape.style.width + shadowBlur * 2 + 2, effectShape.style.height + shadowBlur * 2 + 2 ).style.image; effectShape.shape = 'image'; } Offset = (effectShape.style.width - shape.style.width) / 2; break; case 'line': size = shape.style.lineWidth * effect.scaleSize; shadowBlur = typeof effect.shadowBlur != 'undefined' ? effect.shadowBlur : size; effectShape = { shape : 'circle', id : zr.newShapeId(), zlevel : zlevel, style : { x : shadowBlur, y : shadowBlur, r : size, color : color, shadowColor : shadowColor, shadowBlur : shadowBlur }, draggable : false, hoverable : false }; if (_canvasSupported) { // 提高性能,换成image effectShape.style.image = zr.shapeToImage( effectShape, (size + shadowBlur) * 2, (size + shadowBlur) * 2 ).style.image; effectShape.shape = 'image'; Offset = shadowBlur; } else { Offset = 0; } break; } var duration; // 改变坐标 effectShape.position = shape.position; if (shape._mark === 'point') { effectShape.style.x = shape.style.x - Offset; effectShape.style.y = shape.style.y - Offset; duration = (effect.period + Math.random() * 10) * 100; } else if (shape._mark === 'line') { effectShape.style.x = shape.style.xStart - Offset; effectShape.style.y = shape.style.yStart - Offset; var distance = (shape.style.xStart - shape._x) * (shape.style.xStart - shape._x) + (shape.style.yStart - shape._y) * (shape.style.yStart - shape._y); duration = Math.round(Math.sqrt(Math.round( distance * effect.period * effect.period ))); } self.effectList.push(effectShape); zr.addShape(effectShape); if (shape._mark === 'point') { zr.modShape( shape.id, { invisible : true}, true ); var centerX = effectShape.style.x + (effectShape.style.width) /2; var centerY = effectShape.style.y + (effectShape.style.height) / 2; zr.modShape( effectShape.id, { scale : [0.1, 0.1, centerX, centerY] }, true ); zr.animate(effectShape.id, '', true) .when( duration, { scale : [1, 1, centerX, centerY] } ) .start(); } else if (shape._mark === 'line') { if (!shape.style.smooth) { // 直线 zr.animate(effectShape.id, 'style', true) .when( duration, { x : shape._x - Offset, y : shape._y - Offset } ) .start(); } else { // 曲线 var pointList = shape.style.pointList; var len = pointList.length; duration = Math.round(duration / len); var deferred = zr.animate(effectShape.id, 'style', true); for (var j = 0; j < len; j++) { deferred.when( duration * (j + 1), { x : pointList[j][0] - Offset, y : pointList[j][1] - Offset } ); } deferred.start(); } } } } function resize() { self.refresh && self.refresh(); } function clearAnimationShape() { if (self.zr && self.effectList.length > 0) { self.zr.modLayer( EFFECT_ZLEVEL, { motionBlur : false} ); self.zr.delShape(self.effectList); } self.effectList = []; } /** * 清除图形数据,实例仍可用 */ function clear() { clearAnimationShape(); if (self.zr) { self.zr.delShape(self.shapeList); } self.shapeList = []; } /** * 释放后实例不可用 */ function dispose() { self.clear(); self.shapeList = null; self.effectList = null; self = null; } /** * 基类方法 */ self.getZlevelBase = getZlevelBase; self.reformOption = reformOption; self.reformCssArray = reformCssArray; self.query = ecQuery.query; self.deepQuery = ecQuery.deepQuery; self.deepMerge = ecQuery.deepMerge; self.getFont = getFont; self.addLabel = addLabel; self.buildMark = buildMark; self.getMarkCoord = getMarkCoord; self.getSymbolShape = getSymbolShape; self.parsePercent = number.parsePercent; self.parseCenter = number.parseCenter; self.parseRadius = number.parseRadius; self.numAddCommas = number.addCommas; self.getItemStyleColor = getItemStyleColor; self.subPixelOptimize = subPixelOptimize; self.animation = animation; self.animationMark = animationMark; self.animationEffect = animationEffect; self.resize = resize; self.clearAnimationShape = clearAnimationShape; self.clear = clear; self.dispose = dispose; } return Base; }); /** * 高精度数学运算 */ define('echarts/util/accMath',[],function() { //除法函数,用来得到精确的除法结果 //说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。 //调用:accDiv(arg1,arg2) //返回值:arg1除以arg2的精确结果 function accDiv(arg1, arg2) { return accMul(arg1,1 / arg2); } //乘法函数,用来得到精确的乘法结果 //说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。 //调用:accMul(arg1,arg2) //返回值:arg1乘以arg2的精确结果 function accMul(arg1, arg2) { var m = 0; var s1 = arg1.toString(); var s2 = arg2.toString(); try { m += s1.split('.')[1].length; } catch(e) {} try { m += s2.split('.')[1].length; } catch(e){} return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m); } //加法函数,用来得到精确的加法结果 //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 //调用:accAdd(arg1,arg2) //返回值:arg1加上arg2的精确结果 function accAdd(arg1,arg2) { var r1; var r2; var m; try { r1 = arg1.toString().split('.')[1].length; } catch(e) { r1 = 0; } try { r2=arg2.toString().split('.')[1].length; } catch(e) { r2=0; } m = Math.pow(10, Math.max(r1, r2)); return (Math.round(arg1 * m) + Math.round(arg2 * m)) / m; } //减法函数,用来得到精确的减法结果 //说明:javascript的减法结果会有误差,在两个浮点数减法的时候会比较明显。这个函数返回较为精确的减法结果。 //调用:accSub(arg1,arg2) //返回值:arg1减法arg2的精确结果 function accSub(arg1,arg2) { return accAdd(arg1, -arg2); } return { accDiv : accDiv, accMul : accMul, accAdd : accAdd, accSub : accSub }; }); /** * echarts组件基类 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/chart/calculableBase',['require','../util/ecData','../util/accMath','zrender/tool/util'],function(require) { function Base(zr, option){ var ecData = require('../util/ecData'); var accMath = require('../util/accMath'); var zrUtil = require('zrender/tool/util'); var self = this; self.selectedMap = {}; self.shapeHandler = { onclick : function() { self.isClick = true; }, ondragover : function (param) { // 返回触发可计算特性的图形提示 var calculableShape = zrUtil.clone(param.target); calculableShape.highlightStyle = { text : '', r : calculableShape.style.r + 5, brushType : 'stroke', strokeColor : option.calculableColor,//self.zr.getCalculableColor(), lineWidth : (calculableShape.style.lineWidth || 1) + 12 }; self.zr.addHoverShape(calculableShape); }, ondrop : function (param) { // 排除一些非数据的拖拽进入 if (typeof ecData.get(param.dragged, 'data') != 'undefined') { self.isDrop = true; } }, ondragend : function () { self.isDragend = true; } }; function setCalculable(shape) { shape.dragEnableTime = option.DRAG_ENABLE_TIME; shape.ondragover = self.shapeHandler.ondragover; shape.ondragend = self.shapeHandler.ondragend; shape.ondrop = self.shapeHandler.ondrop; return shape; } /** * 数据项被拖拽进来 */ function ondrop(param, status) { if (!self.isDrop || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } var target = param.target; // 拖拽安放目标 var dragged = param.dragged; // 当前被拖拽的图形对象 var seriesIndex = ecData.get(target, 'seriesIndex'); var dataIndex = ecData.get(target, 'dataIndex'); // 落到数据item上,数据被拖拽到某个数据项上,数据修改 var data = option.series[seriesIndex].data[dataIndex] || '-'; if (data.value) { if (data.value != '-') { option.series[seriesIndex].data[dataIndex].value = accMath.accAdd( option.series[seriesIndex].data[dataIndex].value, ecData.get(dragged, 'value') ); } else { option.series[seriesIndex].data[dataIndex].value = ecData.get(dragged, 'value'); } } else { if (data != '-') { option.series[seriesIndex].data[dataIndex] = accMath.accAdd( option.series[seriesIndex].data[dataIndex], ecData.get(dragged, 'value') ); } else { option.series[seriesIndex].data[dataIndex] = ecData.get(dragged, 'value'); } } // 别status = {}赋值啊!! status.dragIn = status.dragIn || true; // 处理完拖拽事件后复位 self.isDrop = false; return; } /** * 数据项被拖拽出去 */ function ondragend(param, status) { if (!self.isDragend || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } var target = param.target; // 被拖拽图形元素 var seriesIndex = ecData.get(target, 'seriesIndex'); var dataIndex = ecData.get(target, 'dataIndex'); // 被拖拽的图形是折线图bar,删除被拖拽走的数据 option.series[seriesIndex].data[dataIndex] = '-'; // 别status = {}赋值啊!! status.dragOut = true; status.needRefresh = true; // 处理完拖拽事件后复位 self.isDragend = false; return; } /** * 图例选择 */ function onlegendSelected(param, status) { var legendSelected = param.selected; for (var itemName in self.selectedMap) { if (self.selectedMap[itemName] != legendSelected[itemName]) { // 有一项不一致都需要重绘 status.needRefresh = true; } self.selectedMap[itemName] = legendSelected[itemName]; } return; } /** * 基类方法 */ self.setCalculable = setCalculable; self.ondrop = ondrop; self.ondragend = ondragend; self.onlegendSelected = onlegendSelected; } return Base; }); /** * echarts组件:孤岛数据 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/chart/island',['require','../component/base','./calculableBase','../util/ecData','zrender/tool/event','zrender/tool/color','../util/accMath','../chart'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 图表选项 */ function Island(ecConfig, messageCenter, zr) { // 基类装饰 var ComponentBase = require('../component/base'); ComponentBase.call(this, ecConfig, zr); // 可计算特性装饰 var CalculableBase = require('./calculableBase'); CalculableBase.call(this, zr, ecConfig); var ecData = require('../util/ecData'); var zrEvent = require('zrender/tool/event'); var self = this; self.type = ecConfig.CHART_TYPE_ISLAND; var option; var _zlevelBase = self.getZlevelBase(); var _nameConnector; var _valueConnector; var _zrHeight = zr.getHeight(); var _zrWidth = zr.getWidth(); /** * 孤岛合并 * * @param {string} tarShapeIndex 目标索引 * @param {Object} srcShape 源目标,合入目标后删除 */ function _combine(tarShape, srcShape) { var zrColor = require('zrender/tool/color'); var accMath = require('../util/accMath'); var value = accMath.accAdd( ecData.get(tarShape, 'value'), ecData.get(srcShape, 'value') ); var name = ecData.get(tarShape, 'name') + _nameConnector + ecData.get(srcShape, 'name'); tarShape.style.text = name + _valueConnector + value; ecData.set(tarShape, 'value', value); ecData.set(tarShape, 'name', name); tarShape.style.r = option.island.r; tarShape.style.color = zrColor.mix( tarShape.style.color, srcShape.style.color ); } /** * 刷新 */ function refresh(newOption) { if (newOption) { newOption.island = self.reformOption(newOption.island); option = newOption; _nameConnector = option.nameConnector; _valueConnector = option.valueConnector; } } function render(newOption) { refresh(newOption); for (var i = 0, l = self.shapeList.length; i < l; i++) { zr.addShape(self.shapeList[i]); } } function getOption() { return option; } function resize() { var newWidth = zr.getWidth(); var newHieght = zr.getHeight(); var xScale = newWidth / (_zrWidth || newWidth); var yScale = newHieght / (_zrHeight || newHieght); if (xScale == 1 && yScale == 1) { return; } _zrWidth = newWidth; _zrHeight = newHieght; for (var i = 0, l = self.shapeList.length; i < l; i++) { zr.modShape( self.shapeList[i].id, { style: { x: Math.round(self.shapeList[i].style.x * xScale), y: Math.round(self.shapeList[i].style.y * yScale) } }, true ); } } function add(shape) { var name = ecData.get(shape, 'name'); var value = ecData.get(shape, 'value'); var seriesName = typeof ecData.get(shape, 'series') != 'undefined' ? ecData.get(shape, 'series').name : ''; var font = self.getFont(option.island.textStyle); var islandShape = { shape : 'circle', id : zr.newShapeId(self.type), zlevel : _zlevelBase, style : { x : shape.style.x, y : shape.style.y, r : option.island.r, color : shape.style.color || shape.style.strokeColor, text : name + _valueConnector + value, textFont : font }, draggable : true, hoverable : true, onmousewheel : self.shapeHandler.onmousewheel, _type : 'island' }; if (islandShape.style.color == '#fff') { islandShape.style.color = shape.style.strokeColor; } self.setCalculable(islandShape); islandShape.dragEnableTime = 0; ecData.pack( islandShape, {name:seriesName}, -1, value, -1, name ); self.shapeList.push(islandShape); zr.addShape(islandShape); } function del(shape) { zr.delShape(shape.id); var newShapeList = []; for (var i = 0, l = self.shapeList.length; i < l; i++) { if (self.shapeList[i].id != shape.id) { newShapeList.push(self.shapeList[i]); } } self.shapeList = newShapeList; } /** * 数据项被拖拽进来, 重载基类方法 */ function ondrop(param, status) { if (!self.isDrop || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } // 拖拽产生孤岛数据合并 var target = param.target; // 拖拽安放目标 var dragged = param.dragged; // 当前被拖拽的图形对象 _combine(target, dragged); zr.modShape(target.id, target); status.dragIn = true; // 处理完拖拽事件后复位 self.isDrop = false; return; } /** * 数据项被拖拽出去, 重载基类方法 */ function ondragend(param, status) { var target = param.target; // 拖拽安放目标 if (!self.isDragend) { // 拖拽的不是孤岛数据,如果没有图表接受孤岛数据,需要新增孤岛数据 if (!status.dragIn) { target.style.x = zrEvent.getX(param.event); target.style.y = zrEvent.getY(param.event); add(target); status.needRefresh = true; } } else { // 拖拽的是孤岛数据,如果有图表接受了孤岛数据,需要删除孤岛数据 if (status.dragIn) { del(target); status.needRefresh = true; } } // 处理完拖拽事件后复位 self.isDragend = false; return; } /** * 滚轮改变孤岛数据值 */ self.shapeHandler.onmousewheel = function(param) { var shape = param.target; var event = param.event; var delta = zrEvent.getDelta(event); delta = delta > 0 ? (-1) : 1; shape.style.r -= delta; shape.style.r = shape.style.r < 5 ? 5 : shape.style.r; var value = ecData.get(shape, 'value'); var dvalue = value * option.island.calculateStep; if (dvalue > 1) { value = Math.round(value - dvalue * delta); } else { value = (value - dvalue * delta).toFixed(2) - 0; } var name = ecData.get(shape, 'name'); shape.style.text = name + ':' + value; ecData.set(shape, 'value', value); ecData.set(shape, 'name', name); zr.modShape(shape.id, shape); zr.refresh(); zrEvent.stop(event); }; self.refresh = refresh; self.render = render; self.resize = resize; self.getOption = getOption; self.add = add; self.del = del; self.ondrop = ondrop; self.ondragend = ondragend; } // 图表注册 require('../chart').define('island', Island); return Island; }); /** * echart组件库 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component',[],function(/*require*/) { //component var self = {}; var _componentLibrary = {}; //echart组件库 /** * 定义图形实现 * @param {Object} name * @param {Object} clazz 图形实现 */ self.define = function(name, clazz) { _componentLibrary[name] = clazz; return self; }; /** * 获取图形实现 * @param {Object} name */ self.get = function(name) { return _componentLibrary[name]; }; return self; }); /** * echarts组件:图表标题 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/title',['require','./base','zrender/tool/area','zrender/tool/util','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 图表参数 */ function Title(ecConfig, messageCenter, zr, option) { var Base = require('./base'); Base.call(this, ecConfig, zr); var zrArea = require('zrender/tool/area'); var zrUtil = require('zrender/tool/util'); var self = this; self.type = ecConfig.COMPONENT_TYPE_TITLE; var titleOption; // 标题选项,共享数据源 var _zlevelBase = self.getZlevelBase(); var _itemGroupLocation = {}; // 标题元素组的位置参数,通过计算所得x, y, width, height function _buildShape() { _itemGroupLocation = _getItemGroupLocation(); _buildBackground(); _buildItem(); for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } /** * 构建所有标题元素 */ function _buildItem() { var text = titleOption.text; var link = titleOption.link; var subtext = titleOption.subtext; var sublink = titleOption.sublink; var font = self.getFont(titleOption.textStyle); var subfont = self.getFont(titleOption.subtextStyle); var x = _itemGroupLocation.x; var y = _itemGroupLocation.y; var width = _itemGroupLocation.width; var height = _itemGroupLocation.height; var textShape = { shape : 'text', zlevel : _zlevelBase, style : { y : y, color : titleOption.textStyle.color, text: text, textFont: font, textBaseline: 'top' }, highlightStyle: { brushType: 'fill' }, hoverable: false }; if (link) { textShape.hoverable = true; textShape.clickable = true; textShape.onclick = function(){ window.open(link); }; } var subtextShape = { shape : 'text', zlevel : _zlevelBase, style : { y : y + height, color : titleOption.subtextStyle.color, text: subtext, textFont: subfont, textBaseline: 'bottom' }, highlightStyle: { brushType: 'fill' }, hoverable: false }; if (sublink) { subtextShape.hoverable = true; subtextShape.clickable = true; subtextShape.onclick = function(){ window.open(sublink); }; } switch (titleOption.x) { case 'center' : textShape.style.x = subtextShape.style.x = x + width / 2; textShape.style.textAlign = subtextShape.style.textAlign = 'center'; break; case 'left' : textShape.style.x = subtextShape.style.x = x; textShape.style.textAlign = subtextShape.style.textAlign = 'left'; break; case 'right' : textShape.style.x = subtextShape.style.x = x + width; textShape.style.textAlign = subtextShape.style.textAlign = 'right'; break; default : x = titleOption.x - 0; x = isNaN(x) ? 0 : x; textShape.style.x = subtextShape.style.x = x; break; } if (titleOption.textAlign) { textShape.style.textAlign = subtextShape.style.textAlign = titleOption.textAlign; } self.shapeList.push(textShape); subtext !== '' && self.shapeList.push(subtextShape); } function _buildBackground() { var pTop = titleOption.padding[0]; var pRight = titleOption.padding[1]; var pBottom = titleOption.padding[2]; var pLeft = titleOption.padding[3]; self.shapeList.push({ shape : 'rectangle', zlevel : _zlevelBase, hoverable :false, style : { x : _itemGroupLocation.x - pLeft, y : _itemGroupLocation.y - pTop, width : _itemGroupLocation.width + pLeft + pRight, height : _itemGroupLocation.height + pTop + pBottom, brushType : titleOption.borderWidth === 0 ? 'fill' : 'both', color : titleOption.backgroundColor, strokeColor : titleOption.borderColor, lineWidth : titleOption.borderWidth } }); } /** * 根据选项计算标题实体的位置坐标 */ function _getItemGroupLocation() { var text = titleOption.text; var subtext = titleOption.subtext; var font = self.getFont(titleOption.textStyle); var subfont = self.getFont(titleOption.subtextStyle); var totalWidth = Math.max( zrArea.getTextWidth(text, font), zrArea.getTextWidth(subtext, subfont) ); var totalHeight = zrArea.getTextHeight(text, font) + (subtext === '' ? 0 : (titleOption.itemGap + zrArea.getTextHeight(subtext, subfont)) ); var x; var zrWidth = zr.getWidth(); switch (titleOption.x) { case 'center' : x = Math.floor((zrWidth - totalWidth) / 2); break; case 'left' : x = titleOption.padding[3] + titleOption.borderWidth; break; case 'right' : x = zrWidth - totalWidth - titleOption.padding[1] - titleOption.borderWidth; break; default : x = titleOption.x - 0; x = isNaN(x) ? 0 : x; break; } var y; var zrHeight = zr.getHeight(); switch (titleOption.y) { case 'top' : y = titleOption.padding[0] + titleOption.borderWidth; break; case 'bottom' : y = zrHeight - totalHeight - titleOption.padding[2] - titleOption.borderWidth; break; case 'center' : y = Math.floor((zrHeight - totalHeight) / 2); break; default : y = titleOption.y - 0; y = isNaN(y) ? 0 : y; break; } return { x : x, y : y, width : totalWidth, height : totalHeight }; } function init(newOption) { refresh(newOption); } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; option.title = self.reformOption(option.title); // 补全padding属性 option.title.padding = self.reformCssArray( option.title.padding ); titleOption = option.title; titleOption.textStyle = zrUtil.merge( titleOption.textStyle, ecConfig.textStyle, { 'overwrite': false, 'recursive': false } ); titleOption.subtextStyle = zrUtil.merge( titleOption.subtextStyle, ecConfig.textStyle, { 'overwrite': false, 'recursive': false } ); self.clear(); _buildShape(); } } function resize() { self.clear(); _buildShape(); } self.init = init; self.refresh = refresh; self.resize = resize; init(option); } require('../component').define('title', Title); return Title; }); /** * echarts组件: 类目轴 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/categoryAxis',['require','./base','zrender/tool/util','zrender/tool/area','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 类目轴参数 * @param {Grid} grid 网格对象 */ function CategoryAxis(ecConfig, messageCenter, zr, option, component) { var Base = require('./base'); Base.call(this, ecConfig, zr); var zrUtil = require('zrender/tool/util'); var zrArea = require('zrender/tool/area'); var self = this; self.type = ecConfig.COMPONENT_TYPE_AXIS_CATEGORY; var grid = component.grid; var _zlevelBase = self.getZlevelBase(); var _interval; // 标签显示的挑选间隔 var _labelData; function _reformLabel() { var data = zrUtil.clone(option.data); var axisFormatter = option.axisLabel.formatter; var formatter; for (var i = 0, l = data.length; i < l; i++) { formatter = data[i].formatter || axisFormatter; if (formatter) { if (typeof formatter == 'function') { if (typeof data[i].value != 'undefined') { data[i].value = formatter(data[i].value); } else { data[i] = formatter(data[i]); } } else if (typeof formatter == 'string') { if (typeof data[i].value != 'undefined') { data[i].value = formatter.replace( '{value}',data[i].value ); } else { data[i] = formatter.replace('{value}',data[i]); } } } } return data; } /** * 计算标签显示挑选间隔 */ function _getInterval() { var interval = option.axisLabel.interval; if (interval == 'auto') { // 麻烦的自适应计算 var fontSize = option.axisLabel.textStyle.fontSize; var font = self.getFont(option.axisLabel.textStyle); var data = option.data; var dataLength = option.data.length; if (option.position == 'bottom' || option.position == 'top') { // 横向 if (dataLength > 3) { var gap = getGap(); var isEnough = false; var labelSpace; var labelSize; interval = 0; while (!isEnough && interval < dataLength) { interval++; isEnough = true; labelSpace = gap * interval - 10; // 标签左右至少间隔为5px for (var i = 0; i < dataLength; i += interval) { if (option.axisLabel.rotate !== 0) { // 有旋转 labelSize = fontSize; } else if (data[i].textStyle) { labelSize = zrArea.getTextWidth( _labelData[i].value || _labelData[i], self.getFont( zrUtil.merge( data[i].textStyle, option.axisLabel.textStyle, { 'overwrite': false, 'recursive': true } ) ) ); } else { labelSize = zrArea.getTextWidth( _labelData[i].value || _labelData[i], font ); } if (labelSpace < labelSize) { // 放不下,中断循环让interval++ isEnough = false; break; } } } } else { // 少于3个则全部显示 interval = 1; } } else { // 纵向 if (dataLength > 3) { var gap = getGap(); interval = 1; // 标签上下至少间隔为3px while ((gap * interval - 6) < fontSize && interval < dataLength ) { interval++; } } else { // 少于3个则全部显示 interval = 1; } } } else { // 用户自定义间隔 interval += 1; } return interval; } function _buildShape() { _labelData = _reformLabel(); _interval = _getInterval(); option.splitArea.show && _buildSplitArea(); option.splitLine.show && _buildSplitLine(); option.axisLine.show && _buildAxisLine(); option.axisTick.show && _buildAxisTick(); option.axisLabel.show && _buildAxisLabel(); for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } // 轴线 function _buildAxisLine() { var lineWidth = option.axisLine.lineStyle.width; var halfLineWidth = lineWidth / 2; var axShape = { shape : 'line', zlevel : _zlevelBase + 1, hoverable : false }; switch (option.position) { case 'left' : axShape.style = { xStart : grid.getX() - halfLineWidth, yStart : grid.getYend() + halfLineWidth, xEnd : grid.getX() - halfLineWidth, yEnd : grid.getY() - halfLineWidth }; break; case 'right' : axShape.style = { xStart : grid.getXend() + halfLineWidth, yStart : grid.getYend() + halfLineWidth, xEnd : grid.getXend() + halfLineWidth, yEnd : grid.getY() - halfLineWidth }; break; case 'bottom' : axShape.style = { xStart : grid.getX() - halfLineWidth, yStart : grid.getYend() + halfLineWidth, xEnd : grid.getXend() + halfLineWidth, yEnd : grid.getYend() + halfLineWidth }; break; case 'top' : axShape.style = { xStart : grid.getX() - halfLineWidth, yStart : grid.getY() - halfLineWidth, xEnd : grid.getXend() + halfLineWidth, yEnd : grid.getY() - halfLineWidth }; break; } if (option.name !== '') { axShape.style.text = option.name; axShape.style.textPosition = option.nameLocation; axShape.style.textFont = self.getFont(option.nameTextStyle); if (option.nameTextStyle.align) { axShape.style.textAlign = option.nameTextStyle.align; } if (option.nameTextStyle.baseline) { axShape.style.textBaseline = option.nameTextStyle.baseline; } if (option.nameTextStyle.color) { axShape.style.textColor = option.nameTextStyle.color; } } axShape.style.strokeColor = option.axisLine.lineStyle.color; axShape.style.lineWidth = lineWidth; // 亚像素优化 if (option.position == 'left' || option.position == 'right') { // 纵向布局,优化x axShape.style.xStart = axShape.style.xEnd = self.subPixelOptimize(axShape.style.xEnd, lineWidth); } else { // 横向布局,优化y axShape.style.yStart = axShape.style.yEnd = self.subPixelOptimize(axShape.style.yEnd, lineWidth); } axShape.style.lineType = option.axisLine.lineStyle.type; self.shapeList.push(axShape); } // 小标记 function _buildAxisTick() { var axShape; //var data = option.data; var dataLength = option.data.length; var tickOption = option.axisTick; var length = tickOption.length; var color = tickOption.lineStyle.color; var lineWidth = tickOption.lineStyle.width; var interval = tickOption.interval == 'auto' ? _interval : (tickOption.interval - 0 + 1); var onGap = tickOption.onGap; var optGap = onGap ? (getGap() / 2) : typeof onGap == 'undefined' ? (option.boundaryGap ? (getGap() / 2) : 0) : 0; var startIndex = optGap > 0 ? -interval : 0; if (option.position == 'bottom' || option.position == 'top') { // 横向 var yPosition = option.position == 'bottom' ? (tickOption.inside ? (grid.getYend() - length) : grid.getYend()) : (tickOption.inside ? grid.getY() : (grid.getY() - length)); var x; for (var i = startIndex; i < dataLength; i += interval) { // 亚像素优化 x = self.subPixelOptimize( getCoordByIndex(i) + (i >= 0 ? optGap : 0), lineWidth ); axShape = { shape : 'line', zlevel : _zlevelBase, hoverable : false, style : { xStart : x, yStart : yPosition, xEnd : x, yEnd : yPosition + length, strokeColor : color, lineWidth : lineWidth } }; self.shapeList.push(axShape); } } else { // 纵向 var xPosition = option.position == 'left' ? (tickOption.inside ? grid.getX() : (grid.getX() - length)) : (tickOption.inside ? (grid.getXend() - length) : grid.getXend()); var y; for (var i = startIndex; i < dataLength; i += interval) { // 亚像素优化 y = self.subPixelOptimize( getCoordByIndex(i) - (i >= 0 ? optGap : 0), lineWidth ); axShape = { shape : 'line', zlevel : _zlevelBase, hoverable : false, style : { xStart : xPosition, yStart : y, xEnd : xPosition + length, yEnd : y, strokeColor : color, lineWidth : lineWidth } }; self.shapeList.push(axShape); } } } // 坐标轴文本 function _buildAxisLabel() { var axShape; var data = option.data; var dataLength = option.data.length; var rotate = option.axisLabel.rotate; var margin = option.axisLabel.margin; var textStyle = option.axisLabel.textStyle; var dataTextStyle; if (option.position == 'bottom' || option.position == 'top') { // 横向 var yPosition; var baseLine; if (option.position == 'bottom') { yPosition = grid.getYend() + margin; baseLine = 'top'; } else { yPosition = grid.getY() - margin; baseLine = 'bottom'; } for (var i = 0; i < dataLength; i += _interval) { if ((_labelData[i].value || _labelData[i]) === '') { // 空文本优化 continue; } dataTextStyle = zrUtil.merge( data[i].textStyle || {}, textStyle, {'overwrite': false} ); axShape = { shape : 'text', zlevel : _zlevelBase, hoverable : false, style : { x : getCoordByIndex(i), y : yPosition, color : dataTextStyle.color, text : _labelData[i].value || _labelData[i], textFont : self.getFont(dataTextStyle), textAlign : 'center', textBaseline : baseLine } }; if (rotate) { axShape.style.textAlign = rotate > 0 ? (option.position == 'bottom' ? 'right' : 'left') : (option.position == 'bottom' ? 'left' : 'right'); axShape.rotation = [ rotate * Math.PI / 180, axShape.style.x, axShape.style.y ]; } self.shapeList.push(axShape); } } else { // 纵向 var xPosition; var align; if (option.position == 'left') { xPosition = grid.getX() - margin; align = 'right'; } else { xPosition = grid.getXend() + margin; align = 'left'; } for (var i = 0; i < dataLength; i += _interval) { if ((_labelData[i].value || _labelData[i]) === '') { // 空文本优化 continue; } dataTextStyle = zrUtil.merge( data[i].textStyle || {}, textStyle, {'overwrite': false} ); axShape = { shape : 'text', zlevel : _zlevelBase, hoverable : false, style : { x : xPosition, y : getCoordByIndex(i), color : dataTextStyle.color, text : _labelData[i].value || _labelData[i], textFont : self.getFont(dataTextStyle), textAlign : align, textBaseline : (i === 0 && option.name !== '') ? 'bottom' : (i == (dataLength - 1) && option.name !== '') ? 'top' : 'middle' } }; if (rotate) { axShape.rotation = [ rotate * Math.PI / 180, axShape.style.x, axShape.style.y ]; } self.shapeList.push(axShape); } } } function _buildSplitLine() { var axShape; //var data = option.data; var dataLength = option.data.length; var sLineOption = option.splitLine; var lineType = sLineOption.lineStyle.type; var lineWidth = sLineOption.lineStyle.width; var color = sLineOption.lineStyle.color; color = color instanceof Array ? color : [color]; var colorLength = color.length; var onGap = sLineOption.onGap; var optGap = onGap ? (getGap() / 2) : typeof onGap == 'undefined' ? (option.boundaryGap ? (getGap() / 2) : 0) : 0; dataLength -= (onGap || (typeof onGap == 'undefined' && option.boundaryGap)) ? 1 : 0; if (option.position == 'bottom' || option.position == 'top') { // 横向 var sy = grid.getY(); var ey = grid.getYend(); var x; for (var i = 0; i < dataLength; i += _interval) { // 亚像素优化 x = self.subPixelOptimize( getCoordByIndex(i) + optGap, lineWidth ); axShape = { shape : 'line', zlevel : _zlevelBase, hoverable : false, style : { xStart : x, yStart : sy, xEnd : x, yEnd : ey, strokeColor : color[(i / _interval) % colorLength], lineType : lineType, lineWidth : lineWidth } }; self.shapeList.push(axShape); } } else { // 纵向 var sx = grid.getX(); var ex = grid.getXend(); var y; for (var i = 0; i < dataLength; i += _interval) { // 亚像素优化 y = self.subPixelOptimize( getCoordByIndex(i) - optGap, lineWidth ); axShape = { shape : 'line', zlevel : _zlevelBase, hoverable : false, style : { xStart : sx, yStart : y, xEnd : ex, yEnd : y, strokeColor : color[(i / _interval) % colorLength], linetype : lineType, lineWidth : lineWidth } }; self.shapeList.push(axShape); } } } function _buildSplitArea() { var axShape; var sAreaOption = option.splitArea; var color = sAreaOption.areaStyle.color; if (!(color instanceof Array)) { // 非数组一律认为是单一颜色的字符串,单一颜色则用一个背景,颜色错误不负责啊!!! axShape = { shape : 'rectangle', zlevel : _zlevelBase, hoverable : false, style : { x : grid.getX(), y : grid.getY(), width : grid.getWidth(), height : grid.getHeight(), color : color // type : option.splitArea.areaStyle.type, } }; self.shapeList.push(axShape); } else { // 多颜色 var colorLength = color.length; var dataLength = option.data.length; var onGap = sAreaOption.onGap; var optGap = onGap ? (getGap() / 2) : typeof onGap == 'undefined' ? (option.boundaryGap ? (getGap() / 2) : 0) : 0; if (option.position == 'bottom' || option.position == 'top') { // 横向 var y = grid.getY(); var height = grid.getHeight(); var lastX = grid.getX(); var curX; for (var i = 0; i <= dataLength; i += _interval) { curX = i < dataLength ? (getCoordByIndex(i) + optGap) : grid.getXend(); axShape = { shape : 'rectangle', zlevel : _zlevelBase, hoverable : false, style : { x : lastX, y : y, width : curX - lastX, height : height, color : color[(i / _interval) % colorLength] // type : option.splitArea.areaStyle.type, } }; self.shapeList.push(axShape); lastX = curX; } } else { // 纵向 var x = grid.getX(); var width = grid.getWidth(); var lastYend = grid.getYend(); var curY; for (var i = 0; i <= dataLength; i += _interval) { curY = i < dataLength ? (getCoordByIndex(i) - optGap) : grid.getY(); axShape = { shape : 'rectangle', zlevel : _zlevelBase, hoverable : false, style : { x : x, y : curY, width : width, height : lastYend - curY, color : color[(i / _interval) % colorLength] // type : option.splitArea.areaStyle.type } }; self.shapeList.push(axShape); lastYend = curY; } } } } /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newZr * @param {Object} newOption * @param {Object} newGrid */ function init(newOption, newGrid) { if (newOption.data.length < 1) { return; } grid = newGrid; refresh(newOption); } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = self.reformOption(newOption); // 通用字体设置 option.axisLabel.textStyle = zrUtil.merge( option.axisLabel.textStyle || {}, ecConfig.textStyle, { 'overwrite' : false, 'recursive' : true } ); option.axisLabel.textStyle = zrUtil.merge( option.axisLabel.textStyle || {}, ecConfig.textStyle, { 'overwrite' : false, 'recursive' : true } ); } self.clear(); _buildShape(); } /** * 返回间隔 */ function getGap() { var dataLength = option.data.length; var total = (option.position == 'bottom' || option.position == 'top') ? grid.getWidth() : grid.getHeight(); if (option.boundaryGap) { // 留空 return total / dataLength; } else { // 顶头 return total / (dataLength > 1 ? (dataLength - 1) : 1); } } // 根据值换算位置 function getCoord(value) { var data = option.data; var dataLength = data.length; var gap = getGap(); var position = option.boundaryGap ? (gap / 2) : 0; for (var i = 0; i < dataLength; i++) { if (data[i] == value || (typeof data[i].value != 'undefined' && data[i].value == value) ) { if (option.position == 'bottom' || option.position == 'top' ) { // 横向 position = grid.getX() + position; } else { // 纵向 position = grid.getYend() - position; } return position; // Math.floor可能引起一些偏差,但性能会更好 /* 准确更重要 return (i === 0 || i == dataLength - 1) ? position : Math.floor(position); */ } position += gap; } } // 根据类目轴数据索引换算位置 function getCoordByIndex(dataIndex) { if (dataIndex < 0) { if (option.position == 'bottom' || option.position == 'top') { return grid.getX(); } else { return grid.getYend(); } } else if (dataIndex > option.data.length - 1) { if (option.position == 'bottom' || option.position == 'top') { return grid.getXend(); } else { return grid.getY(); } } else { var gap = getGap(); var position = option.boundaryGap ? (gap / 2) : 0; position += dataIndex * gap; if (option.position == 'bottom' || option.position == 'top' ) { // 横向 position = grid.getX() + position; } else { // 纵向 position = grid.getYend() - position; } return position; /* 准确更重要 return (dataIndex === 0 || dataIndex == option.data.length - 1) ? position : Math.floor(position); */ } } // 根据类目轴数据索引换算类目轴名称 function getNameByIndex(dataIndex) { var data = option.data[dataIndex]; if (typeof data != 'undefined' && typeof data.value != 'undefined') { return data.value; } else { return data; } } // 根据类目轴名称换算类目轴数据索引 function getIndexByName(name) { var data = option.data; var dataLength = data.length; for (var i = 0; i < dataLength; i++) { if (data[i] == name || (typeof data[i].value != 'undefined' && data[i].value == name) ) { return i; } } } /** * 根据类目轴数据索引返回是否为主轴线 * @param {number} dataIndex 类目轴数据索引 * @return {boolean} 是否为主轴 */ function isMainAxis(dataIndex) { return dataIndex % _interval === 0; } function getPosition() { return option.position; } self.init = init; self.refresh = refresh; self.getGap = getGap; self.getCoord = getCoord; self.getCoordByIndex = getCoordByIndex; self.getNameByIndex = getNameByIndex; self.getIndexByName = getIndexByName; self.isMainAxis = isMainAxis; self.getPosition = getPosition; init(option, grid); } require('../component').define('categoryAxis', CategoryAxis); return CategoryAxis; }); /** * echarts组件: 数值轴 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/valueAxis',['require','./base','zrender/tool/util','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 类目轴参数 * @param {Grid} grid 网格对象 * @param {Array} series 数据对象 */ function ValueAxis(ecConfig, messageCenter, zr, option, component, series) { var Base = require('./base'); Base.call(this, ecConfig, zr); var zrUtil = require('zrender/tool/util'); var self = this; self.type = ecConfig.COMPONENT_TYPE_AXIS_VALUE; var grid = component.grid; var _zlevelBase = self.getZlevelBase(); var _min; var _max; var _hasData; var _valueList; var _valueLabel; function _buildShape() { _hasData = false; _calculateValue(); if (!_hasData) { return; } option.splitArea.show && _buildSplitArea(); option.splitLine.show && _buildSplitLine(); option.axisLine.show && _buildAxisLine(); option.axisTick.show && _buildAxisTick(); option.axisLabel.show && _buildAxisLabel(); for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } // 轴线 function _buildAxisLine() { var lineWidth = option.axisLine.lineStyle.width; var halfLineWidth = lineWidth / 2; var axShape = { shape : 'line', zlevel : _zlevelBase + 1, hoverable : false }; switch (option.position) { case 'left' : axShape.style = { xStart : grid.getX() - halfLineWidth, yStart : grid.getYend() + halfLineWidth, xEnd : grid.getX() - halfLineWidth, yEnd : grid.getY() - halfLineWidth }; break; case 'right' : axShape.style = { xStart : grid.getXend() + halfLineWidth, yStart : grid.getYend() + halfLineWidth, xEnd : grid.getXend() + halfLineWidth, yEnd : grid.getY() - halfLineWidth }; break; case 'bottom' : axShape.style = { xStart : grid.getX() - halfLineWidth, yStart : grid.getYend() + halfLineWidth, xEnd : grid.getXend() + halfLineWidth, yEnd : grid.getYend() + halfLineWidth }; break; case 'top' : axShape.style = { xStart : grid.getX() - halfLineWidth, yStart : grid.getY() - halfLineWidth, xEnd : grid.getXend() + halfLineWidth, yEnd : grid.getY() - halfLineWidth }; break; } if (option.name !== '') { axShape.style.text = option.name; axShape.style.textPosition = option.nameLocation; axShape.style.textFont = self.getFont(option.nameTextStyle); if (option.nameTextStyle.align) { axShape.style.textAlign = option.nameTextStyle.align; } if (option.nameTextStyle.baseline) { axShape.style.textBaseline = option.nameTextStyle.baseline; } if (option.nameTextStyle.color) { axShape.style.textColor = option.nameTextStyle.color; } } axShape.style.strokeColor = option.axisLine.lineStyle.color; var lineWidth = option.axisLine.lineStyle.width; axShape.style.lineWidth = lineWidth; // 亚像素优化 if (option.position == 'left' || option.position == 'right') { // 纵向布局,优化x axShape.style.xStart = axShape.style.xEnd = self.subPixelOptimize(axShape.style.xEnd, lineWidth); } else { // 横向布局,优化y axShape.style.yStart = axShape.style.yEnd = self.subPixelOptimize(axShape.style.yEnd, lineWidth); } axShape.style.lineType = option.axisLine.lineStyle.type; self.shapeList.push(axShape); } // 小标记 function _buildAxisTick() { var axShape; var data = _valueList; var dataLength = _valueList.length; var tickOption = option.axisTick; var length = tickOption.length; var color = tickOption.lineStyle.color; var lineWidth = tickOption.lineStyle.width; if (option.position == 'bottom' || option.position == 'top') { // 横向 var yPosition = option.position == 'bottom' ? (tickOption.inside ? (grid.getYend() - length) : grid.getYend()) : (tickOption.inside ? grid.getY() : (grid.getY() - length)); var x; for (var i = 0; i < dataLength; i++) { // 亚像素优化 x = self.subPixelOptimize(getCoord(data[i]), lineWidth); axShape = { shape : 'line', zlevel : _zlevelBase, hoverable : false, style : { xStart : x, yStart : yPosition, xEnd : x, yEnd : yPosition + length, strokeColor : color, lineWidth : lineWidth } }; self.shapeList.push(axShape); } } else { // 纵向 var xPosition = option.position == 'left' ? (tickOption.inside ? grid.getX() : (grid.getX() - length)) : (tickOption.inside ? (grid.getXend() - length) : grid.getXend()); var y; for (var i = 0; i < dataLength; i++) { // 亚像素优化 y = self.subPixelOptimize(getCoord(data[i]), lineWidth); axShape = { shape : 'line', zlevel : _zlevelBase, hoverable : false, style : { xStart : xPosition, yStart : y, xEnd : xPosition + length, yEnd : y, strokeColor : color, lineWidth : lineWidth } }; self.shapeList.push(axShape); } } } // 坐标轴文本 function _buildAxisLabel() { var axShape; var data = _valueList; var dataLength = _valueList.length; var rotate = option.axisLabel.rotate; var margin = option.axisLabel.margin; var textStyle = option.axisLabel.textStyle; if (option.position == 'bottom' || option.position == 'top') { // 横向 var yPosition; var baseLine; if (option.position == 'bottom') { yPosition = grid.getYend() + margin; baseLine = 'top'; } else { yPosition = grid.getY() - margin; baseLine = 'bottom'; } for (var i = 0; i < dataLength; i++) { axShape = { shape : 'text', zlevel : _zlevelBase, hoverable : false, style : { x : getCoord(data[i]), y : yPosition, color : typeof textStyle.color == 'function' ? textStyle.color(data[i]) : textStyle.color, text : _valueLabel[i], textFont : self.getFont(textStyle), textAlign : 'center', textBaseline : baseLine } }; if (rotate) { axShape.style.textAlign = rotate > 0 ? (option.position == 'bottom' ? 'right' : 'left') : (option.position == 'bottom' ? 'left' : 'right'); axShape.rotation = [ rotate * Math.PI / 180, axShape.style.x, axShape.style.y ]; } self.shapeList.push(axShape); } } else { // 纵向 var xPosition; var align; if (option.position == 'left') { xPosition = grid.getX() - margin; align = 'right'; } else { xPosition = grid.getXend() + margin; align = 'left'; } for (var i = 0; i < dataLength; i++) { axShape = { shape : 'text', zlevel : _zlevelBase, hoverable : false, style : { x : xPosition, y : getCoord(data[i]), color : typeof textStyle.color == 'function' ? textStyle.color(data[i]) : textStyle.color, text : _valueLabel[i], textFont : self.getFont(textStyle), textAlign : align, textBaseline : (i === 0 && option.name !== '') ? 'bottom' : (i == (dataLength - 1) && option.name !== '') ? 'top' : 'middle' } }; if (rotate) { axShape.rotation = [ rotate * Math.PI / 180, axShape.style.x, axShape.style.y ]; } self.shapeList.push(axShape); } } } function _buildSplitLine() { var axShape; var data = _valueList; var dataLength = _valueList.length; var sLineOption = option.splitLine; var lineType = sLineOption.lineStyle.type; var lineWidth = sLineOption.lineStyle.width; var color = sLineOption.lineStyle.color; color = color instanceof Array ? color : [color]; var colorLength = color.length; if (option.position == 'bottom' || option.position == 'top') { // 横向 var sy = grid.getY(); var ey = grid.getYend(); var x; for (var i = 1; i < dataLength - 1; i++) { // 亚像素优化 x = self.subPixelOptimize(getCoord(data[i]), lineWidth); axShape = { shape : 'line', zlevel : _zlevelBase, hoverable : false, style : { xStart : x, yStart : sy, xEnd : x, yEnd : ey, strokeColor : color[i % colorLength], lineType : lineType, lineWidth : lineWidth } }; self.shapeList.push(axShape); } } else { // 纵向 var sx = grid.getX(); var ex = grid.getXend(); var y; for (var i = 1; i < dataLength - 1; i++) { // 亚像素优化 y = self.subPixelOptimize(getCoord(data[i]), lineWidth); axShape = { shape : 'line', zlevel : _zlevelBase, hoverable : false, style : { xStart : sx, yStart : y, xEnd : ex, yEnd : y, strokeColor : color[i % colorLength], lineType : lineType, lineWidth : lineWidth } }; self.shapeList.push(axShape); } } } function _buildSplitArea() { var axShape; var color = option.splitArea.areaStyle.color; if (!(color instanceof Array)) { // 非数组一律认为是单一颜色的字符串,单一颜色则用一个背景,颜色错误不负责啊!!! axShape = { shape : 'rectangle', zlevel : _zlevelBase, hoverable : false, style : { x : grid.getX(), y : grid.getY(), width : grid.getWidth(), height : grid.getHeight(), color : color // type : option.splitArea.areaStyle.type, } }; self.shapeList.push(axShape); } else { // 多颜色 var colorLength = color.length; var data = _valueList; var dataLength = _valueList.length; if (option.position == 'bottom' || option.position == 'top') { // 横向 var y = grid.getY(); var height = grid.getHeight(); var lastX = grid.getX(); var curX; for (var i = 0; i <= dataLength; i++) { curX = i < dataLength ? getCoord(data[i]) : grid.getXend(); axShape = { shape : 'rectangle', zlevel : _zlevelBase, hoverable : false, style : { x : lastX, y : y, width : curX - lastX, height : height, color : color[i % colorLength] // type : option.splitArea.areaStyle.type, } }; self.shapeList.push(axShape); lastX = curX; } } else { // 纵向 var x = grid.getX(); var width = grid.getWidth(); var lastYend = grid.getYend(); var curY; for (var i = 0; i <= dataLength; i++) { curY = i < dataLength ? getCoord(data[i]) : grid.getY(); axShape = { shape : 'rectangle', zlevel : _zlevelBase, hoverable : false, style : { x : x, y : curY, width : width, height : lastYend - curY, color : color[i % colorLength] // type : option.splitArea.areaStyle.type } }; self.shapeList.push(axShape); lastYend = curY; } } } } /** * 极值计算 */ function _calculateValue() { if (isNaN(option.min - 0) || isNaN(option.max - 0)) { // 有一个没指定都得算 // 数据整形 var oriData; // 原始数据 var data = {}; // 整形后数据抽取 var value; var xIdx; var yIdx; var legend = component.legend; for (var i = 0, l = series.length; i < l; i++) { if (series[i].type != ecConfig.CHART_TYPE_LINE && series[i].type != ecConfig.CHART_TYPE_BAR && series[i].type != ecConfig.CHART_TYPE_SCATTER && series[i].type != ecConfig.CHART_TYPE_K ) { // 非坐标轴支持的不算极值 continue; } // 请允许我写开,跟上面一个不是一样东西 if (legend && !legend.isSelected(series[i].name)){ continue; } // 不指定默认为第一轴线 xIdx = series[i].xAxisIndex || 0; yIdx = series[i].yAxisIndex || 0; if ((option.xAxisIndex != xIdx) && (option.yAxisIndex != yIdx) ) { // 不是自己的数据不计算极值 continue; } var key = series[i].name || 'kener'; if (!series[i].stack) { data[key] = data[key] || []; oriData = series[i].data; for (var j = 0, k = oriData.length; j < k; j++) { value = typeof oriData[j].value != 'undefined' ? oriData[j].value : oriData[j]; if (series[i].type == ecConfig.CHART_TYPE_SCATTER) { if (option.xAxisIndex != -1) { data[key].push(value[0]); } if (option.yAxisIndex != -1) { data[key].push(value[1]); } } else if (series[i].type == ecConfig.CHART_TYPE_K) { data[key].push(value[0]); data[key].push(value[1]); data[key].push(value[2]); data[key].push(value[3]); } else { data[key].push(value); } } } else { // 堆叠数据,需要区分正负向堆叠 var keyP = '__Magic_Key_Positive__' + series[i].stack; var keyN = '__Magic_Key_Negative__' + series[i].stack; data[keyP] = data[keyP] || []; data[keyN] = data[keyN] || []; data[key] = data[key] || []; // scale下还需要记录每一个量 oriData = series[i].data; for (var j = 0, k = oriData.length; j < k; j++) { value = typeof oriData[j].value != 'undefined' ? oriData[j].value : oriData[j]; if (value == '-') { continue; } value = value - 0; if (value >= 0) { if (typeof data[keyP][j] != 'undefined') { data[keyP][j] += value; } else { data[keyP][j] = value; } } else { if (typeof data[keyN][j] != 'undefined') { data[keyN][j] += value; } else { data[keyN][j] = value; } } if (option.scale) { data[key].push(value); } } } } // 找极值 for (var i in data){ oriData = data[i]; for (var j = 0, k = oriData.length; j < k; j++) { if (!isNaN(oriData[j])){ _hasData = true; _min = oriData[j]; _max = oriData[j]; break; } } if (_hasData) { break; } } for (var i in data){ oriData = data[i]; for (var j = 0, k = oriData.length; j < k; j++) { if (!isNaN(oriData[j])){ _min = Math.min(_min, oriData[j]); _max = Math.max(_max, oriData[j]); } } } //console.log(_min,_max,'vvvvv111111') _min = isNaN(option.min - 0) ? (_min - Math.abs(_min * option.boundaryGap[0])) : (option.min - 0); // 指定min忽略boundaryGay[0] _max = isNaN(option.max - 0) ? (_max + Math.abs(_max * option.boundaryGap[1])) : (option.max - 0); // 指定max忽略boundaryGay[1] if (_min == _max) { if (_max === 0) { // 修复全0数据 _max = option.power > 0 ? option.power : 1; } // 修复最大值==最小值时数据整形 else if (_max > 0) { _min = _max / option.splitNumber; } else { // _max < 0 _max = _max / option.splitNumber; } } _reformValue(option.scale); } else { _hasData = true; // 用户指定min max就不多管闲事了 _min = option.min - 0; // 指定min忽略boundaryGay[0] _max = option.max - 0; // 指定max忽略boundaryGay[1] customerDefine = true; _customerValue(); } } /** * 找到原始数据的极值后根据选项整形最终 _min / _max / _valueList * 如果你不知道这个“整形”的用义,请不要试图去理解和修改这个方法!找我也没用,我相信我已经记不起来! * 如果你有更简洁的数学推导欢迎重写,后果自负~ * 一旦你不得不遇到了需要修改或重写的厄运,希望下面的脚手架能帮助你 * ps:其实我是想说别搞砸了!升级后至少得保证这些case通过!! * * by linzhifeng@baidu.com 2013-1-8 * -------- _valueList = []; option = {splitNumber:5,power:100,precision:0}; _min = 1; _max = 123; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : 0 150 [0, 30, 60, 90, 120, 150]', (_min == 0 && _max == 150) ? 'success' : 'failed'); _min = 10; _max = 1923; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : 0 2000 [0, 400, 800, 1200, 1600, 2000]', (_min == 0 && _max == 2000) ? 'success' : 'failed'); _min = 10; _max = 78; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : 0 100 [0, 20, 40, 60, 80, 100]', (_min == 0 && _max == 100) ? 'success' : 'failed'); _min = -31; _max = -3; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : -35 0 [-35, -28, -21, -14, -7, 0]', (_min == -35 && _max == 0) ? 'success' : 'failed'); _min = -51; _max = 203; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : -60 240 [-60, 0, 60, 120, 180, 240]', (_min == -60 && _max == 240) ? 'success' : 'failed'); _min = -251; _max = 23; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : -280 70 [-280, -210, -140, -70, 0, 70]', (_min == -280 && _max == 70) ? 'success' : 'failed'); option.precision = 2; _min = 0.23; _max = 0.78; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : 0.00 1.00' + '["0.00", "0.20", "0.40", "0.60", "0.80", "1.00"]', (_min == 0.00 && _max == 1.00) ? 'success' : 'failed'); _min = -12.23; _max = -0.78; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : -15.00 0.00' + '["-15.00", "-12.00", "-9.00", "-6.00", "-3.00", "0.00"]', (_min == -15.00 && _max == 0.00) ? 'success' : 'failed'); _min = -0.23; _max = 0.78; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : -0.30 1.20' + '["-0.30", "0.00", "0.30", "0.60", "0.90", "1.20"]', (_min == -0.30 && _max == 1.20) ? 'success' : 'failed'); _min = -1.23; _max = 0.78; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : -1.50 1.00' + '["-1.50", "-1.00", "-0.50", "0.00", "0.50", "1.00"]', (_min == -1.50 && _max == 1.00) ? 'success' : 'failed'); option.precision = 1; _min = -2.3; _max = 0.5; console.log(_min, _max); _reformValue(); console.log('result is :', _min, _max, _valueList); console.log('should be : -2.4 0.6' + '["-2.4", "-1.8", "-1.2", "-0.6", "0.0", "0.6"]', (_min == -2.4 && _max == 0.6) ? 'success' : 'failed'); * -------- */ function _reformValue(scale) { var splitNumber = option.splitNumber; var precision = option.precision; var splitGap; var power; if (precision === 0) { // 整数 power = option.power > 1 ? option.power : 1; } else { // 小数 // 放大倍数后复用整数逻辑,最后再缩小回去 power = Math.pow(10, precision); _min *= power; _max *= power; power = option.power; } // console.log(_min,_max) var total; if (_min >= 0 && _max >= 0) { // 双正 if (!scale) { // power自动降级 while ((_max / power < splitNumber) && power != 1) { power = power / 10; } _min = 0; } else { // power自动降级 while (_min < power && power != 1) { power = power / 10; } if (precision === 0) { // 整数 // 满足power _min = Math.floor(_min / power) * power; _max = Math.ceil(_max / power) * power; } } power = power > 1 ? power / 10 : 1; total = _max - _min; splitGap = Math.ceil((total / splitNumber) / power) * power; _max = _min + splitGap * splitNumber; } else if (_min <= 0 && _max <= 0) { // 双负 power = -power; if (!scale) { // power自动降级 while ((_min / power < splitNumber) && power != -1) { power = power / 10; } _max = 0; } else { // power自动降级 while (_max > power && power != -1) { power = power / 10; } if (precision === 0) { // 整数 // 满足power _min = Math.ceil(_min / power) * power; _max = Math.floor(_max / power) * power; } } power = power < -1 ? power / 10 : -1; total = _min - _max; splitGap = -Math.ceil((total / splitNumber) / power) * power; _min = -splitGap * splitNumber + _max; } else { // 一正一负,确保0被选中 total = _max - _min; // power自动降级 while ((total / power < splitNumber) && power != 1) { power = power/10; } // 正数部分的分隔数 var partSplitNumber = Math.round(_max / total * splitNumber); // 修正数据范围极度偏正向,留给负数一个 partSplitNumber -= (partSplitNumber == splitNumber ? 1 : 0); // 修正数据范围极度偏负向,留给正数一个 partSplitNumber += partSplitNumber === 0 ? 1 : 0; splitGap = (Math.ceil(Math.max( _max / partSplitNumber, _min / (partSplitNumber - splitNumber) ) / power)) * power; _max = splitGap * partSplitNumber; _min = splitGap * (partSplitNumber - splitNumber); } //console.log(_min,_max,'vvvvvrrrrrr') _valueList = []; for (var i = 0; i <= splitNumber; i++) { _valueList.push(_min + splitGap * i); } if (precision !== 0) { // 小数 // 放大倍数后复用整数逻辑,最后再缩小回去 power = Math.pow(10, precision); _min = (_min / power).toFixed(precision) - 0; _max = (_max / power).toFixed(precision) - 0; for (var i = 0; i <= splitNumber; i++) { _valueList[i] = (_valueList[i] / power).toFixed(precision) - 0; } } _reformLabelData(); } function _customerValue() { var splitNumber = option.splitNumber; var precision = option.precision; var splitGap = (_max - _min) / splitNumber; _valueList = []; for (var i = 0; i <= splitNumber; i++) { _valueList.push((_min + splitGap * i).toFixed(precision) - 0); } _reformLabelData(); } function _reformLabelData() { _valueLabel = []; var formatter = option.axisLabel.formatter; if (formatter) { for (var i = 0, l = _valueList.length; i < l; i++) { if (typeof formatter == 'function') { _valueLabel.push(formatter(_valueList[i])); } else if (typeof formatter == 'string') { _valueLabel.push( formatter.replace('{value}',_valueList[i]) ); } } } else { // 每三位默认加,格式化 for (var i = 0, l = _valueList.length; i < l; i++) { _valueLabel.push(self.numAddCommas(_valueList[i])); } } } function getExtremum() { _calculateValue(); return { min: _min, max: _max }; } /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newZr * @param {Object} newOption * @param {Object} newGrid */ function init(newOption, newGrid, newSeries) { if (!newSeries || newSeries.length === 0) { return; } grid = newGrid; refresh(newOption, newSeries); } /** * 刷新 */ function refresh(newOption, newSeries) { if (newOption) { option = self.reformOption(newOption); // 通用字体设置 option.axisLabel.textStyle = zrUtil.merge( option.axisLabel.textStyle || {}, ecConfig.textStyle, { 'overwrite' : false, 'recursive' : true } ); option.axisLabel.textStyle = zrUtil.merge( option.axisLabel.textStyle || {}, ecConfig.textStyle, { 'overwrite' : false, 'recursive' : true } ); series = newSeries; } if (zr) { // 数值轴的另外一个功能只是用来计算极值 self.clear(); _buildShape(); } } // 根据值换算位置 function getCoord(value) { value = value < _min ? _min : value; value = value > _max ? _max : value; var valueRange = _max - _min; var total; var result; if (option.position == 'left' || option.position == 'right') { // 纵向 total = grid.getHeight(); result = grid.getYend() - (value - _min) / valueRange * total; } else { // 横向 total = grid.getWidth(); result = (value - _min) / valueRange * total + grid.getX(); } return result; // Math.floor可能引起一些偏差,但性能会更好 /* 准确更重要 return (value == _min || value == _max) ? result : Math.floor(result); */ } // 根据值换算绝对大小 function getCoordSize(value) { if (option.position == 'left' || option.position == 'right') { // 纵向 return Math.abs(value / (_max - _min) * grid.getHeight()); } else { // 横向 return Math.abs(value / (_max - _min) * grid.getWidth()); } } function getPosition() { return option.position; } self.init = init; self.refresh = refresh; self.getExtremum = getExtremum; self.getCoord = getCoord; self.getCoordSize = getCoordSize; self.getPosition = getPosition; init(option, grid, series); } require('../component').define('valueAxis', ValueAxis); return ValueAxis; }); /** * echarts组件类: 坐标轴 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * 直角坐标系中坐标轴数组,数组中每一项代表一条横轴(纵轴)坐标轴。 * 标准(1.0)中规定最多同时存在2条横轴和2条纵轴 * 单条横轴时可指定安放于grid的底部(默认)或顶部,2条同时存在时则默认第一条安放于底部,第二天安放于顶部 * 单条纵轴时可指定安放于grid的左侧(默认)或右侧,2条同时存在时则默认第一条安放于左侧,第二天安放于右侧。 * 坐标轴有两种类型,类目型和数值型(区别详见axis): * 横轴通常为类目型,但条形图时则横轴为数值型,散点图时则横纵均为数值型 * 纵轴通常为数值型,但条形图时则纵轴为类目型。 * */ define('echarts/component/axis',['require','./base','./categoryAxis','./valueAxis','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 图表选项 * @param {string=} option.xAxis.type 坐标轴类型,横轴默认为类目型'category' * @param {string=} option.yAxis.type 坐标轴类型,纵轴默认为类目型'value' * @param {Object} component 组件 * @param {string} axisType 横走or纵轴 */ function Axis(ecConfig, messageCenter, zr, option, component, axisType) { var Base = require('./base'); Base.call(this, ecConfig, zr); var self = this; self.type = ecConfig.COMPONENT_TYPE_AXIS; var _axisList = []; /** * 参数修正&默认值赋值,重载基类方法 * @param {Object} opt 参数 */ function reformOption(opt) { // 不写或传了个空数值默认为数值轴 if (!opt || (opt instanceof Array && opt.length === 0) ) { opt = [{ type : ecConfig.COMPONENT_TYPE_AXIS_VALUE }]; } else if (!(opt instanceof Array)){ opt = [opt]; } // 最多两条,其他参数忽略 if (opt.length > 2) { opt = [opt[0],opt[1]]; } if (axisType == 'xAxis') { // 横轴位置默认配置 if (!opt[0].position // 没配置或配置错 || (opt[0].position != 'bottom' && opt[0].position != 'top') ) { opt[0].position = 'bottom'; } if (opt.length > 1) { opt[1].position = opt[0].position == 'bottom' ? 'top' : 'bottom'; } for (var i = 0, l = opt.length; i < l; i++) { // 坐标轴类型,横轴默认为类目型'category' opt[i].type = opt[i].type || 'category'; // 标识轴类型&索引 opt[i].xAxisIndex = i; opt[i].yAxisIndex = -1; } } else { // 纵轴位置默认配置 if (!opt[0].position // 没配置或配置错 || (opt[0].position != 'left' && opt[0].position != 'right') ) { opt[0].position = 'left'; } if (opt.length > 1) { opt[1].position = opt[0].position == 'left' ? 'right' : 'left'; } for (var i = 0, l = opt.length; i < l; i++) { // 坐标轴类型,纵轴默认为数值型'value' opt[i].type = opt[i].type || 'value'; // 标识轴类型&索引 opt[i].xAxisIndex = -1; opt[i].yAxisIndex = i; } } return opt; } /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newZr * @param {Object} newOption * @param {Object} newCompoent */ function init(newOption, newCompoent, newAxisType) { component = newCompoent; axisType = newAxisType; self.clear(); var axisOption; if (axisType == 'xAxis') { option.xAxis = self.reformOption(newOption.xAxis); axisOption = option.xAxis; } else { option.yAxis = self.reformOption(newOption.yAxis); axisOption = option.yAxis; } var CategoryAxis = require('./categoryAxis'); var ValueAxis = require('./valueAxis'); for (var i = 0, l = axisOption.length; i < l; i++) { _axisList.push( axisOption[i].type == 'category' ? new CategoryAxis( ecConfig, messageCenter, zr, axisOption[i], component ) : new ValueAxis( ecConfig, messageCenter, zr, axisOption[i], component, option.series ) ); } } /** * 刷新 */ function refresh(newOption) { var axisOption; var series; if (newOption) { if (axisType == 'xAxis') { option.xAxis =self.reformOption(newOption.xAxis); axisOption = option.xAxis; } else { option.yAxis = reformOption(newOption.yAxis); axisOption = option.yAxis; } series = newOption.series; } for (var i = 0, l = _axisList.length; i < l; i++) { _axisList[i].refresh && _axisList[i].refresh( axisOption ? axisOption[i] : false, series ); } } /** * 根据值换算位置 * @param {number} idx 坐标轴索引0~1 */ function getAxis(idx) { return _axisList[idx]; } /** * 清除坐标轴子对象,实例仍可用,重载基类方法 */ function clear() { for (var i = 0, l = _axisList.length; i < l; i++) { _axisList[i].dispose && _axisList[i].dispose(); } _axisList = []; } // 重载基类方法 self.clear = clear; self.reformOption = reformOption; self.init = init; self.refresh = refresh; self.getAxis = getAxis; init(option, component, axisType); } require('../component').define('axis', Axis); return Axis; }); /** * echarts组件: 网格 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/grid',['require','./base','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 图表选项 * @param {number=} option.grid.x 直角坐标系内绘图网格起始横坐标,数值单位px * @param {number=} option.grid.y 直角坐标系内绘图网格起始纵坐标,数值单位px * @param {number=} option.grid.width 直角坐标系内绘图网格宽度,数值单位px * @param {number=} option.grid.height 直角坐标系内绘图网格高度,数值单位px */ function Grid(ecConfig, messageCenter, zr, option) { var Base = require('./base'); Base.call(this, ecConfig, zr); var self = this; self.type = ecConfig.COMPONENT_TYPE_GRID; var _zlevelBase = self.getZlevelBase(); var _x; var _y; var _width; var _height; var _zrWidth; var _zrHeight; /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newZr * @param {Object} newOption */ function init(newOption) { option = newOption; option.grid = self.reformOption(option.grid); var gridOption = option.grid; _zrWidth = zr.getWidth(); _zrHeight = zr.getHeight(); _x = self.parsePercent(gridOption.x, _zrWidth); _y = self.parsePercent(gridOption.y, _zrHeight); var x2 = self.parsePercent(gridOption.x2, _zrWidth); var y2 = self.parsePercent(gridOption.y2, _zrHeight); if (typeof gridOption.width == 'undefined') { _width = _zrWidth - _x - x2; } else { _width = self.parsePercent(gridOption.width, _zrWidth); } if (typeof gridOption.height == 'undefined') { _height = _zrHeight - _y - y2; } else { _height = self.parsePercent(gridOption.height, _zrHeight); } _x = self.subPixelOptimize(_x, gridOption.borderWidth); _y = self.subPixelOptimize(_y, gridOption.borderWidth); self.shapeList.push({ shape : 'rectangle', id : zr.newShapeId('grid'), zlevel : _zlevelBase, hoverable : false, style : { x : _x, y : _y, width : _width, height : _height, brushType : gridOption.borderWidth > 0 ? 'both' : 'fill', color : gridOption.backgroundColor, strokeColor: gridOption.borderColor, lineWidth : gridOption.borderWidth // type : option.splitArea.areaStyle.type, } }); zr.addShape(self.shapeList[0]); } function getX() { return _x; } function getY() { return _y; } function getWidth() { return _width; } function getHeight() { return _height; } function getXend() { return _x + _width; } function getYend() { return _y + _height; } function getArea() { return { x : _x, y : _y, width : _width, height : _height }; } function refresh(newOption) { if (_zrWidth != zr.getWidth() || _zrHeight != zr.getHeight() || newOption ) { self.clear(); init(newOption || option); } } self.init = init; self.getX = getX; self.getY = getY; self.getWidth = getWidth; self.getHeight = getHeight; self.getXend = getXend; self.getYend = getYend; self.getArea = getArea; self.refresh = refresh; init(option); } require('../component').define('grid', Grid); return Grid; }); /** * echarts组件:数据区域缩放 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/dataZoom',['require','./base','../component','zrender/tool/util','zrender/tool/util','zrender/tool/util','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 图表参数 * @param {Object} component 组件 */ function DataZoom(ecConfig, messageCenter, zr, option, component) { var Base = require('./base'); Base.call(this, ecConfig, zr); var self = this; self.type = ecConfig.COMPONENT_TYPE_DATAZOOM; var _zlevelBase = self.getZlevelBase(); var zoomOption; var _fillerSize = 28; // 控件大小,水平布局为高,纵向布局为宽 var _handleSize = 8; // 手柄大小 var _location; // 位置参数,通过计算所得x, y, width, height var _zoom; // 缩放参数 var _fillerShae; // 填充 var _startShape; // 起始手柄 var _endShape; // 结束手柄 var _startFrameShape; // 起始特效边框 var _endFrameShape; // 结束特效边框 var _syncTicket; var _isSilence = false; var _originalData; function _buildShape() { _buildBackground(); _buildFiller(); _buildHandle(); _buildFrame(); for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } _syncFrameShape(); } /** * 根据选项计算实体的位置坐标 */ function _getLocation() { var x; var y; var width; var height; var grid = component.grid; // 不指定则根据grid适配 if (zoomOption.orient == 'horizontal') { // 水平布局 width = zoomOption.width || grid.getWidth(); height = zoomOption.height || _fillerSize; x = typeof zoomOption.x != 'undefined' ? zoomOption.x : grid.getX(); y = typeof zoomOption.y != 'undefined' ? zoomOption.y : (zr.getHeight() - height - 2); } else { // 垂直布局 width = zoomOption.width || _fillerSize; height = zoomOption.height || grid.getHeight(); x = typeof zoomOption.x != 'undefined' ? zoomOption.x : 2; y = typeof zoomOption.y != 'undefined' ? zoomOption.y : grid.getY(); } return { x : x, y : y, width : width, height : height }; } /** * 计算缩放参数 * 修正单坐标轴只传对象为数组。 */ function _getZoom() { var series = option.series; var xAxis = option.xAxis; if (xAxis && !(xAxis instanceof Array)) { xAxis = [xAxis]; option.xAxis = xAxis; } var yAxis = option.yAxis; if (yAxis && !(yAxis instanceof Array)) { yAxis = [yAxis]; option.yAxis = yAxis; } var zoomSeriesIndex = []; var xAxisIndex; var yAxisIndex; var zOptIdx = zoomOption.xAxisIndex; if (xAxis && typeof zOptIdx == 'undefined') { xAxisIndex = []; for (var i = 0, l = xAxis.length; i < l; i++) { // 横纵默认为类目轴 if (xAxis[i].type == 'category' || typeof xAxis[i].type == 'undefined' ) { xAxisIndex.push(i); } } } else { if (zOptIdx instanceof Array) { xAxisIndex = zOptIdx; } else if (typeof zOptIdx != 'undefined') { xAxisIndex = [zOptIdx]; } else { xAxisIndex = []; } } zOptIdx = zoomOption.yAxisIndex; if (yAxis && typeof zOptIdx == 'undefined') { yAxisIndex = []; for (var i = 0, l = yAxis.length; i < l; i++) { if (yAxis[i].type == 'category') { yAxisIndex.push(i); } } } else { if (zOptIdx instanceof Array) { yAxisIndex = zOptIdx; } else if (typeof zOptIdx != 'undefined') { yAxisIndex = [zOptIdx]; } else { yAxisIndex = []; } } // 找到缩放控制的所有series for (var i = 0, l = series.length; i < l; i++) { if (series[i].type != ecConfig.CHART_TYPE_LINE && series[i].type != ecConfig.CHART_TYPE_BAR && series[i].type != ecConfig.CHART_TYPE_SCATTER && series[i].type != ecConfig.CHART_TYPE_K ) { continue; } for (var j = 0, k = xAxisIndex.length; j < k; j++) { if (xAxisIndex[j] == (series[i].xAxisIndex || 0)) { zoomSeriesIndex.push(i); break; } } for (var j = 0, k = yAxisIndex.length; j < k; j++) { if (yAxisIndex[j] == (series[i].yAxisIndex || 0)) { zoomSeriesIndex.push(i); break; } } // 不指定接管坐标轴,则散点图被纳入接管范围 if (series[i].type == ecConfig.CHART_TYPE_SCATTER && typeof zoomOption.xAxisIndex == 'undefined' && typeof zoomOption.yAxisIndex == 'undefined' ) { zoomSeriesIndex.push(i); } } var start = typeof zoomOption.start != 'undefined' && zoomOption.start >= 0 && zoomOption.start <= 100 ? zoomOption.start : 0; var end = typeof zoomOption.end != 'undefined' && zoomOption.end >= 0 && zoomOption.end <= 100 ? zoomOption.end : 100; if (start > end) { // 大小颠倒自动翻转 start = start + end; end = start - end; start = start - end; } var size = Math.round( (end - start) / 100 * (zoomOption.orient == 'horizontal' ? _location.width : _location.height) ); return { start : start, end : end, start2 : 0, end2 : 100, size : size, xAxisIndex : xAxisIndex, yAxisIndex : yAxisIndex, seriesIndex : zoomSeriesIndex }; } function _backupData() { _originalData = { xAxis : {}, yAxis : {}, series : {} }; var xAxis = option.xAxis; var xAxisIndex = _zoom.xAxisIndex; for (var i = 0, l = xAxisIndex.length; i < l; i++) { _originalData.xAxis[xAxisIndex[i]] = xAxis[xAxisIndex[i]].data; } var yAxis = option.yAxis; var yAxisIndex = _zoom.yAxisIndex; for (var i = 0, l = yAxisIndex.length; i < l; i++) { _originalData.yAxis[yAxisIndex[i]] = yAxis[yAxisIndex[i]].data; } var series = option.series; var seriesIndex = _zoom.seriesIndex; var serie; for (var i = 0, l = seriesIndex.length; i < l; i++) { serie = series[seriesIndex[i]]; _originalData.series[seriesIndex[i]] = serie.data; if (serie.type == ecConfig.CHART_TYPE_SCATTER) { _calculScatterMap(seriesIndex[i]); } } } function _calculScatterMap(seriesIndex) { _zoom.scatterMap = _zoom.scatterMap || {}; _zoom.scatterMap[seriesIndex] = _zoom.scatterMap[seriesIndex] || {}; var componentLibrary = require('../component'); var zrUtil = require('zrender/tool/util'); // x轴极值 var Axis = componentLibrary.get('axis'); var axisOption = zrUtil.clone(option.xAxis); if (axisOption instanceof Array) { axisOption[0].type = 'value'; axisOption[1] && (axisOption[1].type = 'value'); } else { axisOption.type = 'value'; } var vAxis = new Axis( ecConfig, null, // messageCenter false, // zr { xAxis: axisOption, series : option.series }, component, 'xAxis' ); var axisIndex = option.series[seriesIndex].xAxisIndex || 0; _zoom.scatterMap[seriesIndex].x = vAxis.getAxis(axisIndex).getExtremum(); vAxis.dispose(); // y轴极值 axisOption = zrUtil.clone(option.yAxis); if (axisOption instanceof Array) { axisOption[0].type = 'value'; axisOption[1] && (axisOption[1].type = 'value'); } else { axisOption.type = 'value'; } vAxis = new Axis( ecConfig, null, // messageCenter false, // zr { yAxis: axisOption, series : option.series }, component, 'yAxis' ); axisIndex = option.series[seriesIndex].yAxisIndex || 0; _zoom.scatterMap[seriesIndex].y = vAxis.getAxis(axisIndex).getExtremum(); vAxis.dispose(); // console.log(_zoom.scatterMap); } function _buildBackground() { // 背景 self.shapeList.push({ shape : 'rectangle', zlevel : _zlevelBase, hoverable :false, style : { x : _location.x, y : _location.y, width : _location.width, height : _location.height, color : zoomOption.backgroundColor } }); // 数据阴影 var maxLength = 0; var xAxis = _originalData.xAxis; var xAxisIndex = _zoom.xAxisIndex; for (var i = 0, l = xAxisIndex.length; i < l; i++) { maxLength = Math.max( maxLength, xAxis[xAxisIndex[i]].length ); } var yAxis = _originalData.yAxis; var yAxisIndex = _zoom.yAxisIndex; for (var i = 0, l = yAxisIndex.length; i < l; i++) { maxLength = Math.max( maxLength, yAxis[yAxisIndex[i]].length ); } var seriesIndex = _zoom.seriesIndex[0]; var data = _originalData.series[seriesIndex]; var maxValue = Number.MIN_VALUE; var minValue = Number.MAX_VALUE; var value; for (var i = 0, l = data.length; i < l; i++) { value = typeof data[i] != 'undefined' ? (typeof data[i].value != 'undefined' ? data[i].value : data[i]) : 0; if (option.series[seriesIndex].type == ecConfig.CHART_TYPE_K) { value = value[1]; // 收盘价 } if (isNaN(value)) { value = 0; } maxValue = Math.max(maxValue, value); minValue = Math.min(minValue, value); } var pointList = []; var x = _location.width / maxLength; var y = _location.height / maxLength; for (var i = 0, l = maxLength; i < l; i++) { value = typeof data[i] != 'undefined' ? (typeof data[i].value != 'undefined' ? data[i].value : data[i]) : 0; if (option.series[seriesIndex].type == ecConfig.CHART_TYPE_K) { value = value[1]; // 收盘价 } if (isNaN(value)) { value = 0; } if (zoomOption.orient == 'horizontal') { pointList.push([ _location.x + x * i, _location.y + _location.height - 5 - Math.round( (value - minValue) / (maxValue - minValue) * (_location.height - 10) ) ]); } else { pointList.push([ _location.x + 5 + Math.round( (value - minValue) / (maxValue - minValue) * (_location.width - 10) ), _location.y + y * i ]); } } if (zoomOption.orient == 'horizontal') { pointList.push([ _location.x + _location.width, _location.y + _location.height ]); pointList.push([ _location.x, _location.y + _location.height ]); } else { pointList.push([ _location.x, _location.y + _location.height ]); pointList.push([ _location.x, _location.y ]); } self.shapeList.push({ shape : 'polygon', zlevel : _zlevelBase, style : { pointList : pointList, color : zoomOption.dataBackgroundColor }, hoverable : false }); } /** * 构建填充物 */ function _buildFiller() { _fillerShae = { shape : 'rectangle', zlevel : _zlevelBase, draggable : true, ondrift : _ondrift, ondragend : _ondragend, _type : 'filler' }; if (zoomOption.orient == 'horizontal') { // 横向 _fillerShae.style = { x : _location.x + Math.round(_zoom.start / 100 * _location.width) + _handleSize, y : _location.y, width : _zoom.size - _handleSize * 2, height : _location.height, color : zoomOption.fillerColor, // strokeColor : '#fff', // zoomOption.handleColor, // lineWidth: 2, text : ':::', textPosition : 'inside' }; } else { // 纵向 _fillerShae.style ={ x : _location.x, y : _location.y + Math.round(_zoom.start / 100 * _location.height) + _handleSize, width : _location.width, height : _zoom.size - _handleSize * 2, color : zoomOption.fillerColor, // strokeColor : '#fff', // zoomOption.handleColor, // lineWidth: 2, text : '::', textPosition : 'inside' }; } _fillerShae.highlightStyle = { brushType: 'fill', color : 'rgba(0,0,0,0)' /* color : require('zrender/tool/color').alpha( _fillerShae.style.color, 0 ) */ }; self.shapeList.push(_fillerShae); } /** * 构建拖拽手柄 */ function _buildHandle() { var zrUtil = require('zrender/tool/util'); _startShape = { shape : 'icon', zlevel : _zlevelBase, draggable : true, style : { iconType: 'rectangle', x : _location.x, y : _location.y, width : _handleSize, height : _handleSize, color : zoomOption.handleColor, text : '=', textPosition : 'inside' }, highlightStyle : { brushType: 'fill' }, ondrift : _ondrift, ondragend : _ondragend }; if (zoomOption.orient == 'horizontal') { _startShape.style.height = _location.height; _endShape = zrUtil.clone(_startShape); _startShape.style.x = _fillerShae.style.x - _handleSize, _endShape.style.x = _fillerShae.style.x + _fillerShae.style.width; } else { _startShape.style.width = _location.width; _endShape = zrUtil.clone(_startShape); _startShape.style.y = _fillerShae.style.y - _handleSize; _endShape.style.y = _fillerShae.style.y + _fillerShae.style.height; } self.shapeList.push(_startShape); self.shapeList.push(_endShape); } /** * 构建特效边框 */ function _buildFrame() { var zrUtil = require('zrender/tool/util'); // 特效框线,亚像素优化 var x = self.subPixelOptimize(_location.x, 1); var y = self.subPixelOptimize(_location.y, 1); _startFrameShape = { shape : 'rectangle', zlevel : _zlevelBase, hoverable :false, style : { x : x, y : y, width : _location.width - (x > _location.x ? 1 : 0), height : _location.height - (y > _location.y ? 1 : 0), lineWidth: 1, brushType: 'stroke', strokeColor : zoomOption.handleColor } }; _endFrameShape = zrUtil.clone(_startFrameShape); self.shapeList.push(_startFrameShape); self.shapeList.push(_endFrameShape); return; } /** * 拖拽范围控制 */ function _ondrift(e, dx, dy) { if (zoomOption.zoomLock) { // zoomLock时把handle转成filler的拖拽 e = _fillerShae; } var detailSize = e._type == 'filler' ? _handleSize : 0; if (zoomOption.orient == 'horizontal') { if (e.style.x + dx - detailSize <= _location.x) { e.style.x = _location.x + detailSize; } else if (e.style.x + dx + e.style.width + detailSize >= _location.x + _location.width ) { e.style.x = _location.x + _location.width - e.style.width - detailSize; } else { e.style.x += dx; } } else { if (e.style.y + dy - detailSize <= _location.y) { e.style.y = _location.y + detailSize; } else if (e.style.y + dy + e.style.height + detailSize >= _location.y + _location.height ) { e.style.y = _location.y + _location.height - e.style.height - detailSize; } else { e.style.y += dy; } } if (e._type == 'filler') { _syncHandleShape(); } else { _syncFillerShape(); } if (zoomOption.realtime) { _syncData(); } else { clearTimeout(_syncTicket); _syncTicket = setTimeout(_syncData, 200); } return true; } function _syncHandleShape() { if (zoomOption.orient == 'horizontal') { _startShape.style.x = _fillerShae.style.x - _handleSize; _endShape.style.x = _fillerShae.style.x + _fillerShae.style.width; _zoom.start = Math.floor( (_startShape.style.x - _location.x) / _location.width * 100 ); _zoom.end = Math.ceil( (_endShape.style.x + _handleSize - _location.x) / _location.width * 100 ); } else { _startShape.style.y = _fillerShae.style.y - _handleSize; _endShape.style.y = _fillerShae.style.y + _fillerShae.style.height; _zoom.start = Math.floor( (_startShape.style.y - _location.y) / _location.height * 100 ); _zoom.end = Math.ceil( (_endShape.style.y + _handleSize - _location.y) / _location.height * 100 ); } zr.modShape(_startShape.id, _startShape); zr.modShape(_endShape.id, _endShape); // 同步边框 _syncFrameShape(); zr.refresh(); } function _syncFillerShape() { var a; var b; if (zoomOption.orient == 'horizontal') { a = _startShape.style.x; b = _endShape.style.x; _fillerShae.style.x = Math.min(a, b) + _handleSize; _fillerShae.style.width = Math.abs(a - b) - _handleSize; _zoom.start = Math.floor( (Math.min(a, b) - _location.x) / _location.width * 100 ); _zoom.end = Math.ceil( (Math.max(a, b) + _handleSize - _location.x) / _location.width * 100 ); } else { a = _startShape.style.y; b = _endShape.style.y; _fillerShae.style.y = Math.min(a, b) + _handleSize; _fillerShae.style.height = Math.abs(a - b) - _handleSize; _zoom.start = Math.floor( (Math.min(a, b) - _location.y) / _location.height * 100 ); _zoom.end = Math.ceil( (Math.max(a, b) + _handleSize - _location.y) / _location.height * 100 ); } zr.modShape(_fillerShae.id, _fillerShae); // 同步边框 _syncFrameShape(); zr.refresh(); } function _syncFrameShape() { if (zoomOption.orient == 'horizontal') { _startFrameShape.style.width = _fillerShae.style.x - _location.x; _endFrameShape.style.x = _fillerShae.style.x + _fillerShae.style.width; _endFrameShape.style.width = _location.x + _location.width - _endFrameShape.style.x; } else { _startFrameShape.style.height = _fillerShae.style.y - _location.y; _endFrameShape.style.y = _fillerShae.style.y + _fillerShae.style.height; _endFrameShape.style.height = _location.y + _location.height - _endFrameShape.style.y; } zr.modShape(_startFrameShape.id, _startFrameShape); zr.modShape(_endFrameShape.id, _endFrameShape); } function _syncShape() { if (!zoomOption.show) { // 没有伸缩控件 return; } if (zoomOption.orient == 'horizontal') { _startShape.style.x = _location.x + _zoom.start / 100 * _location.width; _endShape.style.x = _location.x + _zoom.end / 100 * _location.width - _handleSize; _fillerShae.style.x = _startShape.style.x + _handleSize; _fillerShae.style.width = _endShape.style.x - _startShape.style.x - _handleSize; } else { _startShape.style.y = _location.y + _zoom.start / 100 * _location.height; _endShape.style.y = _location.y + _zoom.end / 100 * _location.height - _handleSize; _fillerShae.style.y = _startShape.style.y + _handleSize; _fillerShae.style.height = _endShape.style.y - _startShape.style.y - _handleSize; } zr.modShape(_startShape.id, _startShape); zr.modShape(_endShape.id, _endShape); zr.modShape(_fillerShae.id, _fillerShae); // 同步边框 _syncFrameShape(); zr.refresh(); } function _syncData(dispatchNow) { var target; var start; var end; var length; var data; for (var key in _originalData) { target = _originalData[key]; for (var idx in target) { data = target[idx]; length = data.length; start = Math.floor(_zoom.start / 100 * length); end = Math.ceil(_zoom.end / 100 * length); if (option[key][idx].type != ecConfig.CHART_TYPE_SCATTER) { option[key][idx].data = data.slice(start, end); } else { // 散点图特殊处理 option[key][idx].data = _synScatterData(idx, data); } } } if (!_isSilence && (zoomOption.realtime || dispatchNow)) { messageCenter.dispatch( ecConfig.EVENT.DATA_ZOOM, null, {zoom: _zoom} ); } zoomOption.start = _zoom.start; zoomOption.end = _zoom.end; } function _synScatterData(seriesIndex, data) { var newData = []; var scale = _zoom.scatterMap[seriesIndex]; var total; var xStart; var xEnd; var yStart; var yEnd; if (zoomOption.orient == 'horizontal') { total = scale.x.max - scale.x.min; xStart = _zoom.start / 100 * total + scale.x.min; xEnd = _zoom.end / 100 * total + scale.x.min; total = scale.y.max - scale.y.min; yStart = _zoom.start2 / 100 * total + scale.y.min; yEnd = _zoom.end2 / 100 * total + scale.y.min; } else { total = scale.x.max - scale.x.min; xStart = _zoom.start2 / 100 * total + scale.x.min; xEnd = _zoom.end2 / 100 * total + scale.x.min; total = scale.y.max - scale.y.min; yStart = _zoom.start / 100 * total + scale.y.min; yEnd = _zoom.end / 100 * total + scale.y.min; } // console.log(xStart,xEnd,yStart,yEnd); var value; for (var i = 0, l = data.length; i < l; i++) { value = data[i].value || data[i]; if (value[0] >= xStart && value[0] <= xEnd && value[1] >= yStart && value[1] <= yEnd ) { newData.push(data[i]); } } return newData; } function _ondragend() { self.isDragend = true; } /** * 数据项被拖拽出去 */ function ondragend(param, status) { if (!self.isDragend || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } _syncData(); // 别status = {}赋值啊!! status.dragOut = true; status.dragIn = true; if (!_isSilence && !zoomOption.realtime) { messageCenter.dispatch( ecConfig.EVENT.DATA_ZOOM, null, {zoom: _zoom} ); } status.needRefresh = false; // 会有消息触发fresh,不用再刷一遍 // 处理完拖拽事件后复位 self.isDragend = false; return; } function ondataZoom(param, status) { status.needRefresh = true; return; } function absoluteZoom(param) { zoomOption.start = _zoom.start = param.start; zoomOption.end = _zoom.end = param.end; zoomOption.start2 = _zoom.start2 = param.start2; zoomOption.end2 = _zoom.end2 = param.end2; //console.log(rect,gridArea,_zoom,total) _syncShape(); _syncData(true); return; } function rectZoom(param) { if (!param) { // 重置拖拽 zoomOption.start = zoomOption.start2 = _zoom.start = _zoom.start2 = 0; zoomOption.end = zoomOption.end2 = _zoom.end = _zoom.end2 = 100; _syncShape(); _syncData(true); return _zoom; } var gridArea = component.grid.getArea(); var rect = { x : param.x, y : param.y, width : param.width, height : param.height }; // 修正方向框选 if (rect.width < 0) { rect.x += rect.width; rect.width = -rect.width; } if (rect.height < 0) { rect.y += rect.height; rect.height = -rect.height; } // console.log(rect,_zoom); // 剔除无效缩放 if (rect.x > gridArea.x + gridArea.width || rect.y > gridArea.y + gridArea.height ) { return false; // 无效缩放 } // 修正框选超出 if (rect.x < gridArea.x) { rect.x = gridArea.x; } if (rect.x + rect.width > gridArea.x + gridArea.width) { rect.width = gridArea.x + gridArea.width - rect.x; } if (rect.y + rect.height > gridArea.y + gridArea.height) { rect.height = gridArea.y + gridArea.height - rect.y; } var total; var sdx = (rect.x - gridArea.x) / gridArea.width; var edx = 1 - (rect.x + rect.width - gridArea.x) / gridArea.width; var sdy = 1 - (rect.y + rect.height - gridArea.y) / gridArea.height; var edy = (rect.y - gridArea.y) / gridArea.height; //console.log('this',sdy,edy,_zoom.start,_zoom.end) if (zoomOption.orient == 'horizontal') { total = _zoom.end - _zoom.start; _zoom.start += total * sdx; _zoom.end -= total * edx; total = _zoom.end2 - _zoom.start2; _zoom.start2 += total * sdy; _zoom.end2 -= total * edy; } else { total = _zoom.end - _zoom.start; _zoom.start += total * sdy; _zoom.end -= total * edy; total = _zoom.end2 - _zoom.start2; _zoom.start2 += total * sdx; _zoom.end2 -= total * edx; } //console.log(_zoom.start,_zoom.end,_zoom.start2,_zoom.end2) zoomOption.start = _zoom.start; zoomOption.end = _zoom.end; zoomOption.start2 = _zoom.start2; zoomOption.end2 = _zoom.end2; //console.log(rect,gridArea,_zoom,total) _syncShape(); _syncData(true); return _zoom; } function syncBackupData(curOption, optionBackup) { var start; var target = _originalData['series']; var curSeries = curOption.series; var curData; for (var i = 0, l = curSeries.length; i < l; i++) { curData = curSeries[i].data; if (target[i]) { // dataZoom接管的 start = Math.floor(_zoom.start / 100 * target[i].length); } else { // 非dataZoom接管 start = 0; } for (var j = 0, k = curData.length; j < k; j++) { optionBackup.series[i].data[j + start] = curData[j]; if (target[i]) { // 同步内部备份 target[i][j + start] = curData[j]; } } } } function silence(s) { _isSilence = s; } function getRealDataIndex(sIdx, dIdx) { if (!_originalData) { return dIdx; } var sreies = _originalData.series; if (sreies[sIdx]) { return Math.floor(_zoom.start / 100 * sreies[sIdx].length) + dIdx; } return -1; } function init(newOption) { option = newOption; option.dataZoom = self.reformOption(option.dataZoom); zoomOption = option.dataZoom; self.clear(); // 自己show 或者 toolbox启用且dataZoom有效 if (option.dataZoom.show || ( self.query(option, 'toolbox.show') && self.query(option, 'toolbox.feature.dataZoom.show') ) ) { _location = _getLocation(); _zoom = _getZoom(); _backupData(); } if (option.dataZoom.show) { _buildShape(); _syncData(); } } /** * 避免dataZoom带来两次refresh,不设refresh接口,resize重复一下buildshape逻辑 */ function resize() { self.clear(); // 自己show 或者 toolbox启用且dataZoom有效 if (option.dataZoom.show || ( self.query(option, 'toolbox.show') && self.query(option, 'toolbox.feature.dataZoom.show') ) ) { _location = _getLocation(); _zoom = _getZoom(); } if (option.dataZoom.show) { _buildShape(); } } self.init = init; self.resize = resize; self.syncBackupData = syncBackupData; self.absoluteZoom = absoluteZoom; self.rectZoom = rectZoom; self.ondragend = ondragend; self.ondataZoom = ondataZoom; self.silence = silence; self.getRealDataIndex = getRealDataIndex; init(option); } require('../component').define('dataZoom', DataZoom); return DataZoom; }); /** * echarts组件:图例 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/legend',['require','./base','zrender/tool/util','zrender/tool/area','zrender/tool/color','zrender/shape','zrender/shape','zrender/shape','zrender/shape','zrender/shape','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 图表参数 * @param {Object=} selected 用于状态保持 */ function Legend(ecConfig, messageCenter, zr, option, selected) { var Base = require('./base'); Base.call(this, ecConfig, zr); var zrUtil = require('zrender/tool/util'); var zrArea = require('zrender/tool/area'); var zrColor = require('zrender/tool/color'); var self = this; self.type = ecConfig.COMPONENT_TYPE_LEGEND; var legendOption; // 图例选项,共享数据源 var _zlevelBase = self.getZlevelBase(); var _itemGroupLocation = {}; // 图例元素组的位置参数,通过计算所得x, y, width, height var _colorIndex = 0; var _colorMap = {}; var _selectedMap = {}; var icon = require('zrender/shape').get('icon'); for (var k in legendIcon) { icon.define('legendicon' + k, legendIcon[k]); //console.log('legendicon' + k, legendIcon[k]) } function _buildShape() { _itemGroupLocation = _getItemGroupLocation(); _buildBackground(); _buildItem(); for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } /** * 构建所有图例元素 */ function _buildItem() { var data = legendOption.data; var dataLength = data.length; var itemName; var itemType; var itemShape; var textShape; var textStyle = legendOption.textStyle; var dataTextStyle; var dataFont; var zrWidth = zr.getWidth(); var zrHeight = zr.getHeight(); var lastX = _itemGroupLocation.x; var lastY = _itemGroupLocation.y; var itemWidth = legendOption.itemWidth; var itemHeight = legendOption.itemHeight; var itemGap = legendOption.itemGap; var color; if (legendOption.orient == 'vertical' && legendOption.x == 'right' ) { lastX = _itemGroupLocation.x + _itemGroupLocation.width - itemWidth; } for (var i = 0; i < dataLength; i++) { dataTextStyle = zrUtil.merge( data[i].textStyle || {}, textStyle, {'overwrite': false} ); dataFont = self.getFont(dataTextStyle); itemName = data[i].name || data[i]; if (itemName === '') { if (legendOption.orient == 'horizontal') { lastX = _itemGroupLocation.x; lastY += itemHeight + itemGap; } else { legendOption.x == 'right' ? lastX -= _itemGroupLocation.maxWidth + itemGap : lastX += _itemGroupLocation.maxWidth + itemGap; lastY = _itemGroupLocation.y; } continue; } itemType = _getSomethingByName(itemName).type; color = getColor(itemName); if (legendOption.orient == 'horizontal') { if (zrWidth - lastX < 200 // 最后200px做分行预判 && (itemWidth + 5 + zrArea.getTextWidth( itemName, dataFont ) // 分行的最后一个不用算itemGap + (i == dataLength - 1 || data[i+1] === '' ? 0 : itemGap)) >= zrWidth - lastX ) { lastX = _itemGroupLocation.x; lastY += itemHeight + itemGap; } } else { if (zrHeight - lastY < 200 // 最后200px做分行预判 && (itemHeight // 分行的最后一个不用算itemGap + (i == dataLength - 1 || data[i+1] === '' ? 0 : itemGap)) >= zrHeight - lastY ) { legendOption.x == 'right' ? lastX -= _itemGroupLocation.maxWidth + itemGap : lastX += _itemGroupLocation.maxWidth + itemGap; lastY = _itemGroupLocation.y; } } // 图形 itemShape = _getItemShapeByType( lastX, lastY, itemWidth, itemHeight, (_selectedMap[itemName] ? color : '#ccc'), itemType, color ); itemShape._name = itemName; if (legendOption.selectedMode) { itemShape.onclick = _legendSelected; } self.shapeList.push(itemShape); // 文字 textShape = { shape : 'text', zlevel : _zlevelBase, style : { x : lastX + itemWidth + 5, y : lastY, color : _selectedMap[itemName] ? (dataTextStyle.color === 'auto' ? color : dataTextStyle.color) : '#ccc', text: itemName, textFont: dataFont, textBaseline: 'top' }, highlightStyle : { color : color, brushType: 'fill' }, hoverable : !!legendOption.selectedMode, clickable : !!legendOption.selectedMode }; if (legendOption.orient == 'vertical' && legendOption.x == 'right' ) { textShape.style.x -= (itemWidth + 10); textShape.style.textAlign = 'right'; } textShape._name = itemName; if (legendOption.selectedMode) { textShape.onclick = _legendSelected; } self.shapeList.push(textShape); if (legendOption.orient == 'horizontal') { lastX += itemWidth + 5 + zrArea.getTextWidth(itemName, dataFont) + itemGap; } else { lastY += itemHeight + itemGap; } } if (legendOption.orient == 'horizontal' && legendOption.x == 'center' && lastY != _itemGroupLocation.y ) { // 多行橫排居中优化 _mLineOptimize(); } } // 多行橫排居中优化 function _mLineOptimize() { var lineOffsetArray = []; // 每行宽度 var lastX = _itemGroupLocation.x; for (var i = 2, l = self.shapeList.length; i < l; i++) { if (self.shapeList[i].style.x == lastX) { lineOffsetArray.push( ( _itemGroupLocation.width - ( self.shapeList[i - 1].style.x + zrArea.getTextWidth( self.shapeList[i - 1].style.text, self.shapeList[i - 1].style.textFont ) - lastX ) ) / 2 ); } else if (i == l - 1) { lineOffsetArray.push( ( _itemGroupLocation.width - ( self.shapeList[i].style.x + zrArea.getTextWidth( self.shapeList[i].style.text, self.shapeList[i].style.textFont ) - lastX ) ) / 2 ); } } var curLineIndex = -1; for (var i = 1, l = self.shapeList.length; i < l; i++) { if (self.shapeList[i].style.x == lastX) { curLineIndex++; } if (lineOffsetArray[curLineIndex] === 0) { continue; } else { self.shapeList[i].style.x += lineOffsetArray[curLineIndex]; } } } function _buildBackground() { var pTop = legendOption.padding[0]; var pRight = legendOption.padding[1]; var pBottom = legendOption.padding[2]; var pLeft = legendOption.padding[3]; self.shapeList.push({ shape : 'rectangle', zlevel : _zlevelBase, hoverable :false, style : { x : _itemGroupLocation.x - pLeft, y : _itemGroupLocation.y - pTop, width : _itemGroupLocation.width + pLeft + pRight, height : _itemGroupLocation.height + pTop + pBottom, brushType : legendOption.borderWidth === 0 ? 'fill' : 'both', color : legendOption.backgroundColor, strokeColor : legendOption.borderColor, lineWidth : legendOption.borderWidth } }); } /** * 根据选项计算图例实体的位置坐标 */ function _getItemGroupLocation() { var data = legendOption.data; var dataLength = data.length; var itemGap = legendOption.itemGap; var itemWidth = legendOption.itemWidth + 5; // 5px是图形和文字的间隔,不可配 var itemHeight = legendOption.itemHeight; var textStyle = legendOption.textStyle; var font = self.getFont(textStyle); var totalWidth = 0; var totalHeight = 0; var padding = legendOption.padding; var zrWidth = zr.getWidth() - padding[1] - padding[3]; var zrHeight = zr.getHeight() - padding[0] - padding[2]; var temp = 0; // 宽高计算,用于多行判断 var maxWidth = 0; // 垂直布局有用 if (legendOption.orient == 'horizontal') { // 水平布局,计算总宽度 totalHeight = itemHeight; for (var i = 0; i < dataLength; i++) { if (data[i] === '') { temp -= itemGap; if (temp > zrWidth) { totalWidth = zrWidth; totalHeight += itemHeight + itemGap; } else { totalWidth = Math.max(totalWidth, temp); } totalHeight += itemHeight + itemGap; temp = 0; continue; } dataTextStyle = zrUtil.merge( data[i].textStyle || {}, textStyle, {'overwrite': false} ); temp += itemWidth + zrArea.getTextWidth( data[i].name || data[i], data[i].textStyle ? self.getFont(zrUtil.merge( data[i].textStyle || {}, textStyle, {'overwrite': false} )) : font ) + itemGap; } totalHeight = Math.max(totalHeight, itemHeight); temp -= itemGap; // 减去最后一个的itemGap if (temp > zrWidth) { totalWidth = zrWidth; totalHeight += itemHeight + itemGap; } else { totalWidth = Math.max(totalWidth, temp); } } else { // 垂直布局,计算总高度 for (var i = 0; i < dataLength; i++) { maxWidth = Math.max( maxWidth, zrArea.getTextWidth( data[i].name || data[i], data[i].textStyle ? self.getFont(zrUtil.merge( data[i].textStyle || {}, textStyle, {'overwrite': false} )) : font ) ); } maxWidth += itemWidth; totalWidth = maxWidth; for (var i = 0; i < dataLength; i++) { if (data[i] === '') { temp -= itemGap; if (temp > zrHeight) { totalHeight = zrHeight; totalWidth += maxWidth + itemGap; } else { totalHeight = Math.max(totalHeight, temp); } totalWidth += maxWidth + itemGap; temp = 0; continue; } temp += itemHeight + itemGap; } totalWidth = Math.max(totalWidth, maxWidth); temp -= itemGap; // 减去最后一个的itemGap if (temp > zrHeight) { totalHeight = zrHeight; totalWidth += maxWidth + itemGap; } else { totalHeight = Math.max(totalHeight, temp); } } zrWidth = zr.getWidth(); zrHeight = zr.getHeight(); var x; switch (legendOption.x) { case 'center' : x = Math.floor((zrWidth - totalWidth) / 2); break; case 'left' : x = legendOption.padding[3] + legendOption.borderWidth; break; case 'right' : x = zrWidth - totalWidth - legendOption.padding[1] - legendOption.padding[3] - legendOption.borderWidth * 2; break; default : x = legendOption.x - 0; x = isNaN(x) ? 0 : x; break; } var y; switch (legendOption.y) { case 'top' : y = legendOption.padding[0] + legendOption.borderWidth; break; case 'bottom' : y = zrHeight - totalHeight - legendOption.padding[0] - legendOption.padding[2] - legendOption.borderWidth * 2; break; case 'center' : y = Math.floor((zrHeight - totalHeight) / 2); break; default : y = legendOption.y - 0; y = isNaN(y) ? 0 : y; break; } return { x : x, y : y, width : totalWidth, height : totalHeight, maxWidth : maxWidth }; } /** * 根据名称返回series数据或data */ function _getSomethingByName(name) { var series = option.series; var data; for (var i = 0, l = series.length; i < l; i++) { if (series[i].name == name) { // 系列名称优先 return { type : series[i].type, series : series[i], seriesIndex : i, data : null, dataIndex : -1 }; } if ( series[i].type == ecConfig.CHART_TYPE_PIE || series[i].type == ecConfig.CHART_TYPE_RADAR || series[i].type == ecConfig.CHART_TYPE_CHORD || series[i].type == ecConfig.CHART_TYPE_FORCE ) { data = series[i].type != ecConfig.CHART_TYPE_FORCE ? series[i].data // 饼图、雷达图、和弦图得查找里面的数据名字 : series[i].categories; // 力导布局查找categories配置 for (var j = 0, k = data.length; j < k; j++) { if (data[j].name == name) { return { type : series[i].type, series : series[i], seriesIndex : i, data : data[j], dataIndex : j }; } } } } return { type : 'bar', series : null, seriesIndex : -1, data : null, dataIndex : -1 }; } function _getItemShapeByType(x, y, width, height, color, itemType, defaultColor) { var highlightColor = color === '#ccc' ? defaultColor : typeof color == 'string' && color != '#ccc' ? zrColor.lift(color, -0.3) : color; var itemShape = { shape : 'icon', zlevel : _zlevelBase, style : { iconType : 'legendicon' + (itemType != ecConfig.CHART_TYPE_CHORD // 和弦复用饼图 ? itemType : ecConfig.CHART_TYPE_PIE), x : x, y : y, width : width, height : height, color : color, strokeColor : color, lineWidth : 2 }, highlightStyle: { color : highlightColor, strokeColor : highlightColor, lineWidth : 1 }, hoverable : legendOption.selectedMode, clickable : legendOption.selectedMode }; // 特殊设置 switch (itemType) { case 'line' : itemShape.style.brushType = 'stroke'; itemShape.highlightStyle.lineWidth = 3; break; case 'radar' : case 'scatter' : itemShape.highlightStyle.lineWidth = 3; break; case 'k' : itemShape.style.brushType = 'both'; itemShape.highlightStyle.lineWidth = 3; itemShape.highlightStyle.color = itemShape.style.color = self.query( ecConfig, 'k.itemStyle.normal.color' ) || '#fff'; itemShape.style.strokeColor = color != '#ccc' ? self.query( ecConfig, 'k.itemStyle.normal.lineStyle.color' ) || '#ff3200' : color; } return itemShape; } function _legendSelected(param) { var itemName = param.target._name; if (legendOption.selectedMode === 'single') { for (var k in _selectedMap) { _selectedMap[k] = false; } } _selectedMap[itemName] = !_selectedMap[itemName]; messageCenter.dispatch( ecConfig.EVENT.LEGEND_SELECTED, param.event, { selected : _selectedMap, target : itemName } ); } function init(newOption) { if (!self.query(newOption, 'legend.data')) { return; } option = newOption; option.legend = self.reformOption(option.legend); // 补全padding属性 option.legend.padding = self.reformCssArray( option.legend.padding ); legendOption = option.legend; self.clear(); _selectedMap = {}; var data = legendOption.data || []; var itemName; var something; var color; var queryTarget; for (var i = 0, dataLength = data.length; i < dataLength; i++) { itemName = data[i].name || data[i]; if (itemName === '') { continue; } something = _getSomethingByName(itemName); if (!something.series) { _selectedMap[itemName] = false; } else { if (something.data && (something.type == ecConfig.CHART_TYPE_PIE || something.type == ecConfig.CHART_TYPE_FORCE) ) { queryTarget = [something.data, something.series]; } else { queryTarget = [something.series]; } color = self.getItemStyleColor( self.deepQuery( queryTarget, 'itemStyle.normal.color' ), something.seriesIndex, something.dataIndex, something.data ); if (color && something.type != ecConfig.CHART_TYPE_K) { setColor(itemName, color); } _selectedMap[itemName] = true; } } if (selected) { for (var k in selected) { _selectedMap[k] = selected[k]; } } _buildShape(); } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; option.legend = self.reformOption(option.legend); // 补全padding属性 option.legend.padding = self.reformCssArray( option.legend.padding ); if (option.legend.selected) { for (var k in option.legend.selected) { _selectedMap[k] = option.legend.selected[k]; } } } legendOption = option.legend; self.clear(); _buildShape(); } function setColor(legendName, color) { _colorMap[legendName] = color; } function getColor(legendName) { if (!_colorMap[legendName]) { _colorMap[legendName] = zr.getColor(_colorIndex++); } return _colorMap[legendName]; } function hasColor(legendName) { return _colorMap[legendName] ? _colorMap[legendName] : false; } function add(name, color){ legendOption.data.push(name); setColor(name,color); _selectedMap[name] = true; } function del(name){ var data = legendOption.data; var finalData = []; var found = false; for (var i = 0, dataLength = data.length; i < dataLength; i++) { if (found || data[i] != name) { finalData.push(data[i]); } else { found = true; continue; } } legendOption.data = finalData; } /** * 特殊图形元素回调设置 * @param {Object} name * @param {Object} itemShape */ function getItemShape(name) { if (typeof name == 'undefined') { return; } var shape; for (var i = 0, l = self.shapeList.length; i < l; i++) { shape = self.shapeList[i]; if (shape._name == name && shape.shape != 'text') { return shape; } } } /** * 特殊图形元素回调设置 * @param {Object} name * @param {Object} itemShape */ function setItemShape(name, itemShape) { var shape; for (var i = 0, l = self.shapeList.length; i < l; i++) { shape = self.shapeList[i]; if (shape._name == name && shape.shape != 'text') { if (!_selectedMap[name]) { itemShape.style.color = '#ccc'; itemShape.style.strokeColor = '#ccc'; } zr.modShape(shape.id, itemShape); } } } function isSelected(itemName) { if (typeof _selectedMap[itemName] != 'undefined') { return _selectedMap[itemName]; } else { // 没在legend里定义的都为true啊~ return true; } } function getSelectedMap() { return _selectedMap; } /** * 图例选择 */ function onlegendSelected(param, status) { var legendSelected = param.selected; for (var itemName in _selectedMap) { if (_selectedMap[itemName] != legendSelected[itemName]) { // 有一项不一致都需要重绘 status.needRefresh = true; } _selectedMap[itemName] = legendSelected[itemName]; } return; } self.init = init; self.refresh = refresh; self.setColor = setColor; self.getColor = getColor; self.hasColor = hasColor; self.add = add; self.del = del; self.getItemShape = getItemShape; self.setItemShape = setItemShape; self.isSelected = isSelected; self.getSelectedMap = getSelectedMap; self.onlegendSelected = onlegendSelected; init(option); } var legendIcon = { line : function (ctx, style) { var dy = style.height / 2; ctx.moveTo(style.x, style.y + dy); ctx.lineTo(style.x + style.width,style.y + dy); }, pie : function (ctx, style) { var x = style.x; var y = style.y; var width = style.width; var height = style.height; var sector = require('zrender/shape').get('sector'); sector.buildPath(ctx, { x : x + width / 2, y : y + height + 2, r : height + 2, r0 : 6, startAngle : 45, endAngle : 135 }); }, chord : function(ctx, style) { var x = style.x; var y = style.y; var width = style.width; var height = style.height; var beziercurve = require('zrender/shape').get('beziercurve'); ctx.moveTo(x, y + height); beziercurve.buildPath(ctx, { xStart : x, yStart : y + height, cpX1 : x + width, cpY1 : y + height, cpX2 : x, cpY2 : y + 4, xEnd : x + width, yEnd : y + 4 }); ctx.lineTo(x + width, y); beziercurve.buildPath(ctx, { xStart : x + width, yStart : y, cpX1 : x, cpY1 : y, cpX2 : x + width, cpY2 : y + height - 4, xEnd : x, yEnd : y + height - 4 }); ctx.lineTo(x, y + height); /* var x = style.x + 2; var y = style.y; var width = style.width - 2; var height = style.height; var r = width / Math.sqrt(3); ctx.moveTo(x, y); ctx.quadraticCurveTo(x + width / 4 * 3, y, x + width, y + height); ctx.arc( x + width / 2, y + height + r / 2, r, -Math.PI / 6, -Math.PI / 6 * 5, true); ctx.quadraticCurveTo(x - width / 2, y + height / 3, x, y); */ }, k : function (ctx, style) { var x = style.x; var y = style.y; var width = style.width; var height = style.height; var candle = require('zrender/shape').get('candle'); candle.buildPath(ctx, { x : x + width / 2, y : [y + 1, y + 1, y + height - 6, y + height], width : width - 6 }); }, bar : function (ctx, style) { //ctx.rect(style.x, style.y + 1, style.width, style.height - 2); var x = style.x; var y = style.y +1; var width = style.width; var height = style.height - 2; var r = 3; ctx.moveTo(x + r, y); ctx.lineTo(x + width - r, y); ctx.quadraticCurveTo( x + width, y, x + width, y + r ); ctx.lineTo(x + width, y + height - r); ctx.quadraticCurveTo( x + width, y + height, x + width - r, y + height ); ctx.lineTo(x + r, y + height); ctx.quadraticCurveTo( x, y + height, x, y + height - r ); ctx.lineTo(x, y + r); ctx.quadraticCurveTo(x, y, x + r, y); }, force : function(ctx, style) { require('zrender/shape').get('icon').get('circle')(ctx, style); }, radar: function(ctx, style) { var n = 6; var x = style.x + style.width / 2; var y = style.y + style.height / 2; var r = style.height / 2; var dStep = 2 * Math.PI / n; var deg = -Math.PI / 2; var xStart = x + r * Math.cos(deg); var yStart = y + r * Math.sin(deg); ctx.moveTo(xStart, yStart); deg += dStep; for (var i = 0, end = n - 1; i < end; i ++) { ctx.lineTo(x + r * Math.cos(deg), y + r * Math.sin(deg)); deg += dStep; } ctx.lineTo(xStart, yStart); } }; require('../component').define('legend', Legend); return Legend; }); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:handlePolygon,dataRange手柄 */ define( 'echarts/util/shape/handlePolygon',['require','zrender/tool/matrix','zrender/shape','zrender/shape/base','zrender/shape'],function(require) { var matrix = require('zrender/tool/matrix'); function HandlePolygon() { this.type = 'handlePolygon'; } HandlePolygon.prototype = { /** * 创建多边形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { require('zrender/shape').get('polygon').buildPath( ctx, style ); return; }, isCover : function(e, x, y) { //对鼠标的坐标也做相同的变换 if(e.__needTransform && e._transform){ var inverseMatrix = []; matrix.invert(inverseMatrix, e._transform); var originPos = [x, y]; matrix.mulVector(originPos, inverseMatrix, [x, y, 1]); if (x == originPos[0] && y == originPos[1]) { // 避免外部修改导致的__needTransform不准确 if (Math.abs(e.rotation[0]) > 0.0001 || Math.abs(e.position[0]) > 0.0001 || Math.abs(e.position[1]) > 0.0001 || Math.abs(e.scale[0] - 1) > 0.0001 || Math.abs(e.scale[1] - 1) > 0.0001 ) { e.__needTransform = true; } else { e.__needTransform = false; } } x = originPos[0]; y = originPos[1]; } // 快速预判并保留判断矩形 var rect = e.style.rect; // 提高交互体验,太小的图形包围盒四向扩大4px if (x >= rect.x && x <= (rect.x + rect.width) && y >= rect.y && y <= (rect.y + rect.height) ) { // 矩形内 return true; } else { return false; } } }; require('zrender/shape/base').derive(HandlePolygon); require('zrender/shape').define( 'handlePolygon', new HandlePolygon() ); return HandlePolygon; } ); /** * echarts组件:值域 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/dataRange',['require','./base','zrender/tool/area','zrender/tool/color','zrender/tool/color','../util/shape/handlePolygon','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 图表参数 * @param {Object=} selected 用于状态保持 */ function DataRange(ecConfig, messageCenter, zr, option) { var Base = require('./base'); Base.call(this, ecConfig, zr); var zrArea = require('zrender/tool/area'); var self = this; self.type = ecConfig.COMPONENT_TYPE_DATARANGE; var dataRangeOption; // 值域选项,共享数据源 var _zlevelBase = self.getZlevelBase(); var _itemGroupLocation = {}; // 值域元素组的位置参数,通过计算所得x, y, width, height var _calculableLocation; // 可计算元素的位置缓存 var _startShape; var _startMask; var _endShape; var _endMask; var _fillerShae; var _range; var _syncTicket; var _textGap = 10; // 非值文字间隔 var _gap; var _colorList; var _valueTextList; var _selectedMap = {}; function _buildShape() { _itemGroupLocation = _getItemGroupLocation(); // console.log(_itemGroupLocation); _buildBackground(); if (dataRangeOption.splitNumber <= 0 || dataRangeOption.calculable ) { _buildGradient(); } else { _buildItem(); } for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } _syncShapeFromRange(); } /** * 构建图例型的值域元素 */ function _buildItem() { var data = _valueTextList; var dataLength = data.length; var itemName; var itemShape; var textShape; var font = self.getFont(dataRangeOption.textStyle); var lastX = _itemGroupLocation.x; var lastY = _itemGroupLocation.y; var itemWidth = dataRangeOption.itemWidth; var itemHeight = dataRangeOption.itemHeight; var itemGap = dataRangeOption.itemGap; var textHeight = zrArea.getTextHeight('国', font); var color; if (dataRangeOption.orient == 'vertical' && dataRangeOption.x == 'right' ) { lastX = _itemGroupLocation.x + _itemGroupLocation.width - itemWidth; } var needValueText = true; if (dataRangeOption.text) { needValueText = false; // 第一个文字 if (dataRangeOption.text[0]) { textShape = _getTextShape( lastX, lastY, dataRangeOption.text[0] ); if (dataRangeOption.orient == 'horizontal') { lastX += zrArea.getTextWidth( dataRangeOption.text[0], font ) + _textGap; } else { lastY += textHeight + _textGap; textShape.style.y += textHeight / 2 + _textGap; textShape.style.textBaseline = 'bottom'; } self.shapeList.push(textShape); } } for (var i = 0; i < dataLength; i++) { itemName = data[i]; color = getColor((dataLength - i) * _gap + dataRangeOption.min); // 图形 itemShape = _getItemShape( lastX, lastY, itemWidth, itemHeight, (_selectedMap[i] ? color : '#ccc') ); itemShape._idx = i; itemShape.onclick = _dataRangeSelected; self.shapeList.push(itemShape); if (needValueText) { // 文字 textShape = { shape : 'text', zlevel : _zlevelBase, style : { x : lastX + itemWidth + 5, y : lastY, color : _selectedMap[i] ? dataRangeOption.textStyle.color : '#ccc', text: data[i], textFont: font, textBaseline: 'top' }, highlightStyle:{ brushType: 'fill' }, clickable : true }; if (dataRangeOption.orient == 'vertical' && dataRangeOption.x == 'right' ) { textShape.style.x -= (itemWidth + 10); textShape.style.textAlign = 'right'; } textShape._idx = i; textShape.onclick = _dataRangeSelected; self.shapeList.push(textShape); } if (dataRangeOption.orient == 'horizontal') { lastX += itemWidth + (needValueText ? 5 : 0) + (needValueText ? zrArea.getTextWidth(itemName, font) : 0) + itemGap; } else { lastY += itemHeight + itemGap; } } if (!needValueText && dataRangeOption.text[1]) { if (dataRangeOption.orient == 'horizontal') { lastX = lastX - itemGap + _textGap; } else { lastY = lastY - itemGap + _textGap; } // 最后一个文字 textShape = _getTextShape( lastX, lastY, dataRangeOption.text[1] ); if (dataRangeOption.orient != 'horizontal') { textShape.style.y -= 5; textShape.style.textBaseline = 'top'; } self.shapeList.push(textShape); } } /** * 构建渐变型的值域元素 */ function _buildGradient() { var itemShape; var textShape; var font = self.getFont(dataRangeOption.textStyle); var lastX = _itemGroupLocation.x; var lastY = _itemGroupLocation.y; var itemWidth = dataRangeOption.itemWidth; var itemHeight = dataRangeOption.itemHeight; var textHeight = zrArea.getTextHeight('国', font); var needValueText = true; if (dataRangeOption.text) { needValueText = false; // 第一个文字 if (dataRangeOption.text[0]) { textShape = _getTextShape( lastX, lastY, dataRangeOption.text[0] ); if (dataRangeOption.orient == 'horizontal') { lastX += zrArea.getTextWidth( dataRangeOption.text[0], font ) + _textGap; } else { lastY += textHeight + _textGap; textShape.style.y += textHeight / 2 + _textGap; textShape.style.textBaseline = 'bottom'; } self.shapeList.push(textShape); } } var zrColor = require('zrender/tool/color'); var per = 1 / (dataRangeOption.color.length - 1); var colorList = []; for (var i = 0, l = dataRangeOption.color.length; i < l; i++) { colorList.push([i * per, dataRangeOption.color[i]]); } if (dataRangeOption.orient == 'horizontal') { itemShape = { shape : 'rectangle', zlevel : _zlevelBase, style : { x : lastX, y : lastY, width : itemWidth * 10, height : itemHeight, color : zrColor.getLinearGradient( lastX, lastY, lastX + itemWidth * 10, lastY, colorList ) }, hoverable : false }; lastX += itemWidth * 10 + _textGap; } else { itemShape = { shape : 'rectangle', zlevel : _zlevelBase, style : { x : lastX, y : lastY, width : itemWidth, height : itemHeight * 10, color : zrColor.getLinearGradient( lastX, lastY, lastX, lastY + itemHeight * 10, colorList ) }, hoverable : false }; lastY += itemHeight * 10 + _textGap; } self.shapeList.push(itemShape); if (dataRangeOption.calculable) { _calculableLocation = itemShape.style; _buildFiller(); _bulidMask(); _bulidHandle(); } if (!needValueText && dataRangeOption.text[1]) { // 最后一个文字 textShape = _getTextShape( lastX, lastY, dataRangeOption.text[1] ); self.shapeList.push(textShape); } } /** * 构建填充物 */ function _buildFiller() { _fillerShae = { shape : 'rectangle', zlevel : _zlevelBase + 1, style : { x : _calculableLocation.x, y : _calculableLocation.y, width : _calculableLocation.width, height : _calculableLocation.height, color : 'rgba(255,255,255,0)' }, highlightStyle : { strokeColor : 'rgba(255,255,255,0.5)', lineWidth : 1 }, draggable : true, ondrift : _ondrift, ondragend : _ondragend, _type : 'filler' }; self.shapeList.push(_fillerShae); } /** * 构建拖拽手柄 */ function _bulidHandle() { var x = _calculableLocation.x; var y = _calculableLocation.y; var width = _calculableLocation.width; var height = _calculableLocation.height; var font = self.getFont(dataRangeOption.textStyle); var textHeight = zrArea.getTextHeight('国', font); var textWidth = Math.max( zrArea.getTextWidth( dataRangeOption.max.toFixed( dataRangeOption.precision ), font), zrArea.getTextWidth( dataRangeOption.min.toFixed( dataRangeOption.precision ), font ) ) + 2; var pointListStart; var textXStart; var textYStart; var coverRectStart; var pointListEnd; var textXEnd; var textYEnd; var coverRectEnd; if (dataRangeOption.orient == 'horizontal') { // 水平 if (dataRangeOption.y != 'bottom') { // 手柄统统在下方 pointListStart = [ [x, y], [x, y + height + textHeight], [x - textHeight, y + height + textHeight], [x - 1, y + height], [x - 1, y] ]; textXStart = x - textWidth / 2 - textHeight; textYStart = y + height + textHeight / 2 + 2; coverRectStart = { x : x - textWidth - textHeight, y : y + height, width : textWidth + textHeight, height : textHeight }; pointListEnd = [ [x + width, y], [x + width, y + height + textHeight], [x + width + textHeight, y + height + textHeight], [x + width + 1, y + height], [x + width + 1, y] ]; textXEnd = x + width + textWidth / 2 + textHeight; textYEnd = textYStart; coverRectEnd = { x : x + width, y : y + height, width : textWidth + textHeight, height : textHeight }; } else { // 手柄在上方 pointListStart = [ [x, y + height], [x, y - textHeight], [x - textHeight, y - textHeight], [x - 1, y], [x - 1, y + height] ]; textXStart = x - textWidth / 2 - textHeight; textYStart = y - textHeight / 2 - 2; coverRectStart = { x : x - textWidth - textHeight, y : y - textHeight, width : textWidth + textHeight, height : textHeight }; pointListEnd = [ [x + width, y + height], [x + width, y - textHeight], [x + width + textHeight, y - textHeight], [x + width + 1, y], [x + width + 1, y + height] ]; textXEnd = x + width + textWidth / 2 + textHeight; textYEnd = textYStart; coverRectEnd = { x : x + width, y : y - textHeight, width : textWidth + textHeight, height : textHeight }; } } else { textWidth += textHeight; // 垂直 if (dataRangeOption.x != 'right') { // 手柄统统在右侧 pointListStart = [ [x, y], [x + width + textHeight, y], [x + width + textHeight, y - textHeight], [x + width, y - 1], [x, y - 1] ]; textXStart = x + width + textWidth / 2 + textHeight / 2; textYStart = y - textHeight / 2; coverRectStart = { x : x + width, y : y - textHeight, width : textWidth + textHeight, height : textHeight }; pointListEnd = [ [x, y + height], [x + width + textHeight, y + height], [x + width + textHeight, y + textHeight + height], [x + width, y + 1 + height], [x, y + height + 1] ]; textXEnd = textXStart; textYEnd = y + height + textHeight / 2; coverRectEnd = { x : x + width, y : y + height, width : textWidth + textHeight, height : textHeight }; } else { // 手柄在左侧 pointListStart = [ [x + width, y], [x - textHeight, y], [x - textHeight, y - textHeight], [x, y - 1], [x + width, y - 1] ]; textXStart = x - textWidth / 2 - textHeight / 2; textYStart = y - textHeight / 2; coverRectStart = { x : x - textWidth - textHeight, y : y - textHeight, width : textWidth + textHeight, height : textHeight }; pointListEnd = [ [x + width, y + height], [x - textHeight, y + height], [x - textHeight, y + textHeight + height], [x, y + 1 + height], [x + width, y + height + 1] ]; textXEnd = textXStart; textYEnd = y + height + textHeight / 2; coverRectEnd = { x : x - textWidth - textHeight, y : y + height, width : textWidth + textHeight, height : textHeight }; } } _startShape = { shape : 'handlePolygon', style : { pointList : pointListStart, text : dataRangeOption.max.toFixed( dataRangeOption.precision ), textX : textXStart, textY : textYStart, color : getColor(dataRangeOption.max), rect : coverRectStart, x : pointListStart[0][0], y : pointListStart[0][1], _x : pointListStart[0][0], // 拖拽区域控制缓存 _y : pointListStart[0][1] } }; _startShape.highlightStyle = { strokeColor : _startShape.style.color, lineWidth : 1 }; _endShape = { shape : 'handlePolygon', style : { pointList : pointListEnd, text : dataRangeOption.min.toFixed( dataRangeOption.precision ), textX : textXEnd, textY : textYEnd, color : getColor(dataRangeOption.min), rect : coverRectEnd, x : pointListEnd[0][0], y : pointListEnd[0][1], _x : pointListEnd[0][0], // 拖拽区域控制缓存 _y : pointListEnd[0][1] } }; _endShape.highlightStyle = { strokeColor : _endShape.style.color, lineWidth : 1 }; // 统一参数 _startShape.zlevel = _endShape.zlevel = _zlevelBase + 1; _startShape.draggable = _endShape.draggable = true; _startShape.ondrift = _endShape.ondrift = _ondrift; _startShape.ondragend = _endShape.ondragend = _ondragend; _startShape.style.textColor = _endShape.style.textColor = dataRangeOption.textStyle.color; _startShape.style.textAlign = _endShape.style.textAlign = 'center'; _startShape.style.textPosition = _endShape.style.textPosition = 'specific'; _startShape.style.textBaseline = _endShape.style.textBaseline = 'middle'; _startShape.style.width = _endShape.style.width = 0; // for ondrif计算统一 _startShape.style.height = _endShape.style.height = 0; _startShape.style.textPosition = _endShape.style.textPosition = 'specific'; self.shapeList.push(_startShape); self.shapeList.push(_endShape); } function _bulidMask() { var x = _calculableLocation.x; var y = _calculableLocation.y; var width = _calculableLocation.width; var height = _calculableLocation.height; _startMask = { shape : 'rectangle', zlevel : _zlevelBase + 1, style : { x : x, y : y, width : dataRangeOption.orient == 'horizontal' ? 0 : width, height : dataRangeOption.orient == 'horizontal' ? height : 0, color : '#ccc' }, hoverable:false }; _endMask = { shape : 'rectangle', zlevel : _zlevelBase + 1, style : { x : dataRangeOption.orient == 'horizontal' ? x + width : x, y : dataRangeOption.orient == 'horizontal' ? y : y + height, width : dataRangeOption.orient == 'horizontal' ? 0 : width, height : dataRangeOption.orient == 'horizontal' ? height : 0, color : '#ccc' }, hoverable:false }; self.shapeList.push(_startMask); self.shapeList.push(_endMask); } function _buildBackground() { var pTop = dataRangeOption.padding[0]; var pRight = dataRangeOption.padding[1]; var pBottom = dataRangeOption.padding[2]; var pLeft = dataRangeOption.padding[3]; self.shapeList.push({ shape : 'rectangle', zlevel : _zlevelBase, hoverable :false, style : { x : _itemGroupLocation.x - pLeft, y : _itemGroupLocation.y - pTop, width : _itemGroupLocation.width + pLeft + pRight, height : _itemGroupLocation.height + pTop + pBottom, brushType : dataRangeOption.borderWidth === 0 ? 'fill' : 'both', color : dataRangeOption.backgroundColor, strokeColor : dataRangeOption.borderColor, lineWidth : dataRangeOption.borderWidth } }); } /** * 根据选项计算值域实体的位置坐标 */ function _getItemGroupLocation() { var data = _valueTextList; var dataLength = data.length; var itemGap = dataRangeOption.itemGap; var itemWidth = dataRangeOption.itemWidth; var itemHeight = dataRangeOption.itemHeight; var totalWidth = 0; var totalHeight = 0; var font = self.getFont(dataRangeOption.textStyle); var textHeight = zrArea.getTextHeight('国', font); if (dataRangeOption.orient == 'horizontal') { // 水平布局,计算总宽度 if (dataRangeOption.text || dataRangeOption.splitNumber <= 0 || dataRangeOption.calculable ) { // 指定文字或线性渐变 totalWidth = ((dataRangeOption.splitNumber <= 0 || dataRangeOption.calculable) ? (itemWidth * 10 + itemGap) : dataLength * (itemWidth + itemGap)) + (dataRangeOption.text && typeof dataRangeOption.text[0] != 'undefined' ? (zrArea.getTextWidth( dataRangeOption.text[0], font ) + _textGap) : 0) + (dataRangeOption.text && typeof dataRangeOption.text[1] != 'undefined' ? (zrArea.getTextWidth( dataRangeOption.text[1], font ) + _textGap) : 0); } else { // 值标签 itemWidth += 5; for (var i = 0; i < dataLength; i++) { totalWidth += itemWidth + zrArea.getTextWidth( data[i], font ) + itemGap; } } totalWidth -= itemGap; // 减去最后一个的itemGap totalHeight = Math.max(textHeight, itemHeight); } else { // 垂直布局,计算总高度 var maxWidth; if (dataRangeOption.text || dataRangeOption.splitNumber <= 0 || dataRangeOption.calculable ) { // 指定文字或线性渐变 totalHeight = ((dataRangeOption.splitNumber <= 0 || dataRangeOption.calculable) ? (itemHeight * 10 + itemGap) : dataLength * (itemHeight + itemGap)) + (dataRangeOption.text && typeof dataRangeOption.text[0] != 'undefined' ? (_textGap + textHeight) : 0) + (dataRangeOption.text && typeof dataRangeOption.text[1] != 'undefined' ? (_textGap + textHeight) : 0); maxWidth = Math.max( zrArea.getTextWidth( (dataRangeOption.text && dataRangeOption.text[0]) || '', font ), zrArea.getTextWidth( (dataRangeOption.text && dataRangeOption.text[1]) || '', font ) ); totalWidth = Math.max(itemWidth, maxWidth); } else { totalHeight = (itemHeight + itemGap) * dataLength; // 值标签 itemWidth += 5; maxWidth = 0; for (var i = 0; i < dataLength; i++) { maxWidth = Math.max( maxWidth, zrArea.getTextWidth( data[i], font ) ); } totalWidth = itemWidth + maxWidth; } totalHeight -= itemGap; // 减去最后一个的itemGap; } var x; var zrWidth = zr.getWidth(); switch (dataRangeOption.x) { case 'center' : x = Math.floor((zrWidth - totalWidth) / 2); break; case 'left' : x = dataRangeOption.padding[3] + dataRangeOption.borderWidth; break; case 'right' : x = zrWidth - totalWidth - dataRangeOption.padding[1] - dataRangeOption.borderWidth; break; default : x = self.parsePercent(dataRangeOption.x, zrWidth); x = isNaN(x) ? 0 : x; break; } var y; var zrHeight = zr.getHeight(); switch (dataRangeOption.y) { case 'top' : y = dataRangeOption.padding[0] + dataRangeOption.borderWidth; break; case 'bottom' : y = zrHeight - totalHeight - dataRangeOption.padding[2] - dataRangeOption.borderWidth; break; case 'center' : y = Math.floor((zrHeight - totalHeight) / 2); break; default : y = self.parsePercent(dataRangeOption.y, zrHeight); y = isNaN(y) ? 0 : y; break; } if (dataRangeOption.calculable) { // 留出手柄控件 var handlerWidth = Math.max( zrArea.getTextWidth(dataRangeOption.max, font), zrArea.getTextWidth(dataRangeOption.min, font) ) + textHeight; if (dataRangeOption.orient == 'horizontal') { if (x < handlerWidth) { x = handlerWidth; } if (x + totalWidth + handlerWidth > zrWidth) { x -= handlerWidth; } } else { if (y < textHeight) { y = textHeight; } if (y + totalHeight + textHeight > zrHeight) { y -= textHeight; } } } return { x : x, y : y, width : totalWidth, height : totalHeight }; } // 指定文本 function _getTextShape(x, y, text) { return { shape : 'text', zlevel : _zlevelBase, style : { x : (dataRangeOption.orient == 'horizontal' ? x : _itemGroupLocation.x + _itemGroupLocation.width / 2 ), y : (dataRangeOption.orient == 'horizontal' ? _itemGroupLocation.y + _itemGroupLocation.height / 2 : y ), color : dataRangeOption.textStyle.color, text: text, textFont: self.getFont(dataRangeOption.textStyle), textBaseline: (dataRangeOption.orient == 'horizontal' ? 'middle' : 'top'), textAlign: (dataRangeOption.orient == 'horizontal' ? 'left' : 'center') }, hoverable : false }; } // 色尺legend item shape function _getItemShape(x, y, width, height, color) { return { shape : 'rectangle', zlevel : _zlevelBase, style : { x : x, y : y + 1, width : width, height : height - 2, color : color }, highlightStyle: { strokeColor: color, lineWidth : 1 }, clickable : true }; } /** * 拖拽范围控制 */ function _ondrift(e, dx, dy) { var x = _calculableLocation.x; var y = _calculableLocation.y; var width = _calculableLocation.width; var height = _calculableLocation.height; if (dataRangeOption.orient == 'horizontal') { if (e.style.x + dx <= x) { e.style.x = x; } else if (e.style.x + dx + e.style.width >= x + width) { e.style.x = x + width - e.style.width; } else { e.style.x += dx; } } else { if (e.style.y + dy <= y) { e.style.y = y; } else if (e.style.y + dy + e.style.height >= y + height) { e.style.y = y + height - e.style.height; } else { e.style.y += dy; } } if (e._type == 'filler') { _syncHandleShape(); } else { _syncFillerShape(e); } if (dataRangeOption.realtime) { _syncData(); } else { clearTimeout(_syncTicket); _syncTicket = setTimeout(_syncData, 200); } return true; } function _ondragend() { self.isDragend = true; } /** * 数据项被拖拽出去 */ function ondragend(param, status) { if (!self.isDragend || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } _syncData(); // 别status = {}赋值啊!! status.dragOut = true; status.dragIn = true; if (!dataRangeOption.realtime) { messageCenter.dispatch( ecConfig.EVENT.DATA_RANGE, null, { range : { start : _range.end, end : _range.start } } ); } status.needRefresh = false; // 会有消息触发fresh,不用再刷一遍 // 处理完拖拽事件后复位 self.isDragend = false; return; } // 外部传入range function _syncShapeFromRange() { if (dataRangeOption.range) { // 做一个反转 if (typeof dataRangeOption.range.start != 'undefined') { _range.end = dataRangeOption.range.start; } if (typeof dataRangeOption.range.end != 'undefined') { _range.start = dataRangeOption.range.end; } if (_range.start != 100 || _range.end !== 0) { // 非默认满值同步一下图形 if (dataRangeOption.orient == 'horizontal') { // 横向 var width = _fillerShae.style.width; _fillerShae.style.x += width * (100 - _range.start) / 100; _fillerShae.style.width = width * (_range.start - _range.end) / 100; } else { // 纵向 var height = _fillerShae.style.height; _fillerShae.style.y += height * (100 - _range.start) / 100; _fillerShae.style.height = height * (_range.start - _range.end) / 100; } zr.modShape(_fillerShae.id, _fillerShae); _syncHandleShape(); } } } function _syncHandleShape() { var x = _calculableLocation.x; var y = _calculableLocation.y; var width = _calculableLocation.width; var height = _calculableLocation.height; if (dataRangeOption.orient == 'horizontal') { _startShape.style.x = _fillerShae.style.x; _startMask.style.width = _startShape.style.x - x; _endShape.style.x = _fillerShae.style.x + _fillerShae.style.width; _endMask.style.x = _endShape.style.x; _endMask.style.width = x + width - _endShape.style.x; _range.start = Math.ceil( 100 - (_startShape.style.x - x) / width * 100 ); _range.end = Math.floor( 100 - (_endShape.style.x - x) / width * 100 ); } else { _startShape.style.y = _fillerShae.style.y; _startMask.style.height = _startShape.style.y - y; _endShape.style.y = _fillerShae.style.y + _fillerShae.style.height; _endMask.style.y = _endShape.style.y; _endMask.style.height = y + height - _endShape.style.y; _range.start = Math.ceil( 100 - (_startShape.style.y - y) / height * 100 ); _range.end = Math.floor( 100 - (_endShape.style.y - y) / height * 100 ); } _syncShape(false); } function _syncFillerShape(e) { var x = _calculableLocation.x; var y = _calculableLocation.y; var width = _calculableLocation.width; var height = _calculableLocation.height; var a; var b; if (dataRangeOption.orient == 'horizontal') { a = _startShape.style.x; b = _endShape.style.x; if (e.id == _startShape.id && a >= b) { // _startShape触发 b = a; _endShape.style.x = a; } else if (e.id == _endShape.id && a >= b) { // _endShape触发 a = b; _startShape.style.x = a; } _fillerShae.style.x = a; _fillerShae.style.width = b - a; _startMask.style.width = a - x; _endMask.style.x = b; _endMask.style.width = x + width - b; _range.start = Math.ceil(100 - (a - x) / width * 100); _range.end = Math.floor(100 - (b - x) / width * 100); } else { a = _startShape.style.y; b = _endShape.style.y; if (e.id == _startShape.id && a >= b) { // _startShape触发 b = a; _endShape.style.y = a; } else if (e.id == _endShape.id && a >= b) { // _endShape触发 a = b; _startShape.style.y = a; } _fillerShae.style.y = a; _fillerShae.style.height = b - a; _startMask.style.height = a - y; _endMask.style.y = b; _endMask.style.height = y + height - b; _range.start = Math.ceil(100 - (a - y) / height * 100); _range.end = Math.floor(100 - (b - y) / height * 100); } _syncShape(true); } function _syncShape(needFiller) { _startShape.position = [ _startShape.style.x - _startShape.style._x, _startShape.style.y - _startShape.style._y ]; if (dataRangeOption.precision === 0) { _startShape.style.text = Math.round( _gap * _range.start + dataRangeOption.min ) + ''; } else { _startShape.style.text =( _gap * _range.start + dataRangeOption.min ).toFixed(dataRangeOption.precision); } _startShape.style.color = _startShape.highlightStyle.strokeColor = getColor( _gap * _range.start + dataRangeOption.min ); zr.modShape(_startShape.id, _startShape); _endShape.position = [ _endShape.style.x - _endShape.style._x, _endShape.style.y - _endShape.style._y ]; if (dataRangeOption.precision === 0) { _endShape.style.text = Math.round( _gap * _range.end + dataRangeOption.min ) + ''; } else { _endShape.style.text = ( _gap * _range.end + dataRangeOption.min ).toFixed(dataRangeOption.precision); } _endShape.style.color = _endShape.highlightStyle.strokeColor = getColor( _gap * _range.end + dataRangeOption.min ); zr.modShape(_endShape.id, _endShape); zr.modShape(_startMask.id, _startMask); zr.modShape(_endMask.id, _endMask); needFiller && zr.modShape(_fillerShae.id, _fillerShae); zr.refresh(); } function _syncData() { if (dataRangeOption.realtime) { messageCenter.dispatch( ecConfig.EVENT.DATA_RANGE, null, { range : { start : _range.end, end : _range.start } } ); } } function _dataRangeSelected(param) { var idx = param.target._idx; _selectedMap[idx] = !_selectedMap[idx]; messageCenter.dispatch(ecConfig.EVENT.REFRESH); } function init(newOption) { if (typeof self.query(newOption, 'dataRange.min') == 'undefined' || typeof self.query(newOption, 'dataRange.max') == 'undefined' ) { return; } option = newOption; option.dataRange = self.reformOption(option.dataRange); // 补全padding属性 option.dataRange.padding = self.reformCssArray( option.dataRange.padding ); dataRangeOption = option.dataRange; self.clear(); _selectedMap = {}; var zrColor = require('zrender/tool/color'); var splitNumber = dataRangeOption.splitNumber <= 0 || dataRangeOption.calculable ? 100 : dataRangeOption.splitNumber; _colorList = zrColor.getGradientColors( dataRangeOption.color, Math.max( (splitNumber - dataRangeOption.color.length) / (dataRangeOption.color.length - 1), 0 ) + 1 ); if (_colorList.length > splitNumber) { var len = _colorList.length; var newColorList = [_colorList[0]]; var step = len / (splitNumber - 1); for (var i = 1; i < splitNumber - 1; i++) { newColorList.push(_colorList[Math.floor(i * step)]); } newColorList.push(_colorList[len - 1]); _colorList = newColorList; } // console.log(_colorList.length) if (dataRangeOption.precision === 0) { _gap = Math.round( (dataRangeOption.max - dataRangeOption.min) / splitNumber ) || 1; } else { _gap = (dataRangeOption.max - dataRangeOption.min) / splitNumber; _gap = _gap.toFixed(dataRangeOption.precision) - 0; } _valueTextList = []; for (var i = 0; i < splitNumber; i++) { _selectedMap[i] = true; _valueTextList.unshift( (i * _gap + dataRangeOption.min).toFixed( dataRangeOption.precision ) + ' - ' + ((i + 1) * _gap + dataRangeOption.min).toFixed( dataRangeOption.precision ) ); } _range = { start: 100, end: 0 }; // console.log(_valueTextList,_gap); // console.log(_colorList); _buildShape(); } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; option.dataRange = self.reformOption(option.dataRange); // 补全padding属性 option.dataRange.padding = self.reformCssArray( option.dataRange.padding ); } dataRangeOption = option.dataRange; // 做一个反转 dataRangeOption.range = { start: _range.end, end: _range.start }; /* _range = { start: 100, end: 0 }; */ self.clear(); _buildShape(); } function getColor(value) { if (isNaN(value)) { return null; } if (value < dataRangeOption.min) { value = dataRangeOption.min; } else if (value > dataRangeOption.max) { value = dataRangeOption.max; } if (dataRangeOption.calculable) { if (value > _gap * _range.start + dataRangeOption.min || value < _gap * _range.end + dataRangeOption.min) { return null; } } var idx = _colorList.length - Math.ceil( (value - dataRangeOption.min) / (dataRangeOption.max - dataRangeOption.min) * _colorList.length ); if (idx == _colorList.length) { idx--; } //console.log(value, idx,_colorList[idx]) if (_selectedMap[idx]) { return _colorList[idx]; } else { return null; } } self.init = init; self.refresh = refresh; self.getColor = getColor; self.ondragend = ondragend; init(option); } // 动态扩展zrender shape:candle require('../util/shape/handlePolygon'); require('../component').define('dataRange', DataRange); return DataRange; }); /** * echarts组件:提示框 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/tooltip',['require','./base','../util/ecData','zrender/config','zrender/shape','zrender/tool/event','zrender/tool/area','zrender/tool/color','zrender/tool/util','zrender/shape/base','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 提示框参数 * @param {HtmlElement} dom 目标对象 * @param {ECharts} myChart 当前图表实例 */ function Tooltip(ecConfig, messageCenter, zr, option, dom, myChart) { var Base = require('./base'); Base.call(this, ecConfig, zr); var ecData = require('../util/ecData'); var zrConfig = require('zrender/config'); var zrShape = require('zrender/shape'); var zrEvent = require('zrender/tool/event'); var zrArea = require('zrender/tool/area'); var zrColor = require('zrender/tool/color'); var zrUtil = require('zrender/tool/util'); var zrShapeBase = require('zrender/shape/base'); var rectangle = zrShape.get('rectangle'); var self = this; self.type = ecConfig.COMPONENT_TYPE_TOOLTIP; var _zlevelBase = self.getZlevelBase(); var component = {}; // 组件索引 var grid; var xAxis; var yAxis; var polar; var _selectedMap = {}; // tooltip dom & css var _tDom = document.createElement('div'); // 通用样式 var _gCssText = 'position:absolute;' + 'display:block;' + 'border-style:solid;' + 'white-space:nowrap;'; // 默认样式 var _defaultCssText; // css样式缓存 var _needAxisTrigger; // 坐标轴触发 var _hidingTicket; var _hideDelay; // 隐藏延迟 var _showingTicket; var _showDelay; // 显示延迟 var _curTarget; var _event; var _curTicket; // 异步回调标识,用来区分多个请求 // 缓存一些高宽数据 var _zrHeight = zr.getHeight(); var _zrWidth = zr.getWidth(); var _lastTipShape = false; var _axisLineWidth = 0; var _axisLineShape = { shape : 'line', id : zr.newShapeId('tooltip'), zlevel: _zlevelBase, invisible : true, hoverable: false, style : { // lineWidth : 2, // strokeColor : ecConfig.categoryAxis.axisLine.lineStyle.color } }; var _axisShadowShape = { shape : 'line', id : zr.newShapeId('tooltip'), zlevel: 1, // grid上,chart下 invisible : true, hoverable: false, style : { // lineWidth : 10, // strokeColor : ecConfig.categoryAxis.axisLine.lineStyle.color } }; zr.addShape(_axisLineShape); zr.addShape(_axisShadowShape); /** * 根据配置设置dom样式 */ function _style(opt) { if (!opt) { return ''; } var cssText = []; if (opt.transitionDuration) { var transitionText = 'left ' + opt.transitionDuration + 's,' + 'top ' + opt.transitionDuration + 's'; cssText.push( 'transition:' + transitionText ); cssText.push( '-moz-transition:' + transitionText ); cssText.push( '-webkit-transition:' + transitionText ); cssText.push( '-o-transition:' + transitionText ); } if (opt.backgroundColor) { // for sb ie~ cssText.push( 'background-Color:' + zrColor.toHex( opt.backgroundColor ) ); cssText.push('filter:alpha(opacity=70)'); cssText.push('background-Color:' + opt.backgroundColor); } if (typeof opt.borderWidth != 'undefined') { cssText.push('border-width:' + opt.borderWidth + 'px'); } if (typeof opt.borderColor != 'undefined') { cssText.push('border-color:' + opt.borderColor); } if (typeof opt.borderRadius != 'undefined') { cssText.push( 'border-radius:' + opt.borderRadius + 'px' ); cssText.push( '-moz-border-radius:' + opt.borderRadius + 'px' ); cssText.push( '-webkit-border-radius:' + opt.borderRadius + 'px' ); cssText.push( '-o-border-radius:' + opt.borderRadius + 'px' ); } var textStyle = opt.textStyle; if (textStyle) { textStyle.color && cssText.push('color:' + textStyle.color); textStyle.decoration && cssText.push( 'text-decoration:' + textStyle.decoration ); textStyle.align && cssText.push( 'text-align:' + textStyle.align ); textStyle.fontFamily && cssText.push( 'font-family:' + textStyle.fontFamily ); textStyle.fontSize && cssText.push( 'font-size:' + textStyle.fontSize + 'px' ); textStyle.fontSize && cssText.push( 'line-height:' + Math.round(textStyle.fontSize*3/2) + 'px' ); textStyle.fontStyle && cssText.push( 'font-style:' + textStyle.fontStyle ); textStyle.fontWeight && cssText.push( 'font-weight:' + textStyle.fontWeight ); } var padding = opt.padding; if (typeof padding != 'undefined') { padding = self.reformCssArray(padding); cssText.push( 'padding:' + padding[0] + 'px ' + padding[1] + 'px ' + padding[2] + 'px ' + padding[3] + 'px' ); } cssText = cssText.join(';') + ';'; return cssText; } function _hide() { if (_tDom) { _tDom.style.display = 'none'; } var needRefresh = false; if (!_axisLineShape.invisible) { _axisLineShape.invisible = true; zr.modShape(_axisLineShape.id, _axisLineShape); needRefresh = true; } if (!_axisShadowShape.invisible) { _axisShadowShape.invisible = true; zr.modShape(_axisShadowShape.id, _axisShadowShape); needRefresh = true; } if (_lastTipShape && _lastTipShape.tipShape.length > 0) { zr.delShape(_lastTipShape.tipShape); _lastTipShape = false; } needRefresh && zr.refresh(); } function _show(x, y, specialCssText) { var domHeight = _tDom.offsetHeight; var domWidth = _tDom.offsetWidth; if (x + domWidth > _zrWidth) { // 太靠右 //x = _zrWidth - domWidth; x -= (domWidth + 40); } if (y + domHeight > _zrHeight) { // 太靠下 //y = _zrHeight - domHeight; y -= (domHeight - 20); } if (y < 20) { y = 0; } _tDom.style.cssText = _gCssText + _defaultCssText + (specialCssText ? specialCssText : '') + 'left:' + x + 'px;top:' + y + 'px;'; if (domHeight < 10 || domWidth < 10) { // _zrWidth - x < 100 || _zrHeight - y < 100 setTimeout(_refixed, 20); } } function _refixed() { if (_tDom) { var cssText = ''; var domHeight = _tDom.offsetHeight; var domWidth = _tDom.offsetWidth; if (_tDom.offsetLeft + domWidth > _zrWidth) { cssText += 'left:' + (_zrWidth - domWidth - 20) + 'px;'; } if (_tDom.offsetTop + domHeight > _zrHeight) { cssText += 'top:' + (_zrHeight - domHeight - 10) + 'px;'; } if (cssText !== '') { _tDom.style.cssText += cssText; } } } function _tryShow() { var needShow; var trigger; if (!_curTarget) { // 坐标轴事件 _findPolarTrigger() || _findAxisTrigger(); } else { // 数据项事件 if (_curTarget._type == 'island' && option.tooltip.show) { _showItemTrigger(); return; } var serie = ecData.get(_curTarget, 'series'); var data = ecData.get(_curTarget, 'data'); needShow = self.deepQuery( [data, serie, option], 'tooltip.show' ); if (typeof serie == 'undefined' || typeof data == 'undefined' || needShow === false ) { // 不响应tooltip的数据对象延时隐藏 clearTimeout(_hidingTicket); clearTimeout(_showingTicket); _hidingTicket = setTimeout(_hide, _hideDelay); } else { trigger = self.deepQuery( [data, serie, option], 'tooltip.trigger' ); trigger == 'axis' ? _showAxisTrigger( serie.xAxisIndex, serie.yAxisIndex, ecData.get(_curTarget, 'dataIndex') ) : _showItemTrigger(); } } } /** * 直角系 */ function _findAxisTrigger() { if (!xAxis || !yAxis) { _hidingTicket = setTimeout(_hide, _hideDelay); return; } var series = option.series; var xAxisIndex; var yAxisIndex; for (var i = 0, l = series.length; i < l; i++) { // 找到第一个axis触发tooltip的系列 if (self.deepQuery( [series[i], option], 'tooltip.trigger' ) == 'axis' ) { xAxisIndex = series[i].xAxisIndex || 0; yAxisIndex = series[i].yAxisIndex || 0; if (xAxis.getAxis(xAxisIndex) && xAxis.getAxis(xAxisIndex).type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY ) { // 横轴为类目轴 _showAxisTrigger(xAxisIndex, yAxisIndex, _getNearestDataIndex('x', xAxis.getAxis(xAxisIndex)) ); return; } else if (yAxis.getAxis(yAxisIndex) && yAxis.getAxis(yAxisIndex).type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY ) { // 纵轴为类目轴 _showAxisTrigger(xAxisIndex, yAxisIndex, _getNearestDataIndex('y', yAxis.getAxis(yAxisIndex)) ); return; } } } } /** * 极坐标 */ function _findPolarTrigger() { if (!polar) { return false; } var x = zrEvent.getX(_event); var y = zrEvent.getY(_event); var polarIndex = polar.getNearestIndex([x, y]); var valueIndex; if (polarIndex) { valueIndex = polarIndex.valueIndex; polarIndex = polarIndex.polarIndex; } else { polarIndex = -1; } if (polarIndex != -1) { return _showPolarTrigger(polarIndex, valueIndex); } return false; } /** * 根据坐标轴事件带的属性获取最近的axisDataIndex */ function _getNearestDataIndex(direction, categoryAxis) { var dataIndex = -1; var x = zrEvent.getX(_event); var y = zrEvent.getY(_event); if (direction == 'x') { // 横轴为类目轴 var left; var right; var xEnd = grid.getXend(); var curCoord = categoryAxis.getCoordByIndex(dataIndex); while (curCoord < xEnd) { if (curCoord <= x) { left = curCoord; } if (curCoord >= x) { break; } curCoord = categoryAxis.getCoordByIndex(++dataIndex); right = curCoord; } if (x - left < right - x) { dataIndex -= dataIndex !== 0 ? 1 : 0; } else { // 离右边近,看是否为最后一个 if (typeof categoryAxis.getNameByIndex(dataIndex) == 'undefined' ) { dataIndex -= 1; } } return dataIndex; } else { // 纵轴为类目轴 var top; var bottom; var yStart = grid.getY(); var curCoord = categoryAxis.getCoordByIndex(dataIndex); while (curCoord > yStart) { if (curCoord >= y) { bottom = curCoord; } if (curCoord <= y) { break; } curCoord = categoryAxis.getCoordByIndex(++dataIndex); top = curCoord; } if (y - top > bottom - y) { dataIndex -= dataIndex !== 0 ? 1 : 0; } else { // 离上方边近,看是否为最后一个 if (typeof categoryAxis.getNameByIndex(dataIndex) == 'undefined' ) { dataIndex -= 1; } } return dataIndex; } return -1; } /** * 直角系 */ function _showAxisTrigger(xAxisIndex, yAxisIndex, dataIndex) { !_event.connectTrigger && messageCenter.dispatch( ecConfig.EVENT.TOOLTIP_IN_GRID, _event ); if (typeof xAxis == 'undefined' || typeof yAxis == 'undefined' || typeof xAxisIndex == 'undefined' || typeof yAxisIndex == 'undefined' || dataIndex < 0 ) { // 不响应tooltip的数据对象延时隐藏 clearTimeout(_hidingTicket); clearTimeout(_showingTicket); _hidingTicket = setTimeout(_hide, _hideDelay); return; } var series = option.series; var seriesArray = []; var seriesIndex = []; var categoryAxis; var x; var y; var formatter; var showContent; var specialCssText = ''; if (option.tooltip.trigger == 'axis') { if (option.tooltip.show === false) { return; } formatter = option.tooltip.formatter; } if (xAxisIndex != -1 && xAxis.getAxis(xAxisIndex).type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY ) { // 横轴为类目轴,找到所有用这条横轴并且axis触发的系列数据 categoryAxis = xAxis.getAxis(xAxisIndex); for (var i = 0, l = series.length; i < l; i++) { if (!_isSelected(series[i].name)) { continue; } if (series[i].xAxisIndex == xAxisIndex && self.deepQuery( [series[i], option], 'tooltip.trigger' ) == 'axis' ) { showContent = self.query( series[i], 'tooltip.showContent' ) || showContent; formatter = self.query( series[i], 'tooltip.formatter' ) || formatter; specialCssText += _style(self.query( series[i], 'tooltip' )); seriesArray.push(series[i]); seriesIndex.push(i); } } // 寻找高亮元素 messageCenter.dispatch( ecConfig.EVENT.TOOLTIP_HOVER, _event, { seriesIndex : seriesIndex, dataIndex : component.dataZoom ? component.dataZoom.getRealDataIndex( seriesIndex, dataIndex ) : dataIndex } ); y = zrEvent.getY(_event) + 10; x = self.subPixelOptimize( categoryAxis.getCoordByIndex(dataIndex), _axisLineWidth ); _styleAxisPointer( seriesArray, x, grid.getY(), x, grid.getYend(), categoryAxis.getGap() ); x += 10; } else if (yAxisIndex != -1 && yAxis.getAxis(yAxisIndex).type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY ) { // 纵轴为类目轴,找到所有用这条纵轴并且axis触发的系列数据 categoryAxis = yAxis.getAxis(yAxisIndex); for (var i = 0, l = series.length; i < l; i++) { if (!_isSelected(series[i].name)) { continue; } if (series[i].yAxisIndex == yAxisIndex && self.deepQuery( [series[i], option], 'tooltip.trigger' ) == 'axis' ) { showContent = self.query( series[i], 'tooltip.showContent' ) || showContent; formatter = self.query( series[i], 'tooltip.formatter' ) || formatter; specialCssText += _style(self.query( series[i], 'tooltip' )); seriesArray.push(series[i]); seriesIndex.push(i); } } // 寻找高亮元素 messageCenter.dispatch( ecConfig.EVENT.TOOLTIP_HOVER, _event, { seriesIndex : seriesIndex, dataIndex : component.dataZoom ? component.dataZoom.getRealDataIndex( seriesIndex, dataIndex ) : dataIndex } ); x = zrEvent.getX(_event) + 10; y = self.subPixelOptimize( categoryAxis.getCoordByIndex(dataIndex), _axisLineWidth ); _styleAxisPointer( seriesArray, grid.getX(), y, grid.getXend(), y, categoryAxis.getGap() ); y += 10; } if (seriesArray.length > 0) { var data; if (typeof formatter == 'function') { var params = []; for (var i = 0, l = seriesArray.length; i < l; i++) { data = seriesArray[i].data[dataIndex]; data = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; params.push([ seriesArray[i].name || '', categoryAxis.getNameByIndex(dataIndex), data ]); } _curTicket = 'axis:' + dataIndex; _tDom.innerHTML = formatter( params, _curTicket, _setContent ); } else if (typeof formatter == 'string') { _curTicket = NaN; formatter = formatter.replace('{a}','{a0}') .replace('{b}','{b0}') .replace('{c}','{c0}'); for (var i = 0, l = seriesArray.length; i < l; i++) { formatter = formatter.replace( '{a' + i + '}', _encodeHTML(seriesArray[i].name || '') ); formatter = formatter.replace( '{b' + i + '}', _encodeHTML(categoryAxis.getNameByIndex(dataIndex)) ); data = seriesArray[i].data[dataIndex]; data = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; formatter = formatter.replace( '{c' + i + '}', data instanceof Array ? data : self.numAddCommas(data) ); } _tDom.innerHTML = formatter; } else { _curTicket = NaN; formatter = _encodeHTML( categoryAxis.getNameByIndex(dataIndex) ); for (var i = 0, l = seriesArray.length; i < l; i++) { formatter += '
' + _encodeHTML(seriesArray[i].name || '') + ' : '; data = seriesArray[i].data[dataIndex]; data = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; formatter += data instanceof Array ? data : self.numAddCommas(data); } _tDom.innerHTML = formatter; } if (showContent === false || !option.tooltip.showContent) { // 只用tooltip的行为,不显示主体 return; } if (!self.hasAppend) { _tDom.style.left = _zrWidth / 2 + 'px'; _tDom.style.top = _zrHeight / 2 + 'px'; dom.firstChild.appendChild(_tDom); self.hasAppend = true; } _show(x, y, specialCssText); } } /** * 极坐标 */ function _showPolarTrigger(polarIndex, dataIndex) { if (typeof polar == 'undefined' || typeof polarIndex == 'undefined' || typeof dataIndex == 'undefined' || dataIndex < 0 ) { return false; } var series = option.series; var seriesArray = []; var formatter; var showContent; var specialCssText = ''; if (option.tooltip.trigger == 'axis') { if (option.tooltip.show === false) { return false; } formatter = option.tooltip.formatter; } var indicatorName = option.polar[polarIndex].indicator[dataIndex].text; // 找到所有用这个极坐标并且axis触发的系列数据 for (var i = 0, l = series.length; i < l; i++) { if (!_isSelected(series[i].name)) { continue; } if (series[i].polarIndex == polarIndex && self.deepQuery( [series[i], option], 'tooltip.trigger' ) == 'axis' ) { showContent = self.query( series[i], 'tooltip.showContent' ) || showContent; formatter = self.query( series[i], 'tooltip.formatter' ) || formatter; specialCssText += _style(self.query( series[i], 'tooltip' )); seriesArray.push(series[i]); } } if (seriesArray.length > 0) { var polarData; var data; var params = []; for (var i = 0, l = seriesArray.length; i < l; i++) { polarData = seriesArray[i].data; for (var j = 0, k = polarData.length; j < k; j++) { data = polarData[j]; if (!_isSelected(data.name)) { continue; } data = typeof data != 'undefined' ? data : {name:'', value: {dataIndex:'-'}}; params.push([ seriesArray[i].name || '', data.name, data.value[dataIndex], indicatorName ]); } } if (params.length <= 0) { return; } if (typeof formatter == 'function') { _curTicket = 'axis:' + dataIndex; _tDom.innerHTML = formatter( params, _curTicket, _setContent ); } else if (typeof formatter == 'string') { formatter = formatter.replace('{a}','{a0}') .replace('{b}','{b0}') .replace('{c}','{c0}') .replace('{d}','{d0}'); for (var i = 0, l = params.length; i < l; i++) { formatter = formatter.replace( '{a' + i + '}', _encodeHTML(params[i][0]) ); formatter = formatter.replace( '{b' + i + '}', _encodeHTML(params[i][1]) ); formatter = formatter.replace( '{c' + i + '}', self.numAddCommas(params[i][2]) ); formatter = formatter.replace( '{d' + i + '}', _encodeHTML(params[i][3]) ); } _tDom.innerHTML = formatter; } else { formatter = _encodeHTML(params[0][1]) + '
' + _encodeHTML(params[0][3]) + ' : ' + self.numAddCommas(params[0][2]); for (var i = 1, l = params.length; i < l; i++) { formatter += '
' + _encodeHTML(params[i][1]) + '
'; formatter += _encodeHTML(params[i][3]) + ' : ' + self.numAddCommas(params[i][2]); } _tDom.innerHTML = formatter; } if (showContent === false || !option.tooltip.showContent) { // 只用tooltip的行为,不显示主体 return; } if (!self.hasAppend) { _tDom.style.left = _zrWidth / 2 + 'px'; _tDom.style.top = _zrHeight / 2 + 'px'; dom.firstChild.appendChild(_tDom); self.hasAppend = true; } _show( zrEvent.getX(_event), zrEvent.getY(_event), specialCssText ); return true; } } function _showItemTrigger() { var serie = ecData.get(_curTarget, 'series'); var data = ecData.get(_curTarget, 'data'); var name = ecData.get(_curTarget, 'name'); var value = ecData.get(_curTarget, 'value'); var special = ecData.get(_curTarget, 'special'); var special2 = ecData.get(_curTarget, 'special2'); // 从低优先级往上找到trigger为item的formatter和样式 var formatter; var showContent; var specialCssText = ''; var indicator; var html = ''; if (_curTarget._type != 'island') { // 全局 if (option.tooltip.trigger == 'item') { formatter = option.tooltip.formatter; } // 系列 if (self.query(serie, 'tooltip.trigger') == 'item') { showContent = self.query( serie, 'tooltip.showContent' ) || showContent; formatter = self.query( serie, 'tooltip.formatter' ) || formatter; specialCssText += _style(self.query( serie, 'tooltip' )); } // 数据项 showContent = self.query( data, 'tooltip.showContent' ) || showContent; formatter = self.query( data, 'tooltip.formatter' ) || formatter; specialCssText += _style(self.query(data, 'tooltip')); } else { showContent = self.deepQuery( [data, serie, option], 'tooltip.showContent' ); formatter = self.deepQuery( [data, serie, option], 'tooltip.islandFormatter' ); } if (typeof formatter == 'function') { _curTicket = (serie.name || '') + ':' + ecData.get(_curTarget, 'dataIndex'); _tDom.innerHTML = formatter( [ serie.name || '', name, value, special, special2 ], _curTicket, _setContent ); } else if (typeof formatter == 'string') { _curTicket = NaN; formatter = formatter.replace('{a}','{a0}') .replace('{b}','{b0}') .replace('{c}','{c0}'); formatter = formatter.replace( '{a0}', _encodeHTML(serie.name || '') ) .replace('{b0}', _encodeHTML(name)) .replace( '{c0}', value instanceof Array ? value : self.numAddCommas(value) ); formatter = formatter.replace('{d}','{d0}') .replace('{d0}', special || ''); formatter = formatter.replace('{e}','{e0}') .replace('{e0}', ecData.get(_curTarget, 'special2') || ''); _tDom.innerHTML = formatter; } else { _curTicket = NaN; if (serie.type == ecConfig.CHART_TYPE_SCATTER) { _tDom.innerHTML = (typeof serie.name != 'undefined' ? (_encodeHTML(serie.name) + '
') : '' ) + (name === '' ? '' : (_encodeHTML(name) + ' : ') ) + value + (typeof special == 'undefined' ? '' : (' (' + special + ')')); } else if (serie.type == ecConfig.CHART_TYPE_RADAR && special) { indicator = special; html += _encodeHTML( name === '' ? (serie.name || '') : name ); html += html === '' ? '' : '
'; for (var i = 0 ; i < indicator.length; i ++) { html += _encodeHTML(indicator[i].text) + ' : ' + self.numAddCommas(value[i]) + '
'; } _tDom.innerHTML = html; } else if (serie.type == ecConfig.CHART_TYPE_CHORD) { if (typeof special2 == 'undefined') { // 外环上 _tDom.innerHTML = _encodeHTML(name) + ' (' + self.numAddCommas(value) + ')'; } else { var name1 = _encodeHTML(name); var name2 = _encodeHTML(special); // 内部弦上 _tDom.innerHTML = (typeof serie.name != 'undefined' ? (_encodeHTML(serie.name) + '
') : '') + name1 + ' -> ' + name2 + ' (' + self.numAddCommas(value) + ')' + '
' + name2 + ' -> ' + name1 + ' (' + self.numAddCommas(special2) + ')'; } } else { _tDom.innerHTML = (typeof serie.name != 'undefined' ? (_encodeHTML(serie.name) + '
') : '') + _encodeHTML(name) + ' : ' + self.numAddCommas(value) + (typeof special == 'undefined' ? '' : (' ('+ self.numAddCommas(special) +')') ); } } if (!_axisLineShape.invisible) { _axisLineShape.invisible = true; zr.modShape(_axisLineShape.id, _axisLineShape); zr.refresh(); } if (showContent === false || !option.tooltip.showContent) { // 只用tooltip的行为,不显示主体 return; } if (!self.hasAppend) { _tDom.style.left = _zrWidth / 2 + 'px'; _tDom.style.top = _zrHeight / 2 + 'px'; dom.firstChild.appendChild(_tDom); self.hasAppend = true; } _show( zrEvent.getX(_event) + 20, zrEvent.getY(_event) - 20, specialCssText ); } /** * 设置坐标轴指示器样式 */ function _styleAxisPointer( seriesArray, xStart, yStart, xEnd, yEnd, gap ) { if (seriesArray.length > 0) { var queryTarget; var curType; var axisPointer = option.tooltip.axisPointer; var pointType = axisPointer.type; var lineColor = axisPointer.lineStyle.color; var lineWidth = axisPointer.lineStyle.width; var lineType = axisPointer.lineStyle.type; var areaSize = axisPointer.areaStyle.size; var areaColor = axisPointer.areaStyle.color; for (var i = 0, l = seriesArray.length; i < l; i++) { if (self.deepQuery( [seriesArray[i], option], 'tooltip.trigger' ) == 'axis' ) { queryTarget = seriesArray[i]; curType = self.query( queryTarget, 'tooltip.axisPointer.type' ); pointType = curType || pointType; if (curType == 'line') { lineColor = self.query( queryTarget, 'tooltip.axisPointer.lineStyle.color' ) || lineColor; lineWidth = self.query( queryTarget, 'tooltip.axisPointer.lineStyle.width' ) || lineWidth; lineType = self.query( queryTarget, 'tooltip.axisPointer.lineStyle.type' ) || lineType; } else if (curType == 'shadow') { areaSize = self.query( queryTarget, 'tooltip.axisPointer.areaStyle.size' ) || areaSize; areaColor = self.query( queryTarget, 'tooltip.axisPointer.areaStyle.color' ) || areaColor; } } } if (pointType == 'line') { _axisLineShape.style = { xStart : xStart, yStart : yStart, xEnd : xEnd, yEnd : yEnd, strokeColor : lineColor, lineWidth : lineWidth, lineType : lineType }; _axisLineShape.invisible = false; zr.modShape(_axisLineShape.id, _axisLineShape); } else if (pointType == 'shadow') { if (typeof areaSize == 'undefined' || areaSize == 'auto' || isNaN(areaSize) ) { lineWidth = gap; } else { lineWidth = areaSize; } if (xStart == xEnd) { // 纵向 if (Math.abs(grid.getX() - xStart) < 2) { // 最左边 lineWidth /= 2; xStart = xEnd = xEnd + lineWidth / 2; } else if (Math.abs(grid.getXend() - xStart) < 2) { // 最右边 lineWidth /= 2; xStart = xEnd = xEnd - lineWidth / 2; } } else if (yStart == yEnd) { // 横向 if (Math.abs(grid.getY() - yStart) < 2) { // 最上边 lineWidth /= 2; yStart = yEnd = yEnd + lineWidth / 2; } else if (Math.abs(grid.getYend() - yStart) < 2) { // 最右边 lineWidth /= 2; yStart = yEnd = yEnd - lineWidth / 2; } } _axisShadowShape.style = { xStart : xStart, yStart : yStart, xEnd : xEnd, yEnd : yEnd, strokeColor : areaColor, lineWidth : lineWidth }; _axisShadowShape.invisible = false; zr.modShape(_axisShadowShape.id, _axisShadowShape); } zr.refresh(); } } /** * zrender事件响应:鼠标移动 */ function _onmousemove(param) { clearTimeout(_hidingTicket); clearTimeout(_showingTicket); var target = param.target; var mx = zrEvent.getX(param.event); var my = zrEvent.getY(param.event); if (!target) { // 判断是否落到直角系里,axis触发的tooltip _curTarget = false; _event = param.event; _event._target = _event.target || _event.toElement; _event.zrenderX = mx; _event.zrenderY = my; if (_needAxisTrigger && grid && zrArea.isInside( rectangle, grid.getArea(), mx, my ) ) { _showingTicket = setTimeout(_tryShow, _showDelay); } else if (_needAxisTrigger && polar && polar.isInside([mx, my]) != -1 ) { _showingTicket = setTimeout(_tryShow, _showDelay); } else { !_event.connectTrigger && messageCenter.dispatch( ecConfig.EVENT.TOOLTIP_OUT_GRID, _event ); _hidingTicket = setTimeout(_hide, _hideDelay); } } else { _curTarget = target; _event = param.event; _event._target = _event.target || _event.toElement; _event.zrenderX = mx; _event.zrenderY = my; var polarIndex; if (_needAxisTrigger && polar && (polarIndex = polar.isInside([mx, my])) != -1 ) { // 看用这个polar的系列数据是否是axis触发,如果是设置_curTarget为nul var series = option.series; for (var i = 0, l = series.length; i < l; i++) { if (series[i].polarIndex == polarIndex && self.deepQuery( [series[i], option], 'tooltip.trigger' ) == 'axis' ) { _curTarget = null; break; } } } _showingTicket = setTimeout(_tryShow, _showDelay); } } /** * zrender事件响应:鼠标离开绘图区域 */ function _onglobalout() { clearTimeout(_hidingTicket); clearTimeout(_showingTicket); _hidingTicket = setTimeout(_hide, _hideDelay); } /** * 异步回调填充内容 */ function _setContent(ticket, content) { if (!_tDom) { return; } if (ticket == _curTicket) { _tDom.innerHTML = content; } setTimeout(_refixed, 20); } function setComponent() { component = myChart.component; grid = component.grid; xAxis = component.xAxis; yAxis = component.yAxis; polar = component.polar; } function ontooltipHover(param, tipShape) { if (!_lastTipShape // 不存在或者存在但dataIndex发生变化才需要重绘 || (_lastTipShape && _lastTipShape.dataIndex != param.dataIndex) ) { if (_lastTipShape && _lastTipShape.tipShape.length > 0) { zr.delShape(_lastTipShape.tipShape); } for (var i = 0, l = tipShape.length; i < l; i++) { tipShape[i].id = zr.newShapeId('tooltip'); tipShape[i].zlevel = _zlevelBase; tipShape[i].style = zrShapeBase.getHighlightStyle( tipShape[i].style, tipShape[i].highlightStyle ); tipShape[i].draggable = false; tipShape[i].hoverable = false; tipShape[i].clickable = false; tipShape[i].ondragend = null; tipShape[i].ondragover = null; tipShape[i].ondrop = null; zr.addShape(tipShape[i]); } _lastTipShape = { dataIndex : param.dataIndex, tipShape : tipShape }; } } function ondragend() { _hide(); } /** * 图例选择 */ function onlegendSelected(param) { _selectedMap = param.selected; } function _setSelectedMap() { if (option.legend && option.legend.selected) { _selectedMap = option.legend.selected; } else { _selectedMap = {}; } } function _isSelected(itemName) { if (typeof _selectedMap[itemName] != 'undefined') { return _selectedMap[itemName]; } else { return true; // 没在legend里定义的都为true啊~ } } /** * 模拟tooltip hover方法 * {object} params 参数 * {seriesIndex: 0, seriesName:'', dataInex:0} line、bar、scatter、k、radar * {seriesIndex: 0, seriesName:'', name:''} map、pie、chord */ function showTip(params) { if (!params) { return; } var seriesIndex; var series = option.series; if (typeof params.seriesIndex != 'undefined') { seriesIndex = params.seriesIndex; } else { var seriesName = params.seriesName; for (var i = 0, l = series.length; i < l; i++) { if (series[i].name == seriesName) { seriesIndex = i; break; } } } var serie = series[seriesIndex]; if (typeof serie == 'undefined') { return; } var chart = myChart.chart[serie.type]; var isAxisTrigger = self.deepQuery( [serie, option], 'tooltip.trigger' ) == 'axis'; if (!chart) { return; } if (isAxisTrigger) { // axis trigger var dataIndex = params.dataIndex; switch (chart.type) { case ecConfig.CHART_TYPE_LINE : case ecConfig.CHART_TYPE_BAR : case ecConfig.CHART_TYPE_K : if (typeof xAxis == 'undefined' || typeof yAxis == 'undefined' || serie.data.length <= dataIndex ) { return; } var xAxisIndex = serie.xAxisIndex || 0; var yAxisIndex = serie.yAxisIndex || 0; if (xAxis.getAxis(xAxisIndex).type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY ) { // 横轴是类目 _event = { zrenderX : xAxis.getAxis(xAxisIndex).getCoordByIndex(dataIndex), zrenderY : grid.getY() + (grid.getYend() - grid.getY()) / 4 }; } else { // 纵轴是类目 _event = { zrenderX : grid.getX() + (grid.getXend() - grid.getX()) / 4, zrenderY : yAxis.getAxis(yAxisIndex).getCoordByIndex(dataIndex) }; } _showAxisTrigger( xAxisIndex, yAxisIndex, dataIndex ); break; case ecConfig.CHART_TYPE_RADAR : if (typeof polar == 'undefined' || serie.data[0].value.length <= dataIndex ) { return; } var polarIndex = serie.polarIndex || 0; var vector = polar.getVector(polarIndex, dataIndex, 'max'); _event = { zrenderX : vector[0], zrenderY : vector[1] }; _showPolarTrigger( polarIndex, dataIndex ); break; } } else { // item trigger var shapeList = chart.shapeList; var x; var y; switch (chart.type) { case ecConfig.CHART_TYPE_LINE : case ecConfig.CHART_TYPE_BAR : case ecConfig.CHART_TYPE_K : case ecConfig.CHART_TYPE_SCATTER : var dataIndex = params.dataIndex; for (var i = 0, l = shapeList.length; i < l; i++) { if (ecData.get(shapeList[i], 'seriesIndex') == seriesIndex && ecData.get(shapeList[i], 'dataIndex') == dataIndex ) { _curTarget = shapeList[i]; x = shapeList[i].style.x; y = chart.type != ecConfig.CHART_TYPE_K ? shapeList[i].style.y : shapeList[i].style.y[0]; break; } } break; case ecConfig.CHART_TYPE_RADAR : var dataIndex = params.dataIndex; for (var i = 0, l = shapeList.length; i < l; i++) { if (shapeList[i].shape == 'polygon' && ecData.get(shapeList[i], 'seriesIndex') == seriesIndex && ecData.get(shapeList[i], 'dataIndex') == dataIndex ) { _curTarget = shapeList[i]; var vector = polar.getCenter(serie.polarIndex || 0); x = vector[0]; y = vector[1]; break; } } break; case ecConfig.CHART_TYPE_PIE : var name = params.name; for (var i = 0, l = shapeList.length; i < l; i++) { if (shapeList[i].shape == 'sector' && ecData.get(shapeList[i], 'seriesIndex') == seriesIndex && ecData.get(shapeList[i], 'name') == name ) { _curTarget = shapeList[i]; var style = _curTarget.style; var midAngle = (style.startAngle + style.endAngle) / 2 * Math.PI / 180; x = _curTarget.style.x + Math.cos(midAngle) * style.r / 1.5; y = _curTarget.style.y - Math.sin(midAngle) * style.r / 1.5; break; } } break; case ecConfig.CHART_TYPE_MAP : var name = params.name; var mapType = serie.mapType; for (var i = 0, l = shapeList.length; i < l; i++) { if (shapeList[i].shape == 'text' && shapeList[i]._mapType == mapType && shapeList[i].style._text == name ) { _curTarget = shapeList[i]; x = _curTarget.style.x + _curTarget.position[0]; y = _curTarget.style.y + _curTarget.position[1]; break; } } break; case ecConfig.CHART_TYPE_CHORD: var name = params.name; for (var i = 0, l = shapeList.length; i < l; i++) { if (shapeList[i].shape == 'sector' && ecData.get(shapeList[i], 'name') == name ) { _curTarget = shapeList[i]; var style = _curTarget.style; var midAngle = (style.startAngle + style.endAngle) / 2 * Math.PI / 180; x = _curTarget.style.x + Math.cos(midAngle) * (style.r - 2); y = _curTarget.style.y - Math.sin(midAngle) * (style.r - 2); zr.trigger( zrConfig.EVENT.MOUSEMOVE, { zrenderX : x, zrenderY : y } ); return; } } break; case ecConfig.CHART_TYPE_FORCE: var name = params.name; for (var i = 0, l = shapeList.length; i < l; i++) { if (shapeList[i].shape == 'circle' && ecData.get(shapeList[i], 'name') == name ) { _curTarget = shapeList[i]; x = _curTarget.position[0]; y = _curTarget.position[1]; break; } } break; } if (typeof x != 'undefined' && typeof y != 'undefined') { _event = { zrenderX : x, zrenderY : y }; zr.addHoverShape(_curTarget); zr.refreshHover(); _showItemTrigger(); } } } /** * 关闭,公开接口 */ function hideTip() { _hide(); } function init(newOption, newDom) { option = newOption; dom = newDom; option.tooltip = self.reformOption(option.tooltip); option.tooltip.textStyle = zrUtil.merge( option.tooltip.textStyle, ecConfig.textStyle, { 'overwrite': false, 'recursive': true } ); // 补全padding属性 option.tooltip.padding = self.reformCssArray( option.tooltip.padding ); _needAxisTrigger = false; if (option.tooltip.trigger == 'axis') { _needAxisTrigger = true; } var series = option.series; for (var i = 0, l = series.length; i < l; i++) { if (self.query(series[i], 'tooltip.trigger') == 'axis') { _needAxisTrigger = true; break; } } _showDelay = option.tooltip.showDelay; _hideDelay = option.tooltip.hideDelay; _defaultCssText = _style(option.tooltip); _tDom.style.position = 'absolute'; // 不是多余的,别删! self.hasAppend = false; _setSelectedMap(); _axisLineWidth = option.tooltip.axisPointer.lineStyle.width; } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; option.tooltip = self.reformOption(option.tooltip); option.tooltip.textStyle = zrUtil.merge( option.tooltip.textStyle, ecConfig.textStyle, { 'overwrite': false, 'recursive': true } ); // 补全padding属性 option.tooltip.padding = self.reformCssArray( option.tooltip.padding ); _setSelectedMap(); _axisLineWidth = option.tooltip.axisPointer.lineStyle.width; } } /** * zrender事件响应:窗口大小改变 */ function resize() { _zrHeight = zr.getHeight(); _zrWidth = zr.getWidth(); } /** * 释放后实例不可用,重载基类方法 */ function dispose() { clearTimeout(_hidingTicket); clearTimeout(_showingTicket); zr.un(zrConfig.EVENT.MOUSEMOVE, _onmousemove); zr.un(zrConfig.EVENT.GLOBALOUT, _onglobalout); if (self.hasAppend) { dom.firstChild.removeChild(_tDom); } _tDom = null; // self.clear(); self.shapeList = null; self = null; } /** * html转码的方法 */ function _encodeHTML(source) { return String(source) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } zr.on(zrConfig.EVENT.MOUSEMOVE, _onmousemove); zr.on(zrConfig.EVENT.GLOBALOUT, _onglobalout); // 重载基类方法 self.dispose = dispose; self.init = init; self.refresh = refresh; self.resize = resize; self.setComponent = setComponent; self.ontooltipHover = ontooltipHover; self.ondragend = ondragend; self.onlegendSelected = onlegendSelected; self.showTip = showTip; self.hideTip = hideTip; init(option, dom); } require('../component').define('tooltip', Tooltip); return Tooltip; }); /** * echarts组件:工具箱 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/toolbox',['require','./base','zrender/config','zrender/tool/util','zrender/tool/event','zrender/tool/env','../component','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {HtmlElement} dom 目标对象 * @param {ECharts} myChart 当前图表实例 */ function Toolbox(ecConfig, messageCenter, zr, dom, myChart) { var Base = require('./base'); Base.call(this, ecConfig, zr); var zrConfig = require('zrender/config'); var zrUtil = require('zrender/tool/util'); var zrEvent = require('zrender/tool/event'); var option; var component; var self = this; self.type = ecConfig.COMPONENT_TYPE_TOOLBOX; var _canvasSupported = require('zrender/tool/env').canvasSupported; var _zlevelBase = self.getZlevelBase(); var _magicType = {}; var _magicMap; var _isSilence = false; var _iconList; var _iconShapeMap = {}; var _itemGroupLocation; var _featureTitle = {}; // 文字 var _featureIcon = {}; // 图标 var _featureColor = {}; // 颜色 var _enableColor = 'red'; var _disableColor = '#ccc'; var _markStart; var _marking; var _markShape; var _zoomStart; var _zooming; var _zoomShape; var _zoomQueue; var _dataView; var _MAGICTYPE_STACK = 'stack'; var _MAGICTYPE_TILED = 'tiled'; function _buildShape() { _iconList = []; var feature = option.toolbox.feature; var iconName = []; for (var key in feature){ if (feature[key].show) { switch (key) { case 'mark' : iconName.push({key : key, name : 'mark'}); iconName.push({key : key, name : 'markUndo'}); iconName.push({key : key, name : 'markClear'}); break; case 'magicType' : for (var i = 0, l = feature[key].type.length; i < l; i++) { feature[key].title[feature[key].type[i] + 'Chart'] = feature[key].title[feature[key].type[i]]; iconName.push({key : key, name : feature[key].type[i] + 'Chart'}); } break; case 'dataZoom' : iconName.push({key : key, name : 'dataZoom'}); iconName.push({key : key, name : 'dataZoomReset'}); break; case 'saveAsImage' : if (_canvasSupported) { iconName.push({key : key, name : 'saveAsImage'}); } break; default : iconName.push({key : key, name : key}); break; } } } if (iconName.length > 0) { var name; var key; for (var i = 0, l = iconName.length; i < l; i++) { name = iconName[i].name; key = iconName[i].key; _iconList.push(name); _featureTitle[name] = feature[key].title[name] || feature[key].title; if (feature[key].icon) { _featureIcon[name] = feature[key].icon[name] || feature[key].icon; } if (feature[key].color) { _featureColor[name] = feature[key].color[name] || feature[key].color; } } _itemGroupLocation = _getItemGroupLocation(); _buildBackground(); _buildItem(); for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } if (_iconShapeMap['mark']) { _iconDisable(_iconShapeMap['markUndo']); _iconDisable(_iconShapeMap['markClear']); } if (_iconShapeMap['dataZoomReset'] && _zoomQueue.length === 0) { _iconDisable(_iconShapeMap['dataZoomReset']); } } } /** * 构建所有图例元素 */ function _buildItem() { var toolboxOption = option.toolbox; var iconLength = _iconList.length; var lastX = _itemGroupLocation.x; var lastY = _itemGroupLocation.y; var itemSize = toolboxOption.itemSize; var itemGap = toolboxOption.itemGap; var itemShape; var color = toolboxOption.color instanceof Array ? toolboxOption.color : [toolboxOption.color]; var textFont = self.getFont(toolboxOption.textStyle); var textPosition; var textAlign; var textBaseline; if (toolboxOption.orient == 'horizontal') { textPosition = _itemGroupLocation.y / zr.getHeight() < 0.5 ? 'bottom' : 'top'; textAlign = _itemGroupLocation.x / zr.getWidth() < 0.5 ? 'left' : 'right'; textBaseline = _itemGroupLocation.y / zr.getHeight() < 0.5 ? 'top' : 'bottom'; } else { textPosition = _itemGroupLocation.x / zr.getWidth() < 0.5 ? 'right' : 'left'; /* textAlign = _itemGroupLocation.x / zr.getWidth() < 0.5 ? 'right' : 'left'; textBaseline = 'top'; */ } _iconShapeMap = {}; for (var i = 0; i < iconLength; i++) { // 图形 itemShape = { shape : 'icon', zlevel : _zlevelBase, style : { x : lastX, y : lastY, width : itemSize, height : itemSize, iconType : _iconList[i], lineWidth : 1, strokeColor : _featureColor[_iconList[i]] || color[i % color.length], brushType: 'stroke' }, highlightStyle : { lineWidth : 2, text : toolboxOption.showTitle ? _featureTitle[_iconList[i]] : false, textFont : textFont, textPosition : textPosition, strokeColor : _featureColor[_iconList[i]] || color[i % color.length] }, hoverable : true, clickable : true }; if (_featureIcon[_iconList[i]]) { itemShape.style.image = _featureIcon[_iconList[i]].replace( new RegExp('^image:\\/\\/'), '' ); itemShape.style.opacity = 0.8; itemShape.highlightStyle.opacity = 1; itemShape.shape = 'image'; } if (toolboxOption.orient == 'horizontal') { // 修正左对齐第一个或右对齐最后一个 if (i === 0 && textAlign == 'left') { itemShape.highlightStyle.textPosition = 'specific'; itemShape.highlightStyle.textAlign = textAlign; itemShape.highlightStyle.textBaseline = textBaseline; itemShape.highlightStyle.textX = lastX; itemShape.highlightStyle.textY = textBaseline == 'top' ? lastY + itemSize + 10 : lastY - 10; } if (i == iconLength - 1 && textAlign == 'right') { itemShape.highlightStyle.textPosition = 'specific'; itemShape.highlightStyle.textAlign = textAlign; itemShape.highlightStyle.textBaseline = textBaseline; itemShape.highlightStyle.textX = lastX + itemSize; itemShape.highlightStyle.textY = textBaseline == 'top' ? lastY + itemSize + 10 : lastY - 10; } } switch(_iconList[i]) { case 'mark': itemShape.onclick = _onMark; break; case 'markUndo': itemShape.onclick = _onMarkUndo; break; case 'markClear': itemShape.onclick = _onMarkClear; break; case 'dataZoom': itemShape.onclick = _onDataZoom; break; case 'dataZoomReset': itemShape.onclick = _onDataZoomReset; break; case 'dataView' : if (!_dataView) { var componentLibrary = require('../component'); var DataView = componentLibrary.get('dataView'); _dataView = new DataView( ecConfig, messageCenter, zr, option, dom ); } itemShape.onclick = _onDataView; break; case 'restore': itemShape.onclick = _onRestore; break; case 'saveAsImage': itemShape.onclick = _onSaveAsImage; break; default: if (_iconList[i].match('Chart')) { itemShape._name = _iconList[i].replace('Chart', ''); if (_magicType[itemShape._name]) { itemShape.style.strokeColor = _enableColor; } itemShape.onclick = _onMagicType; } else { itemShape.onclick = _onCustomHandler; } break; } self.shapeList.push(itemShape); _iconShapeMap[_iconList[i]] = itemShape; if (toolboxOption.orient == 'horizontal') { lastX += itemSize + itemGap; } else { lastY += itemSize + itemGap; } } } function _buildBackground() { var toolboxOption = option.toolbox; var pTop = toolboxOption.padding[0]; var pRight = toolboxOption.padding[1]; var pBottom = toolboxOption.padding[2]; var pLeft = toolboxOption.padding[3]; self.shapeList.push({ shape : 'rectangle', zlevel : _zlevelBase, hoverable :false, style : { x : _itemGroupLocation.x - pLeft, y : _itemGroupLocation.y - pTop, width : _itemGroupLocation.width + pLeft + pRight, height : _itemGroupLocation.height + pTop + pBottom, brushType : toolboxOption.borderWidth === 0 ? 'fill' : 'both', color : toolboxOption.backgroundColor, strokeColor : toolboxOption.borderColor, lineWidth : toolboxOption.borderWidth } }); } /** * 根据选项计算图例实体的位置坐标 */ function _getItemGroupLocation() { var toolboxOption = option.toolbox; var iconLength = _iconList.length; var itemGap = toolboxOption.itemGap; var itemSize = toolboxOption.itemSize; var totalWidth = 0; var totalHeight = 0; if (toolboxOption.orient == 'horizontal') { // 水平布局,计算总宽度,别忘减去最后一个的itemGap totalWidth = (itemSize + itemGap) * iconLength - itemGap; totalHeight = itemSize; } else { // 垂直布局,计算总高度 totalHeight = (itemSize + itemGap) * iconLength - itemGap; totalWidth = itemSize; } var x; var zrWidth = zr.getWidth(); switch (toolboxOption.x) { case 'center' : x = Math.floor((zrWidth - totalWidth) / 2); break; case 'left' : x = toolboxOption.padding[3] + toolboxOption.borderWidth; break; case 'right' : x = zrWidth - totalWidth - toolboxOption.padding[1] - toolboxOption.borderWidth; break; default : x = toolboxOption.x - 0; x = isNaN(x) ? 0 : x; break; } var y; var zrHeight = zr.getHeight(); switch (toolboxOption.y) { case 'top' : y = toolboxOption.padding[0] + toolboxOption.borderWidth; break; case 'bottom' : y = zrHeight - totalHeight - toolboxOption.padding[2] - toolboxOption.borderWidth; break; case 'center' : y = Math.floor((zrHeight - totalHeight) / 2); break; default : y = toolboxOption.y - 0; y = isNaN(y) ? 0 : y; break; } return { x : x, y : y, width : totalWidth, height : totalHeight }; } function _onMark(param) { var target = param.target; if (_marking || _markStart) { // 取消 _resetMark(); zr.refresh(); } else { // 启用Mark _resetZoom(); // mark与dataZoom互斥 zr.modShape(target.id, {style: {strokeColor: _enableColor}}); zr.refresh(); _markStart = true; setTimeout(function(){ zr && zr.on(zrConfig.EVENT.CLICK, _onclick) && zr.on(zrConfig.EVENT.MOUSEMOVE, _onmousemove); }, 10); } return true; // 阻塞全局事件 } function _onDataZoom(param) { var target = param.target; if (_zooming || _zoomStart) { // 取消 _resetZoom(); zr.refresh(); dom.style.cursor = 'default'; } else { // 启用Zoom _resetMark(); // mark与dataZoom互斥 zr.modShape(target.id, {style: {strokeColor: _enableColor}}); zr.refresh(); _zoomStart = true; setTimeout(function(){ zr && zr.on(zrConfig.EVENT.MOUSEDOWN, _onmousedown) && zr.on(zrConfig.EVENT.MOUSEUP, _onmouseup) && zr.on(zrConfig.EVENT.MOUSEMOVE, _onmousemove); }, 10); dom.style.cursor = 'crosshair'; } return true; // 阻塞全局事件 } function _onmousemove(param) { if (_marking) { _markShape.style.xEnd = zrEvent.getX(param.event); _markShape.style.yEnd = zrEvent.getY(param.event); zr.addHoverShape(_markShape); } if (_zooming) { _zoomShape.style.width = zrEvent.getX(param.event) - _zoomShape.style.x; _zoomShape.style.height = zrEvent.getY(param.event) - _zoomShape.style.y; zr.addHoverShape(_zoomShape); dom.style.cursor = 'crosshair'; } if (_zoomStart && (dom.style.cursor != 'pointer' && dom.style.cursor != 'move') ) { dom.style.cursor = 'crosshair'; } } function _onmousedown(param) { if (param.target) { return; } _zooming = true; var x = zrEvent.getX(param.event); var y = zrEvent.getY(param.event); var zoomOption = option.dataZoom || {}; _zoomShape = { shape : 'rectangle', id : zr.newShapeId('zoom'), zlevel : _zlevelBase, style : { x : x, y : y, width : 1, height : 1, brushType: 'both' }, highlightStyle : { lineWidth : 2, color: zoomOption.fillerColor || ecConfig.dataZoom.fillerColor, strokeColor : zoomOption.handleColor || ecConfig.dataZoom.handleColor, brushType: 'both' } }; zr.addHoverShape(_zoomShape); return true; // 阻塞全局事件 } function _onmouseup(/*param*/) { if (!_zoomShape || Math.abs(_zoomShape.style.width) < 10 || Math.abs(_zoomShape.style.height) < 10 ) { _zooming = false; return true; } if (_zooming && component.dataZoom) { _zooming = false; var zoom = component.dataZoom.rectZoom(_zoomShape.style); if (zoom) { _zoomQueue.push({ start : zoom.start, end : zoom.end, start2 : zoom.start2, end2 : zoom.end2 }); _iconEnable(_iconShapeMap['dataZoomReset']); zr.refresh(); } } return true; // 阻塞全局事件 } function _onclick(param) { if (_marking) { _marking = false; self.shapeList.push(_markShape); _iconEnable(_iconShapeMap['markUndo']); _iconEnable(_iconShapeMap['markClear']); zr.addShape(_markShape); zr.refresh(); } else if (_markStart) { _marking = true; var x = zrEvent.getX(param.event); var y = zrEvent.getY(param.event); _markShape = { shape : 'line', id : zr.newShapeId('mark'), zlevel : _zlevelBase, style : { xStart : x, yStart : y, xEnd : x, yEnd : y, lineWidth : self.query( option, 'toolbox.feature.mark.lineStyle.width' ), strokeColor : self.query( option, 'toolbox.feature.mark.lineStyle.color' ), lineType : self.query( option, 'toolbox.feature.mark.lineStyle.type' ) } }; zr.addHoverShape(_markShape); } } function _onMarkUndo() { if (_marking) { _marking = false; } else { var len = self.shapeList.length - 1; // 有一个是背景shape if (_iconList.length == len - 1) { _iconDisable(_iconShapeMap['markUndo']); _iconDisable(_iconShapeMap['markClear']); } if (_iconList.length < len) { var target = self.shapeList[self.shapeList.length - 1]; zr.delShape(target.id); zr.refresh(); self.shapeList.pop(); } } return true; } function _onMarkClear() { if (_marking) { _marking = false; } // 有一个是背景shape var len = self.shapeList.length - _iconList.length - 1; var hasClear = false; while(len--) { zr.delShape(self.shapeList.pop().id); hasClear = true; } if (hasClear) { _iconDisable(_iconShapeMap['markUndo']); _iconDisable(_iconShapeMap['markClear']); zr.refresh(); } return true; } function _onDataZoomReset() { if (_zooming) { _zooming = false; } _zoomQueue.pop(); //console.log(_zoomQueue) if (_zoomQueue.length > 0) { component.dataZoom.absoluteZoom( _zoomQueue[_zoomQueue.length - 1] ); } else { component.dataZoom.rectZoom(); _iconDisable(_iconShapeMap['dataZoomReset']); zr.refresh(); } return true; } function _resetMark() { _marking = false; if (_markStart) { _markStart = false; if (_iconShapeMap['mark']) { // 还原图标为未生效状态 zr.modShape( _iconShapeMap['mark'].id, { style: { strokeColor: _iconShapeMap['mark'] .highlightStyle .strokeColor } } ); } zr.un(zrConfig.EVENT.CLICK, _onclick); zr.un(zrConfig.EVENT.MOUSEMOVE, _onmousemove); } } function _resetZoom() { _zooming = false; if (_zoomStart) { _zoomStart = false; if (_iconShapeMap['dataZoom']) { // 还原图标为未生效状态 zr.modShape( _iconShapeMap['dataZoom'].id, { style: { strokeColor: _iconShapeMap['dataZoom'] .highlightStyle .strokeColor } } ); } zr.un(zrConfig.EVENT.MOUSEDOWN, _onmousedown); zr.un(zrConfig.EVENT.MOUSEUP, _onmouseup); zr.un(zrConfig.EVENT.MOUSEMOVE, _onmousemove); } } function _iconDisable(target) { if (target.shape != 'image') { zr.modShape(target.id, { hoverable : false, clickable : false, style : { strokeColor : _disableColor } }); } else { zr.modShape(target.id, { hoverable : false, clickable : false, style : { opacity : 0.3 } }); } } function _iconEnable(target) { if (target.shape != 'image') { zr.modShape(target.id, { hoverable : true, clickable : true, style : { strokeColor : target.highlightStyle.strokeColor } }); } else { zr.modShape(target.id, { hoverable : true, clickable : true, style : { opacity : 0.8 } }); } } function _onDataView() { _dataView.show(option); return true; } function _onRestore(){ _resetMark(); _resetZoom(); messageCenter.dispatch(ecConfig.EVENT.RESTORE); return true; } function _onSaveAsImage() { var saveOption = option.toolbox.feature.saveAsImage; var imgType = saveOption.type || 'png'; if (imgType != 'png' && imgType != 'jpeg') { imgType = 'png'; } var image; if (!myChart.isConnected()) { image = zr.toDataURL( 'image/' + imgType, option.backgroundColor && option.backgroundColor.replace(' ','') == 'rgba(0,0,0,0)' ? '#fff' : option.backgroundColor ); } else { image = myChart.getConnectedDataURL(imgType); } var downloadDiv = document.createElement('div'); downloadDiv.id = '__echarts_download_wrap__'; downloadDiv.style.cssText = 'position:fixed;' + 'z-index:99999;' + 'display:block;' + 'top:0;left:0;' + 'background-color:rgba(33,33,33,0.5);' + 'text-align:center;' + 'width:100%;' + 'height:100%;' + 'line-height:' + document.documentElement.clientHeight + 'px;'; var downloadLink = document.createElement('a'); //downloadLink.onclick = _saveImageForIE; downloadLink.href = image; downloadLink.setAttribute( 'download', (saveOption.name ? saveOption.name : (option.title && (option.title.text || option.title.subtext)) ? (option.title.text || option.title.subtext) : 'ECharts') + '.' + imgType ); downloadLink.innerHTML = ''; downloadDiv.appendChild(downloadLink); document.body.appendChild(downloadDiv); downloadLink = null; downloadDiv = null; setTimeout(function(){ var _d = document.getElementById('__echarts_download_wrap__'); if (_d) { _d.onclick = function () { var d = document.getElementById( '__echarts_download_wrap__' ); d.onclick = null; d.innerHTML = ''; document.body.removeChild(d); d = null; }; _d = null; } }, 500); /* function _saveImageForIE() { window.win = window.open(image); win.document.execCommand("SaveAs"); win.close() } */ return; } function _onMagicType(param) { _resetMark(); var itemName = param.target._name; if (_magicType[itemName]) { // 取消 _magicType[itemName] = false; } else { // 启用 _magicType[itemName] = true; // 折柱互斥 if (itemName == ecConfig.CHART_TYPE_LINE) { _magicType[ecConfig.CHART_TYPE_BAR] = false; } else if (itemName == ecConfig.CHART_TYPE_BAR) { _magicType[ecConfig.CHART_TYPE_LINE] = false; } // 堆叠平铺互斥 if (itemName == _MAGICTYPE_STACK) { _magicType[_MAGICTYPE_TILED] = false; } else if (itemName == _MAGICTYPE_TILED) { _magicType[_MAGICTYPE_STACK] = false; } } messageCenter.dispatch( ecConfig.EVENT.MAGIC_TYPE_CHANGED, param.event, {magicType : _magicType} ); return true; } function setMagicType(magicType) { _resetMark(); _magicType = magicType; !_isSilence && messageCenter.dispatch( ecConfig.EVENT.MAGIC_TYPE_CHANGED, null, {magicType : _magicType} ); } // 用户自定义扩展toolbox方法 function _onCustomHandler(param) { var target = param.target.style.iconType; var featureHandler = option.toolbox.feature[target].onclick; if (typeof featureHandler === 'function') { featureHandler(option); } } // 重置备份还原状态等 function reset(newOption) { if (self.query(newOption, 'toolbox.show') && self.query(newOption, 'toolbox.feature.magicType.show') ) { var magicType = newOption.toolbox.feature.magicType.type; var len = magicType.length; _magicMap = {}; // 标识可控类型 while (len--) { _magicMap[magicType[len]] = true; } len = newOption.series.length; var oriType; // 备份还原可控类型 var axis; while (len--) { oriType = newOption.series[len].type; if (_magicMap[oriType]) { axis = newOption.xAxis instanceof Array ? newOption.xAxis[ newOption.series[len].xAxisIndex || 0 ] : newOption.xAxis; if (axis && (axis.type || 'category') == 'category') { axis.__boundaryGap = typeof axis.boundaryGap != 'undefined' ? axis.boundaryGap : true; } axis = newOption.yAxis instanceof Array ? newOption.yAxis[ newOption.series[len].yAxisIndex || 0 ] : newOption.yAxis; if (axis && axis.type == 'category') { axis.__boundaryGap = typeof axis.boundaryGap != 'undefined' ? axis.boundaryGap : true; } newOption.series[len].__type = oriType; // 避免不同类型图表类型的样式污染 newOption.series[len].__itemStyle = newOption.series[len].itemStyle ? zrUtil.clone( newOption.series[len].itemStyle ) : {}; } if (_magicMap[_MAGICTYPE_STACK] || _magicMap[_MAGICTYPE_TILED]) { newOption.series[len].__stack = newOption.series[len].stack; } } } _magicType = {}; // 框选缩放 var zoomOption = newOption.dataZoom; if (zoomOption && zoomOption.show) { var start = typeof zoomOption.start != 'undefined' && zoomOption.start >= 0 && zoomOption.start <= 100 ? zoomOption.start : 0; var end = typeof zoomOption.end != 'undefined' && zoomOption.end >= 0 && zoomOption.end <= 100 ? zoomOption.end : 100; if (start > end) { // 大小颠倒自动翻转 start = start + end; end = start - end; start = start - end; } _zoomQueue = [{ start : start, end : end, start2 : 0, end2 : 100 }]; } else { _zoomQueue = []; } } function getMagicOption(){ var axis; if (_magicType[ecConfig.CHART_TYPE_LINE] || _magicType[ecConfig.CHART_TYPE_BAR]) { // 图表类型有切换 var boundaryGap = _magicType[ecConfig.CHART_TYPE_LINE] ? false : true; for (var i = 0, l = option.series.length; i < l; i++) { if (_magicMap[option.series[i].type]) { option.series[i].type = _magicType[ecConfig.CHART_TYPE_LINE] ? ecConfig.CHART_TYPE_LINE : ecConfig.CHART_TYPE_BAR; // 避免不同类型图表类型的样式污染 option.series[i].itemStyle = zrUtil.clone( option.series[i].__itemStyle ); axis = option.xAxis instanceof Array ? option.xAxis[option.series[i].xAxisIndex || 0] : option.xAxis; if (axis && (axis.type || 'category') == 'category') { axis.boundaryGap = boundaryGap ? true : axis.__boundaryGap; } axis = option.yAxis instanceof Array ? option.yAxis[option.series[i].yAxisIndex || 0] : option.yAxis; if (axis && axis.type == 'category') { axis.boundaryGap = boundaryGap ? true : axis.__boundaryGap; } } } } else { // 图表类型无切换 for (var i = 0, l = option.series.length; i < l; i++) { if (_magicMap[option.series[i].type]) { option.series[i].type = option.series[i].__type; // 避免不同类型图表类型的样式污染 option.series[i].itemStyle = option.series[i].__itemStyle; axis = option.xAxis instanceof Array ? option.xAxis[option.series[i].xAxisIndex || 0] : option.xAxis; if (axis && (axis.type || 'category') == 'category') { axis.boundaryGap = axis.__boundaryGap; } axis = option.yAxis instanceof Array ? option.yAxis[option.series[i].yAxisIndex || 0] : option.yAxis; if (axis && axis.type == 'category') { axis.boundaryGap = axis.__boundaryGap; } } } } if (_magicType[_MAGICTYPE_STACK] || _magicType[_MAGICTYPE_TILED]) { // 有堆叠平铺切换 for (var i = 0, l = option.series.length; i < l; i++) { if (_magicType[_MAGICTYPE_STACK]) { // 启用堆叠 option.series[i].stack = '_ECHARTS_STACK_KENER_2014_'; } else if (_magicType[_MAGICTYPE_TILED]) { // 启用平铺 option.series[i].stack = null; } } } else { // 无堆叠平铺切换 for (var i = 0, l = option.series.length; i < l; i++) { option.series[i].stack = option.series[i].__stack; } } return option; } function silence(s) { _isSilence = s; } function render(newOption, newComponent){ _resetMark(); _resetZoom(); newOption.toolbox = self.reformOption(newOption.toolbox); // 补全padding属性 newOption.toolbox.padding = self.reformCssArray( newOption.toolbox.padding ); option = newOption; component = newComponent; self.shapeList = []; if (newOption.toolbox.show) { _buildShape(); } hideDataView(); } function resize() { _resetMark(); self.clear(); if (option && option.toolbox && option.toolbox.show) { _buildShape(); } if (_dataView) { _dataView.resize(); } } function hideDataView() { if (_dataView) { _dataView.hide(); } } /** * 释放后实例不可用 */ function dispose() { if (_dataView) { _dataView.dispose(); _dataView = null; } self.clear(); self.shapeList = null; self = null; } /** * 刷新 */ function refresh(newOption) { if (newOption) { newOption.toolbox = self.reformOption(newOption.toolbox); // 补全padding属性 newOption.toolbox.padding = self.reformCssArray( newOption.toolbox.padding ); option = newOption; } } // 重载基类方法 self.dispose = dispose; self.render = render; self.resize = resize; self.hideDataView = hideDataView; self.getMagicOption = getMagicOption; self.silence = silence; self.setMagicType = setMagicType; self.reset = reset; self.refresh = refresh; } require('../component').define('toolbox', Toolbox); return Toolbox; }); /** * echarts组件:提示框 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/component/dataView',['require','./base','zrender/tool/env','../component'],function (require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 提示框参数 * @param {HtmlElement} dom 目标对象 */ function DataView(ecConfig, messageCenter, zr, option, dom) { var Base = require('./base'); Base.call(this, ecConfig, zr); var self = this; self.type = ecConfig.COMPONENT_TYPE_DATAVIEW; var _lang = ['Data View', 'close', 'refresh']; var _canvasSupported = require('zrender/tool/env').canvasSupported; // dataview dom & css var _tDom = document.createElement('div'); var _textArea = document.createElement('textArea'); var _buttonRefresh = document.createElement('button'); var _buttonClose = document.createElement('button'); var _hasShow = false; // 通用样式 var _gCssText = 'position:absolute;' + 'display:block;' + 'overflow:hidden;' + 'transition:height 0.8s,background-color 1s;' + '-moz-transition:height 0.8s,background-color 1s;' + '-webkit-transition:height 0.8s,background-color 1s;' + '-o-transition:height 0.8s,background-color 1s;' + 'z-index:1;' + 'left:0;' + 'top:0;'; var _sizeCssText; var _cssName = 'echarts-dataview'; // 缓存一些高宽数据 var _zrHeight = zr.getHeight(); var _zrWidth = zr.getWidth(); function hide() { _sizeCssText = 'width:' + _zrWidth + 'px;' + 'height:' + 0 + 'px;' + 'background-color:#f0ffff;'; _tDom.style.cssText = _gCssText + _sizeCssText; // 这是个很恶心的事情 dom.onselectstart = function() { return false; }; } function show(newOption) { _hasShow = true; var lang = self.query(option, 'toolbox.feature.dataView.lang') || _lang; option = newOption; _tDom.innerHTML = '

' + (lang[0] || _lang[0]) + '

'; _textArea.style.cssText = 'display:block;margin:0 0 8px 0;padding:4px 6px;overflow:auto;' + 'width:' + (_zrWidth - 15) + 'px;' + 'height:' + (_zrHeight - 100) + 'px;'; var customContent = self.query( option, 'toolbox.feature.dataView.optionToContent' ); if (typeof customContent != 'function') { _textArea.value = _optionToContent(); } else { _textArea.value = customContent(option); } _tDom.appendChild(_textArea); _buttonClose.style.cssText = 'float:right;padding:1px 6px;'; _buttonClose.innerHTML = lang[1] || _lang[1]; _buttonClose.onclick = hide; _tDom.appendChild(_buttonClose); if (self.query(option, 'toolbox.feature.dataView.readOnly') === false ) { _buttonRefresh.style.cssText = 'float:right;margin-right:10px;padding:1px 6px;'; _buttonRefresh.innerHTML = lang[2] || _lang[2]; _buttonRefresh.onclick = _save; _tDom.appendChild(_buttonRefresh); _textArea.readOnly = false; _textArea.style.cursor = 'default'; } else { _textArea.readOnly = true; _textArea.style.cursor = 'text'; } _sizeCssText = 'width:' + _zrWidth + 'px;' + 'height:' + _zrHeight + 'px;' + 'background-color:#fff;'; _tDom.style.cssText = _gCssText + _sizeCssText; // 这是个很恶心的事情 dom.onselectstart = function() { return true; }; } function _optionToContent() { var i; var j; var k; var len; var data; var valueList; var axisList = []; var content = ''; if (option.xAxis) { if (option.xAxis instanceof Array) { axisList = option.xAxis; } else { axisList = [option.xAxis]; } for (i = 0, len = axisList.length; i < len; i++) { // 横纵默认为类目 if ((axisList[i].type || 'category') == 'category') { valueList = []; for (j = 0, k = axisList[i].data.length; j < k; j++) { data = axisList[i].data[j]; valueList.push( typeof data.value != 'undefined' ? data.value : data ); } content += valueList.join(', ') + '\n\n'; } } } if (option.yAxis) { if (option.yAxis instanceof Array) { axisList = option.yAxis; } else { axisList = [option.yAxis]; } for (i = 0, len = axisList.length; i < len; i++) { if (axisList[i].type == 'category') { valueList = []; for (j = 0, k = axisList[i].data.length; j < k; j++) { data = axisList[i].data[j]; valueList.push( typeof data.value != 'undefined' ? data.value : data ); } content += valueList.join(', ') + '\n\n'; } } } var series = option.series; var itemName; for (i = 0, len = series.length; i < len; i++) { valueList = []; for (j = 0, k = series[i].data.length; j < k; j++) { data = series[i].data[j]; if (series[i].type == ecConfig.CHART_TYPE_PIE || series[i].type == ecConfig.CHART_TYPE_MAP ) { itemName = (data.name || '-') + ':'; } else { itemName = ''; } if (series[i].type == ecConfig.CHART_TYPE_SCATTER) { data = typeof data.value != 'undefined' ? data.value : data; data = data.join(', '); } valueList.push( itemName + (typeof data.value != 'undefined' ? data.value : data) ); } content += (series[i].name || '-') + ' : \n'; content += valueList.join( series[i].type == ecConfig.CHART_TYPE_SCATTER ? '\n': ', ' ); content += '\n\n'; } return content; } function _save() { var text = _textArea.value; var customContent = self.query( option, 'toolbox.feature.dataView.contentToOption' ); if (typeof customContent != 'function') { text = text.split('\n'); var content = []; for (var i = 0, l = text.length; i < l; i++) { text[i] = _trim(text[i]); if (text[i] !== '') { content.push(text[i]); } } _contentToOption(content); } else { customContent(text, option); } hide(); setTimeout( function(){ messageCenter && messageCenter.dispatch( ecConfig.EVENT.DATA_VIEW_CHANGED, null, {option : option} ); }, // 有动画,所以高级浏览器时间更长点 _canvasSupported ? 800 : 100 ); } function _contentToOption(content) { var i; var j; var k; var len; var data; var axisList = []; var contentIdx = 0; var contentValueList; var value; if (option.xAxis) { if (option.xAxis instanceof Array) { axisList = option.xAxis; } else { axisList = [option.xAxis]; } for (i = 0, len = axisList.length; i < len; i++) { // 横纵默认为类目 if ((axisList[i].type || 'category') == 'category' ) { contentValueList = content[contentIdx].split(','); for (j = 0, k = axisList[i].data.length; j < k; j++) { value = _trim(contentValueList[j] || ''); data = axisList[i].data[j]; if (typeof axisList[i].data[j].value != 'undefined' ) { axisList[i].data[j].value = value; } else { axisList[i].data[j] = value; } } contentIdx++; } } } if (option.yAxis) { if (option.yAxis instanceof Array) { axisList = option.yAxis; } else { axisList = [option.yAxis]; } for (i = 0, len = axisList.length; i < len; i++) { if (axisList[i].type == 'category') { contentValueList = content[contentIdx].split(','); for (j = 0, k = axisList[i].data.length; j < k; j++) { value = _trim(contentValueList[j] || ''); data = axisList[i].data[j]; if (typeof axisList[i].data[j].value != 'undefined' ) { axisList[i].data[j].value = value; } else { axisList[i].data[j] = value; } } contentIdx++; } } } var series = option.series; for (i = 0, len = series.length; i < len; i++) { contentIdx++; if (series[i].type == ecConfig.CHART_TYPE_SCATTER) { for (var j = 0, k = series[i].data.length; j < k; j++) { contentValueList = content[contentIdx]; value = contentValueList.replace(' ','').split(','); if (typeof series[i].data[j].value != 'undefined' ) { series[i].data[j].value = value; } else { series[i].data[j] = value; } contentIdx++; } } else { contentValueList = content[contentIdx].split(','); for (var j = 0, k = series[i].data.length; j < k; j++) { value = (contentValueList[j] || '').replace(/.*:/,''); value = _trim(value); value = (value != '-' && value !== '') ? (value - 0) : '-'; if (typeof series[i].data[j].value != 'undefined' ) { series[i].data[j].value = value; } else { series[i].data[j] = value; } } contentIdx++; } } } function _trim(str){ var trimer = new RegExp( '(^[\\s\\t\\xa0\\u3000]+)|([\\u3000\\xa0\\s\\t]+\x24)', 'g' ); return str.replace(trimer, ''); } // 阻塞zrender事件 function _stop(e){ e = e || window.event; if (e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; } } function _init() { _tDom.className = _cssName; hide(); dom.firstChild.appendChild(_tDom); if (window.addEventListener) { _tDom.addEventListener('click', _stop); _tDom.addEventListener('mousewheel', _stop); _tDom.addEventListener('mousemove', _stop); _tDom.addEventListener('mousedown', _stop); _tDom.addEventListener('mouseup', _stop); // mobile支持 _tDom.addEventListener('touchstart', _stop); _tDom.addEventListener('touchmove', _stop); _tDom.addEventListener('touchend', _stop); } else { _tDom.attachEvent('onclick', _stop); _tDom.attachEvent('onmousewheel', _stop); _tDom.attachEvent('onmousemove', _stop); _tDom.attachEvent('onmousedown', _stop); _tDom.attachEvent('onmouseup', _stop); } } /** * zrender事件响应:窗口大小改变 */ function resize() { _zrHeight = zr.getHeight(); _zrWidth = zr.getWidth(); if (_tDom.offsetHeight > 10) { _sizeCssText = 'width:' + _zrWidth + 'px;' + 'height:' + _zrHeight + 'px;' + 'background-color:#fff;'; _tDom.style.cssText = _gCssText + _sizeCssText; _textArea.style.cssText = 'display:block;margin:0 0 8px 0;' + 'padding:4px 6px;overflow:auto;' + 'width:' + (_zrWidth - 15) + 'px;' + 'height:' + (_zrHeight - 100) + 'px;'; } } /** * 释放后实例不可用,重载基类方法 */ function dispose() { if (window.removeEventListener) { _tDom.removeEventListener('click', _stop); _tDom.removeEventListener('mousewheel', _stop); _tDom.removeEventListener('mousemove', _stop); _tDom.removeEventListener('mousedown', _stop); _tDom.removeEventListener('mouseup', _stop); // mobile支持 _tDom.removeEventListener('touchstart', _stop); _tDom.removeEventListener('touchmove', _stop); _tDom.removeEventListener('touchend', _stop); } else { _tDom.detachEvent('onclick', _stop); _tDom.detachEvent('onmousewheel', _stop); _tDom.detachEvent('onmousemove', _stop); _tDom.detachEvent('onmousedown', _stop); _tDom.detachEvent('onmouseup', _stop); } _buttonRefresh.onclick = null; _buttonClose.onclick = null; if (_hasShow) { _tDom.removeChild(_textArea); _tDom.removeChild(_buttonRefresh); _tDom.removeChild(_buttonClose); } _textArea = null; _buttonRefresh = null; _buttonClose = null; dom.firstChild.removeChild(_tDom); _tDom = null; self = null; } // 重载基类方法 self.dispose = dispose; self.resize = resize; self.show = show; self.hide = hide; _init(); } require('../component').define('dataView', DataView); return DataView; }); /** * echarts坐标处理方法 * * @author Neil (杨骥, yangji01@baidu.com) */ define( 'echarts/util/coordinates',['require','zrender/tool/math'],function(require) { var zrMath = require('zrender/tool/math'); /** * 极坐标转直角坐标 * * @param {number} 半径 * @param {number} 角度 * * @return {Array.} 直角坐标[x,y] */ function polar2cartesian(r, theta) { return [r * zrMath.sin(theta), r*zrMath.cos(theta)]; } /** * 直角坐标转极坐标 * * @param {number} 横坐标 * @param {number} 纵坐标 * * @return {Array.} 极坐标[r,theta] */ function cartesian2polar(x, y) { return [Math.sqrt(x * x + y * y), Math.atan(y / x)]; } return { polar2cartesian : polar2cartesian, cartesian2polar : cartesian2polar }; } ); /** * echarts组件类:极坐标 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Neil (杨骥, yangji01@baidu.com) * */ define( 'echarts/component/polar',['require','./base','../util/coordinates','zrender/tool/util','../component'],function(require) { function Polar(ecConfig, messageCenter, zr, option, component) { var Base = require('./base'); Base.call(this, ecConfig, zr); var ecCoordinates = require('../util/coordinates'); var zrUtil = require('zrender/tool/util'); var self = this; self.type = ecConfig.COMPONENT_TYPE_POLAR; var polar; var series; var _queryTarget; function init(newOption, newComponent) { component = newComponent; refresh(newOption); } /** * 绘制图形 */ function _buildShape() { for (var i = 0; i < polar.length; i ++) { self.reformOption(polar[i]); _queryTarget = [polar[i], option]; _createVector(i); _buildSpiderWeb(i); _buildText(i); _adjustIndicatorValue(i); _addAxisLabel(i); } for (var i = 0; i < self.shapeList.length; i ++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } /** * 生成蜘蛛网顶点坐标 * @param {number} polar的index */ function _createVector(index) { var item = polar[index]; var indicator = self.deepQuery(_queryTarget, 'indicator'); var length = indicator.length; var startAngle = item.startAngle ; var dStep = 2 * Math.PI / length; var radius = self.parsePercent( item.radius, Math.min(zr.getWidth(), zr.getHeight()) / 2 ); var __ecIndicator = item.__ecIndicator = []; var vector; for (var i = 0 ;i < length ; i ++) { vector = ecCoordinates.polar2cartesian( radius, startAngle * Math.PI / 180 + dStep * i ); __ecIndicator.push({ // 将图形翻转 vector : [vector[1], -vector[0]] }); } } /** * 构建蜘蛛网 * @param {number} polar的index */ function _buildSpiderWeb(index) { var item = polar[index]; var __ecIndicator = item.__ecIndicator; var splitArea = item.splitArea; var splitLine = item.splitLine; var center = getCenter(index); var splitNumber = item.splitNumber; var strokeColor = splitLine.lineStyle.color; var lineWidth = splitLine.lineStyle.width; var show = splitLine.show; var axisLine = self.deepQuery(_queryTarget, 'axisLine'); _addArea( __ecIndicator, splitNumber, center, splitArea, strokeColor, lineWidth, show ); _addLine( __ecIndicator, center, axisLine ); } /** * 绘制axisLabel */ function _addAxisLabel(index) { var item = polar[index]; var indicator = self.deepQuery(_queryTarget, 'indicator'); var __ecIndicator = item.__ecIndicator; var axisLabel; var vector; var style; var newStyle; var splitNumber = self.deepQuery(_queryTarget, 'splitNumber'); var center = getCenter(index); var vector; var value; var text; var theta; // var startAngle = self.deepQuery(_queryTarget, 'startAngle'); var offset; var precision = self.deepQuery(_queryTarget, 'precision'); for (var i = 0; i < indicator.length; i ++) { axisLabel = self.deepQuery( [indicator[i], item, option], 'axisLabel' ); if (axisLabel.show) { style = {}; style.textFont = self.getFont(); //Todo: bug fix style = zrUtil.merge(style, axisLabel); style.lineWidth = style.width; vector = __ecIndicator[i].vector; value = __ecIndicator[i].value; theta = i / indicator.length * 2 * Math.PI; offset = axisLabel.offset || 10; for (var j = 1 ; j <= splitNumber; j ++) { newStyle = zrUtil.merge({}, style); text = j * (value.max - value.min) / splitNumber + value.min; if (precision) { text = text.toFixed(precision); } newStyle.text = self.numAddCommas(text); newStyle.x = j * vector[0] / splitNumber + Math.cos(theta) * offset + center[0]; newStyle.y = j * vector[1] / splitNumber + Math.sin(theta) * offset + center[1]; self.shapeList.push({ shape : 'text', style : newStyle, draggable : false, hoverable : false }); } } } } /** * 绘制坐标头的文字 * @param {number} polar的index */ function _buildText (index) { var item = polar[index]; var __ecIndicator = item.__ecIndicator; var vector; var indicator = self.deepQuery(_queryTarget, 'indicator'); var center = getCenter(index); var style; var textAlign; var name; var rotation; var x = 0; var y = 0; var margin; var textStyle; for (var i = 0; i < indicator.length; i ++) { name = self.deepQuery( [indicator[i], item, option], 'name' ); if (!name.show) { continue; } textStyle = self.deepQuery( [name, item, option], 'textStyle' ); style = {}; style.textFont = self.getFont(textStyle); style.color = textStyle.color; if (typeof name.formatter == 'function') { style.text = name.formatter(indicator[i].text, i); } else if (typeof name.formatter == 'string'){ style.text = name.formatter.replace( '{value}', indicator[i].text ); } else { style.text = indicator[i].text; } vector = __ecIndicator[i].vector; if (Math.round(vector[0]) > 0) { textAlign = 'left'; } else if (Math.round(vector[0]) < 0) { textAlign = 'right'; } else { textAlign = 'center'; } if (!name.margin) { vector = _mapVector(vector, center, 1.2); } else { margin = name.margin; x = vector[0] > 0 ? margin : - margin; y = vector[1] > 0 ? margin : - margin; x = vector[0] === 0 ? 0 : x; y = vector[1] === 0 ? 0 : y; vector = _mapVector(vector, center, 1); } style.textAlign = textAlign; style.x = vector[0] + x; style.y = vector[1] + y; if (name.rotate) { rotation = [ name.rotate / 180 * Math.PI, vector[0], vector[1] ]; } self.shapeList.push({ shape : 'text', style : style, draggable : false, hoverable : false, rotation : rotation }); } } /** * 添加一个隐形的盒子 当做drop的容器 暴露给外部的图形类使用 * @param {number} polar的index * @return {Object} 添加的盒子图形 */ function _addDropBox(index) { var index = index || 0; var item = polar[index]; var center = getCenter(index); var __ecIndicator = item.__ecIndicator; var len = __ecIndicator.length; var pointList = []; var vector; var shape; for (var i = 0; i < len; i ++) { vector = __ecIndicator[i].vector; pointList.push(_mapVector(vector, center, 1.2)); } shape = _getShape( pointList, 'fill', 'rgba(0,0,0,0)', '', 1 ); return shape; } /** * 绘制蜘蛛网的正n变形 * * @param {Array} 指标数组 * @param {number} 分割线数量 * @param {Array} 中点坐标 * @param {Object} 分割区域对象 * @param {string} 线条颜色 * @param {number} 线条宽度 */ function _addArea( __ecIndicator, splitNumber, center, splitArea, strokeColor, lineWidth, show ) { var shape; var scale; var scale1; var pointList; for (var i = 0; i < splitNumber ; i ++ ) { scale = (splitNumber - i) / splitNumber; pointList = _getPointList(__ecIndicator, scale, center); if (show) { shape = _getShape( pointList, 'stroke', '', strokeColor, lineWidth ); self.shapeList.push(shape); } if (splitArea.show) { scale1 = (splitNumber - i - 1) / splitNumber; _addSplitArea( __ecIndicator, splitArea, scale, scale1, center, i ); } } } /** * 获取需要绘制的多边形的点集 * @param {Object} serie的指标参数 * @param {number} 缩小的系数 * @param {Array} 中点坐标 * * @return {Array>} 返回绘制的点集 */ function _getPointList(__ecIndicator, scale, center) { var pointList = []; var len = __ecIndicator.length; var vector; for (var i = 0 ; i < len ; i ++ ) { vector = __ecIndicator[i].vector; pointList.push(_mapVector(vector, center, scale)); } return pointList; } /** * 获取绘制的图形 * @param {Array>} 绘制的点集 * @param {string} 绘制方式 stroke | fill | both 描边 | 填充 | 描边 + 填充 * @param {string} 颜色 * @param {string} 描边颜色 * @param {number} 线条宽度 * @param {boolean=} hoverable * @param {boolean=} draggable * @return {Object} 绘制的图形对象 */ function _getShape( pointList, brushType, color, strokeColor, lineWidth, hoverable, draggable ) { return { shape : 'polygon', style : { pointList : pointList, brushType : brushType, color : color, strokeColor : strokeColor, lineWidth : lineWidth }, hoverable : hoverable || false, draggable : draggable || false }; } /** * 绘制填充区域 */ function _addSplitArea( __ecIndicator, splitArea, scale, scale1, center, colorInd ) { var indLen = __ecIndicator.length; var color; var colorArr = splitArea.areaStyle.color; var colorLen; var vector; var vector1; var pointList = []; var indLen = __ecIndicator.length; var shape; if (typeof colorArr == 'string') { colorArr = [colorArr]; } colorLen = colorArr.length; color = colorArr[ colorInd % colorLen]; for (var i = 0; i < indLen ; i ++) { pointList = []; vector = __ecIndicator[i].vector; vector1 = __ecIndicator[(i + 1) % indLen].vector; pointList.push(_mapVector(vector, center, scale)); pointList.push(_mapVector(vector, center, scale1)); pointList.push(_mapVector(vector1, center, scale1)); pointList.push(_mapVector(vector1, center, scale)); shape = _getShape( pointList, 'fill', color, '', 1 ); self.shapeList.push(shape); } } /** * 转换坐标 * * @param {Array} 原始坐标 * @param {Array} 中点坐标 * @param {number} 缩小的倍数 * * @return {Array} 转换后的坐标 */ function _mapVector(vector, center, scale) { return [ vector[0] * scale + center[0], vector[1] * scale + center[1] ]; } /** * 获取中心点位置 暴露给外部图形类使用 * @param {number} polar的index */ function getCenter(index) { var index = index || 0; return self.parseCenter(zr, polar[index].center); } /** * 绘制从中点出发的线 * * @param {Array} 指标对象 * @param {Array} 中点坐标 * @param {string} 线条颜色 * @param {number} 线条宽度 * @param {string} 线条绘制类型 * solid | dotted | dashed 实线 | 点线 | 虚线 */ function _addLine( __ecIndicator, center, axisLine ) { var indLen = __ecIndicator.length; var line; var vector; var lineStyle = axisLine.lineStyle; var strokeColor = lineStyle.color; var lineWidth = lineStyle.width; var lineType = lineStyle.type; for (var i = 0; i < indLen ; i ++ ) { vector = __ecIndicator[i].vector; line = _getLine( center[0], center[1], vector[0] + center[0], vector[1] + center[1], strokeColor, lineWidth, lineType ); self.shapeList.push(line); } } /** * 获取线条对象 * @param {number} 出发点横坐标 * @param {number} 出发点纵坐标 * @param {number} 终点横坐标 * @param {number} 终点纵坐标 * @param {string} 线条颜色 * @param {number} 线条宽度 * @param {string} 线条类型 * * @return {Object} 线条对象 */ function _getLine( xStart, yStart, xEnd, yEnd, strokeColor, lineWidth, lineType ) { return { shape : 'line', style : { xStart : xStart, yStart : yStart, xEnd : xEnd, yEnd : yEnd, strokeColor : strokeColor, lineWidth : lineWidth, lineType : lineType }, hoverable : false }; } /** * 调整指标的值,当indicator中存在max时设置为固定值 * @param {number} polar的index */ function _adjustIndicatorValue(index) { var item = polar[index]; var indicator = self.deepQuery(_queryTarget, 'indicator'); var len = indicator.length; var __ecIndicator = item.__ecIndicator; var value; var max; var min; var data = _getSeriesData(index); var splitNumber = item.splitNumber; var boundaryGap = self.deepQuery(_queryTarget, 'boundaryGap'); var precision = self.deepQuery(_queryTarget, 'precision'); var power = self.deepQuery(_queryTarget, 'power'); var scale = self.deepQuery(_queryTarget, 'scale'); for (var i = 0; i < len ; i ++ ) { if (typeof indicator[i].max == 'number') { max = indicator[i].max; min = indicator[i].min || 0; value = { max : max, min : min }; } else { value = _findValue( data, i, splitNumber, boundaryGap, precision, power, scale ); } __ecIndicator[i].value = value; } } /** * 将series中的数据拿出来,如果没有polarIndex属性,默认为零 * @param {number} polar 的index * @param {Array} 需要处理的数据 */ function _getSeriesData(index) { var data = []; var serie; var serieData; var legend = component.legend; for (var i = 0; i < series.length; i ++) { serie = series[i]; if (serie.type != ecConfig.CHART_TYPE_RADAR) { continue; } serieData = serie.data || []; for (var j = 0; j < serieData.length; j ++) { polarIndex = self.deepQuery( [serieData[j], serie, option], 'polarIndex' ) || 0; if (polarIndex == index && (!legend || legend.isSelected(serieData[j].name)) ) { data.push(serieData[j]); } } } return data; } /** * 查找指标合适的值 * * 如果只有一组数据以数据中的最大值作为最大值 0为最小值 * 如果是多组,使用同一维度的进行比较 选出最大值最小值 * 对它们进行处理 * @param {Object} serie 的 data * @param {number} 指标的序号 * @param {boolean} boundaryGap 两端留白 * @param {number} precision 小数精度 * @param {number} power 整数精度 * @return {Object} 指标的最大值最小值 */ function _findValue( data, index, splitNumber, boundaryGap, precision, power, scale ) { var max; var min; var value; var delta; var str; var len = 0; var max0; var min0; var one; if (!data || data.length === 0) { return; } function _compare(item) { (item > max || max === undefined) && (max = item); (item < min || min === undefined) && (min = item); } if (data.length == 1) { min = 0; } if (data.length != 1) { for (var i = 0; i < data.length; i ++) { value = data[i].value[index]; _compare(value); } } else { one = data[0]; for (var i = 0; i < one.value.length; i ++) { _compare(one.value[i]); } } if (data.length != 1) { if (scale) { delta = _getDelta( max, min, splitNumber, precision, power ); if (delta >= 1) { min = Math.floor(min / delta) * delta - delta; } else if (delta === 0) { if (max > 0) { min0 = 0; max0 = 2 * max; } else if (max === 0) { min0 = 0; max0 = 100; } else { max0 = 0; min0 = 2 * min; } return { max : max0, min : min0 }; } else { str = (delta + '').split('.')[1]; len = str.length; min = Math.floor( min * Math.pow(10, len)) / Math.pow(10, len ) - delta; } if (Math.abs(min) <= delta) { min = 0; } max = min + Math.floor(delta * Math.pow(10, len) * (splitNumber + 1)) / Math.pow(10, len) ; } else { min = min > 0 ? 0 : min; } } if (boundaryGap) { max = max > 0 ? max * 1.2 : max * 0.8; min = min > 0 ? min * 0.8 : min * 1.2; } return { max : max, min : min }; } /** * 获取最大值与最小值中间比较合适的差值 * @param {number} max; * @param {number} min * @param {number} precision 小数精度 * @param {number} power 整数精度 * @return {number} delta */ function _getDelta(max , min, splitNumber, precision, power) { var delta = (max - min) / splitNumber; var str; var n; if (delta > 1) { if (!power) { str = (delta + '').split('.')[0]; n = str.length; if (str.charAt(0) >= 5) { return Math.pow(10, n); } else { return (str.charAt(0) - 0 + 1 ) * Math.pow(10, n - 1); } } else { delta = Math.ceil(delta); if (delta % power > 0) { return (Math.ceil(delta / power) + 1) * power; } else { return delta; } } } else if (delta == 1) { return 1; } else if (delta === 0) { return 0; } else { if (!precision) { str = (delta + '').split('.')[1]; n = 0; while (str[n] == '0') { n ++ ; } if (str[n] >= 5) { return '0.' + str.substring(0, n + 1) - 0 + 1 / Math.pow(10, n); } else { return '0.' + str.substring(0, n + 1) - 0 + 1 / Math.pow(10, n + 1); } } else { return Math.ceil(delta * Math.pow(10, precision)) / Math.pow(10, precision); } } } /** * 获取每个指标上某个value对应的坐标 * @param {number} polarIndex * @param {number} indicatorIndex * @param {number} value * @return {Array} 对应坐标 */ function getVector(polarIndex, indicatorIndex, value) { polarIndex = polarIndex || 0; indicatorIndex = indicatorIndex || 0; var __ecIndicator = polar[polarIndex].__ecIndicator; if (indicatorIndex >= __ecIndicator.length) { return ; } var indicator = polar[polarIndex].__ecIndicator[indicatorIndex]; var center = getCenter(polarIndex); var vector = indicator.vector; var max = indicator.value.max; var min = indicator.value.min; var alpha; if (typeof value == 'undefined') { return center; } switch (value) { case 'min' : value = min; break; case 'max' : value = max; break; case 'center' : value = (max + min) / 2; break; } if (max != min) { alpha = (value - min) / (max - min); } else { alpha = 0.5; } return _mapVector(vector, center, alpha); } /** * 判断一个点是否在网内 * @param {Array} 坐标 * @return {number} 返回polarindex 返回-1表示不在任何polar */ function isInside(vector) { var polar = getNearestIndex(vector); if (polar) { return polar.polarIndex; } return -1; } /** * 如果一个点在网内,返回离它最近的数据轴的index * @param {Array} 坐标 * @return {Object} | false * polarIndex * valueIndex */ function getNearestIndex(vector) { var item; var center; var radius; var polarVector; var startAngle; var indicator; var len; var angle; var finalAngle; var zrSize = Math.min(zr.getWidth(), zr.getHeight()) / 2; for (var i = 0 ; i < polar.length; i ++) { item = polar[i]; center = getCenter(i); if (vector[0] == center[0] && vector[1] == center[1]) { return { polarIndex : i, valueIndex : 0 }; } radius = self.parsePercent(item.radius, zrSize); startAngle = item.startAngle; indicator = item.indicator; len = indicator.length; angle = 2 * Math.PI / len; // 注意y轴的翻转 polarVector = ecCoordinates.cartesian2polar( vector[0] - center[0], center[1] - vector[1] ); if (vector[0] - center[0] < 0) { polarVector[1] += Math.PI; } if (polarVector[1] < 0) { polarVector[1] += 2 * Math.PI; } // 减去startAngle的偏移量 再加2PI变成正数 finalAngle = polarVector[1] - startAngle / 180 * Math.PI + Math.PI * 2; if (Math.abs(Math.cos(finalAngle % (angle / 2))) * radius > polarVector[0]) { return { polarIndex : i, valueIndex : Math.floor( (finalAngle + angle / 2 ) / angle ) % len }; } } } /** * 获取指标信息 * @param {number} polarIndex * @return {Array} indicator */ function getIndicator(index) { var index = index || 0; return polar[index].indicator; } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; polar = option.polar; series = option.series; } self.clear(); _buildShape(); } self.refresh = refresh; self.getVector = getVector; self.getDropBox = _addDropBox; self.getCenter = getCenter; self.getIndicator = getIndicator; self.isInside = isInside; self.getNearestIndex = getNearestIndex; init(option, component); } require('../component').define('polar', Polar); return Polar; } ); /** * echarts默认主题,开发中 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/theme/default',[],function() { var config = { }; return config; }); /*! * ECharts, a javascript interactive chart library. * * Copyright (c) 2013, Baidu Inc. * All rights reserved. * * LICENSE * https://github.com/ecomfe/echarts/blob/master/LICENSE.txt */ /** * echarts * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/echarts',['require','zrender/tool/env','./config','zrender/tool/util','zrender','zrender/tool/event','zrender/config','./util/shape/icon','./util/shape/markLine','./chart','./chart/island','./component','./component/title','./component/axis','./component/categoryAxis','./component/valueAxis','./component/grid','./component/dataZoom','./component/legend','./component/dataRange','./component/tooltip','./component/toolbox','./component/dataView','./component/polar','./util/ecQuery','./util/ecData','./chart','./component','zrender/tool/util','./util/ecQuery','zrender/tool/util','zrender/tool/color','zrender/tool/util','./util/ecQuery','zrender/tool/util','./util/ecQuery','zrender/tool/util','zrender','zrender/tool/util','zrender/tool/util','./theme/default','./theme/default'],function(require) { var self = {}; var echarts = self; // 提供内部反向使用静态方法; var _canvasSupported = require('zrender/tool/env').canvasSupported; var _idBase = new Date() - 0; var _instances = {}; // ECharts实例map索引 var DOM_ATTRIBUTE_KEY = '_echarts_instance_'; self.version = '1.4.0'; self.dependencies = { zrender : '1.1.1' }; /** * 入口方法 */ self.init = function(dom, theme) { dom = dom instanceof Array ? dom[0] : dom; // dom与echarts实例映射索引 var key = dom.getAttribute(DOM_ATTRIBUTE_KEY); if (!key) { key = _idBase++; dom.setAttribute(DOM_ATTRIBUTE_KEY, key); } if (_instances[key]) { // 同一个dom上多次init,自动释放已有实例 _instances[key].dispose(); } _instances[key] = new Echarts(dom); _instances[key].id = key; _instances[key].setTheme(theme); return _instances[key]; }; /** * 通过id获得ECharts实例,id可在实例化后读取 */ self.getInstanceById = function(key) { return _instances[key]; }; /** * 基于zrender实现Echarts接口层 * @param {HtmlElement} dom 必要 */ function Echarts(dom) { var ecConfig = require('./config'); var _themeConfig = require('zrender/tool/util').clone(ecConfig); var self = this; var _zr; var _option; var _optionBackup; // for各种change和zoom var _optionRestore; // for restore; var _chartList; // 图表实例 var _messageCenter; // Echarts层的消息中心,做zrender原始事件转换 var _connected = false; var _status = { // 用于图表间通信 dragIn : false, dragOut : false, needRefresh : false }; var _selectedMap; var _island; var _toolbox; var _refreshInside; // 内部刷新标志位 // 初始化::构造函数 _init(); function _init() { var zrender = require('zrender'); if (((zrender.version || '1.0.3').replace('.', '') - 0) < (echarts.dependencies.zrender.replace('.', '') - 0) ) { console.error( 'ZRender ' + (zrender.version || '1.0.3-') + ' is too old for ECharts ' + echarts.version + '. Current version need ZRender ' + echarts.dependencies.zrender + '+' ); } _zr = zrender.init(dom); _option = {}; _chartList = []; // 图表实例 _messageCenter = {}; // Echarts层的消息中心,做zrender原始事件转换 // 添加消息中心的事件分发器特性 var zrEvent = require('zrender/tool/event'); zrEvent.Dispatcher.call(_messageCenter); for (var e in ecConfig.EVENT) { if (e != 'CLICK' && e != 'HOVER' && e != 'MAP_ROAM') { _messageCenter.bind(ecConfig.EVENT[e], _onevent); } } var zrConfig = require('zrender/config'); _zr.on(zrConfig.EVENT.CLICK, _onclick); _zr.on(zrConfig.EVENT.MOUSEOVER, _onhover); //_zr.on(zrConfig.EVENT.MOUSEWHEEL, _onmousewheel); _zr.on(zrConfig.EVENT.DRAGSTART, _ondragstart); _zr.on(zrConfig.EVENT.DRAGEND, _ondragend); _zr.on(zrConfig.EVENT.DRAGENTER, _ondragenter); _zr.on(zrConfig.EVENT.DRAGOVER, _ondragover); _zr.on(zrConfig.EVENT.DRAGLEAVE, _ondragleave); _zr.on(zrConfig.EVENT.DROP, _ondrop); // 动态扩展zrender shape:icon、markLine require('./util/shape/icon'); require('./util/shape/markLine'); // 内置图表注册 var chartLibrary = require('./chart'); require('./chart/island'); // 孤岛 var Island = chartLibrary.get('island'); _island = new Island(_themeConfig, _messageCenter, _zr); // 内置组件注册 var componentLibrary = require('./component'); require('./component/title'); require('./component/axis'); require('./component/categoryAxis'); require('./component/valueAxis'); require('./component/grid'); require('./component/dataZoom'); require('./component/legend'); require('./component/dataRange'); require('./component/tooltip'); require('./component/toolbox'); require('./component/dataView'); require('./component/polar'); // 工具箱 var Toolbox = componentLibrary.get('toolbox'); _toolbox = new Toolbox(_themeConfig, _messageCenter, _zr, dom, self); _disposeChartList(); } /** * ECharts事件处理中心 */ var _curEventType = null; // 破循环信号灯 function _onevent(param){ param.__echartsId = param.__echartsId || self.id; var fromMyself = true; if (param.__echartsId != self.id) { // 来自其他联动图表的事件 fromMyself = false; } if (!_curEventType) { _curEventType = param.type; } switch(param.type) { case ecConfig.EVENT.LEGEND_SELECTED : _onlegendSelected(param); break; case ecConfig.EVENT.DATA_ZOOM : if (!fromMyself) { var dz = self.component.dataZoom; if (dz) { dz.silence(true); dz.absoluteZoom(param.zoom); dz.silence(false); } } _ondataZoom(param); break; case ecConfig.EVENT.DATA_RANGE : fromMyself && _ondataRange(param); break; case ecConfig.EVENT.MAGIC_TYPE_CHANGED : if (!fromMyself) { var tb = self.component.toolbox; if (tb) { tb.silence(true); tb.setMagicType(param.magicType); tb.silence(false); } } _onmagicTypeChanged(param); break; case ecConfig.EVENT.DATA_VIEW_CHANGED : fromMyself && _ondataViewChanged(param); break; case ecConfig.EVENT.TOOLTIP_HOVER : fromMyself && _tooltipHover(param); break; case ecConfig.EVENT.RESTORE : _onrestore(); break; case ecConfig.EVENT.REFRESH : fromMyself && _onrefresh(param); break; // 鼠标同步 case ecConfig.EVENT.TOOLTIP_IN_GRID : case ecConfig.EVENT.TOOLTIP_OUT_GRID : if (!fromMyself) { // 只处理来自外部的鼠标同步 var grid = self.component.grid; if (grid) { _zr.trigger( 'mousemove', { connectTrigger : true, zrenderX : grid.getX() + param.x * grid.getWidth(), zrenderY : grid.getY() + param.y * grid.getHeight() } ); } } else if (_connected) { // 来自自己,并且存在多图联动,空间坐标映射修改参数分发 var grid = self.component.grid; if (grid) { param.x = (param.event.zrenderX - grid.getX()) / grid.getWidth(); param.y = (param.event.zrenderY - grid.getY()) / grid.getHeight(); } } break; /* case ecConfig.EVENT.RESIZE : case ecConfig.EVENT.DATA_CHANGED : case ecConfig.EVENT.PIE_SELECTED : case ecConfig.EVENT.MAP_SELECTED : break; */ } // 多图联动,只做自己的一级事件分发,避免级联事件循环 if (_connected && fromMyself && _curEventType == param.type) { for (var c in _connected) { _connected[c].connectedEventHandler(param); } // 分发完毕后复位 _curEventType = null; } if (!fromMyself || (!_connected && fromMyself)) { // 处理了完联动事件复位 _curEventType = null; } } /** * 点击事件,响应zrender事件,包装后分发到Echarts层 */ function _onclick(param) { var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].onclick && _chartList[len].onclick(param); } if (param.target) { var ecData = _eventPackage(param.target); if (ecData && typeof ecData.seriesIndex != 'undefined') { _messageCenter.dispatch( ecConfig.EVENT.CLICK, param.event, ecData ); } } } /** * 悬浮事件,响应zrender事件,包装后分发到Echarts层 */ function _onhover(param) { if (param.target) { var ecData = _eventPackage(param.target); if (ecData && typeof ecData.seriesIndex != 'undefined') { _messageCenter.dispatch( ecConfig.EVENT.HOVER, param.event, ecData ); } } } /** * 滚轮回调,孤岛可计算特性 function _onmousewheel(param) { _messageCenter.dispatch( ecConfig.EVENT.MOUSEWHEEL, param.event, _eventPackage(param.target) ); } */ /** * dragstart回调,可计算特性实现 */ function _ondragstart(param) { // 复位用于图表间通信拖拽标识 _status = { dragIn : false, dragOut : false, needRefresh : false }; var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].ondragstart && _chartList[len].ondragstart(param); } } /** * dragging回调,可计算特性实现 */ function _ondragenter(param) { var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].ondragenter && _chartList[len].ondragenter(param); } } /** * dragstart回调,可计算特性实现 */ function _ondragover(param) { var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].ondragover && _chartList[len].ondragover(param); } } /** * dragstart回调,可计算特性实现 */ function _ondragleave(param) { var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].ondragleave && _chartList[len].ondragleave(param); } } /** * dragstart回调,可计算特性实现 */ function _ondrop(param) { var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].ondrop && _chartList[len].ondrop(param, _status); } _island.ondrop(param, _status); } /** * dragdone回调 ,可计算特性实现 */ function _ondragend(param) { var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].ondragend && _chartList[len].ondragend(param, _status); } _island.ondragend(param, _status); // 发生过重计算 if (_status.needRefresh) { _syncBackupData(_island.getOption()); _messageCenter.dispatch( ecConfig.EVENT.DATA_CHANGED, param.event, _eventPackage(param.target) ); _messageCenter.dispatch(ecConfig.EVENT.REFRESH); } } /** * 图例选择响应 */ function _onlegendSelected(param) { // 用于图表间通信 _status.needRefresh = false; var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].onlegendSelected && _chartList[len].onlegendSelected(param, _status); } _selectedMap = param.selected; if (_status.needRefresh) { _messageCenter.dispatch(ecConfig.EVENT.REFRESH); } } /** * 数据区域缩放响应 */ function _ondataZoom(param) { // 用于图表间通信 _status.needRefresh = false; var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].ondataZoom && _chartList[len].ondataZoom(param, _status); } if (_status.needRefresh) { _messageCenter.dispatch(ecConfig.EVENT.REFRESH); } } /** * 值域漫游响应 */ function _ondataRange(param) { // 用于图表间通信 _status.needRefresh = false; var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].ondataRange && _chartList[len].ondataRange(param, _status); } // 没有相互影响,直接刷新即可 if (_status.needRefresh) { _zr.refresh(); } } /** * 动态类型切换响应 */ function _onmagicTypeChanged() { _render(_getMagicOption()); } /** * 数据视图修改响应 */ function _ondataViewChanged(param) { _syncBackupData(param.option); _messageCenter.dispatch( ecConfig.EVENT.DATA_CHANGED, null, param ); _messageCenter.dispatch(ecConfig.EVENT.REFRESH); } /** * tooltip与图表间通信 */ function _tooltipHover(param) { var len = _chartList.length; var tipShape = []; while (len--) { _chartList[len] && _chartList[len].ontooltipHover && _chartList[len].ontooltipHover(param, tipShape); } } /** * 还原 */ function _onrestore() { self.restore(); } /** * 刷新 */ function _onrefresh(param) { _refreshInside = true; self.refresh(param); _refreshInside = false; } /** * 当前正在使用的option,还原可能存在的dataZoom */ function _getMagicOption(targetOption) { var magicOption = targetOption || _toolbox.getMagicOption(); var len; // 横轴数据还原 if (_optionBackup.xAxis) { if (_optionBackup.xAxis instanceof Array) { len = _optionBackup.xAxis.length; while (len--) { magicOption.xAxis[len].data = _optionBackup.xAxis[len].data; } } else { magicOption.xAxis.data = _optionBackup.xAxis.data; } } // 纵轴数据还原 if (_optionBackup.yAxis) { if (_optionBackup.yAxis instanceof Array) { len = _optionBackup.yAxis.length; while (len--) { magicOption.yAxis[len].data = _optionBackup.yAxis[len].data; } } else { magicOption.yAxis.data = _optionBackup.yAxis.data; } } // 系列数据还原 len = magicOption.series.length; while (len--) { magicOption.series[len].data = _optionBackup.series[len].data; } return magicOption; } /** * 数据修改后的反向同步备份数据 */ function _syncBackupData(curOption) { var ecQuery = require('./util/ecQuery'); if (ecQuery.query(curOption, 'dataZoom.show') || ( ecQuery.query(curOption, 'toolbox.show') && ecQuery.query(curOption, 'toolbox.feature.dataZoom.show') ) ) { // 有dataZoom就dataZoom做同步 for (var i = 0, l = _chartList.length; i < l; i++) { if (_chartList[i].type == ecConfig.COMPONENT_TYPE_DATAZOOM ) { _chartList[i].syncBackupData(curOption, _optionBackup); return; } } } else { // 没有就ECharts做 var curSeries = curOption.series; var curData; for (var i = 0, l = curSeries.length; i < l; i++) { curData = curSeries[i].data; for (var j = 0, k = curData.length; j < k; j++) { _optionBackup.series[i].data[j] = curData[j]; } } } } /** * 打包Echarts层的事件附件 */ function _eventPackage(target) { if (target) { var ecData = require('./util/ecData'); var seriesIndex = ecData.get(target, 'seriesIndex'); var dataIndex = ecData.get(target, 'dataIndex'); dataIndex = self.component.dataZoom ? self.component.dataZoom.getRealDataIndex( seriesIndex, dataIndex ) : dataIndex; return { seriesIndex : seriesIndex, dataIndex : dataIndex, data : ecData.get(target, 'data'), name : ecData.get(target, 'name'), value : ecData.get(target, 'value') }; } return; } /** * 图表渲染 */ function _render(magicOption) { _mergeGlobalConifg(magicOption); if (magicOption.backgroundColor) { if (!_canvasSupported && magicOption.backgroundColor.indexOf('rgba') != -1 ) { // IE6~8对RGBA的处理,filter会带来其他颜色的影响 var cList = magicOption.backgroundColor.split(','); dom.style.filter = 'alpha(opacity=' + cList[3].substring(0, cList[3].lastIndexOf(')')) * 100 + ')'; cList.length = 3; cList[0] = cList[0].replace('a', ''); dom.style.backgroundColor = cList.join(',') + ')'; } else { dom.style.backgroundColor = magicOption.backgroundColor; } } _disposeChartList(); _zr.clear(); var chartLibrary = require('./chart'); var componentLibrary = require('./component'); // 标题 var title; if (magicOption.title) { var Title = componentLibrary.get('title'); title = new Title( _themeConfig, _messageCenter, _zr, magicOption ); _chartList.push(title); self.component.title = title; } // 提示 var tooltip; if (magicOption.tooltip) { var Tooltip = componentLibrary.get('tooltip'); tooltip = new Tooltip( _themeConfig, _messageCenter, _zr, magicOption, dom, self ); _chartList.push(tooltip); self.component.tooltip = tooltip; } // 图例 var legend; if (magicOption.legend) { var Legend = componentLibrary.get('legend'); legend = new Legend( _themeConfig, _messageCenter, _zr, magicOption, _selectedMap ); _chartList.push(legend); self.component.legend = legend; } // 值域控件 var dataRange; if (magicOption.dataRange) { var DataRange = componentLibrary.get('dataRange'); dataRange = new DataRange( _themeConfig, _messageCenter, _zr, magicOption ); _chartList.push(dataRange); self.component.dataRange = dataRange; } // 直角坐标系 var grid; var dataZoom; var xAxis; var yAxis; if (magicOption.grid || magicOption.xAxis || magicOption.yAxis) { var Grid = componentLibrary.get('grid'); grid = new Grid(_themeConfig, _messageCenter, _zr, magicOption); _chartList.push(grid); self.component.grid = grid; var DataZoom = componentLibrary.get('dataZoom'); dataZoom = new DataZoom( _themeConfig, _messageCenter, _zr, magicOption, { 'legend' : legend, 'grid' : grid } ); _chartList.push(dataZoom); self.component.dataZoom = dataZoom; var Axis = componentLibrary.get('axis'); xAxis = new Axis( _themeConfig, _messageCenter, _zr, magicOption, { 'legend' : legend, 'grid' : grid }, 'xAxis' ); _chartList.push(xAxis); self.component.xAxis = xAxis; yAxis = new Axis( _themeConfig, _messageCenter, _zr, magicOption, { 'legend' : legend, 'grid' : grid }, 'yAxis' ); _chartList.push(yAxis); self.component.yAxis = yAxis; } // 极坐标系 var polar; if (magicOption.polar) { var Polar = componentLibrary.get('polar'); polar = new Polar( _themeConfig, _messageCenter, _zr, magicOption, { 'legend' : legend } ); _chartList.push(polar); self.component.polar = polar; } tooltip && tooltip.setComponent(); var ChartClass; var chartType; var chart; var chartMap = {}; // 记录已经初始化的图表 for (var i = 0, l = magicOption.series.length; i < l; i++) { chartType = magicOption.series[i].type; if (!chartType) { console.error('series[' + i + '] chart type has not been defined.'); continue; } if (!chartMap[chartType]) { chartMap[chartType] = true; ChartClass = chartLibrary.get(chartType); if (ChartClass) { chart = new ChartClass( _themeConfig, _messageCenter, _zr, magicOption, { 'tooltip' : tooltip, 'legend' : legend, 'dataRange' : dataRange, 'grid' : grid, 'xAxis' : xAxis, 'yAxis' : yAxis, 'polar' : polar } ); _chartList.push(chart); self.chart[chartType] = chart; } else { console.error(chartType + ' has not been required.'); } } } _island.render(magicOption); _toolbox.render(magicOption, {dataZoom: dataZoom}); if (magicOption.animation && !magicOption.renderAsImage) { var len = _chartList.length; while (len--) { chart = _chartList[len]; if (chart && chart.animation && chart.shapeList && chart.shapeList.length < magicOption.animationThreshold ) { chart.animation(); } } _zr.refresh(); } else { _zr.render(); } var imgId = 'IMG' + self.id; var img = document.getElementById(imgId); if (magicOption.renderAsImage && _canvasSupported) { // IE8- 不支持图片渲染形式 if (img) { // 已经渲染过则更新显示 img.src = getDataURL(magicOption.renderAsImage); } else { // 没有渲染过插入img dom img = getImage(magicOption.renderAsImage); img.id = imgId; img.style.position = 'absolute'; img.style.left = 0; img.style.top = 0; dom.firstChild.appendChild(img); } un(); _zr.un(); _disposeChartList(); _zr.clear(); } else if (img) { // 删除可能存在的img img.parentNode.removeChild(img); } img = null; } /** * 还原 */ function restore() { var zrUtil = require('zrender/tool/util'); if (_optionRestore.legend && _optionRestore.legend.selected) { _selectedMap = _optionRestore.legend.selected; } else { _selectedMap = {}; } _optionBackup = zrUtil.clone(_optionRestore); _option = zrUtil.clone(_optionRestore); _island.clear(); _toolbox.reset(_option); _render(_option); } /** * 刷新 * @param {Object=} param,可选参数,用于附带option,内部同步用,外部不建议带入数据修改,无法同步 */ function refresh(param) { param = param || {}; var magicOption = param.option; // 外部调用的refresh且有option带入 if (!_refreshInside && param.option) { // 做简单的差异合并去同步内部持有的数据克隆,不建议带入数据 // 开启数据区域缩放、拖拽重计算、数据视图可编辑模式情况下,当用户产生了数据变化后无法同步 // 如有带入option存在数据变化,请重新setOption var ecQuery = require('./util/ecQuery'); if (ecQuery.query(_optionBackup, 'toolbox.show') && ecQuery.query(_optionBackup, 'toolbox.feature.magicType.show') ) { magicOption = _getMagicOption(); } else { magicOption = _getMagicOption(_island.getOption()); } var zrUtil = require('zrender/tool/util'); zrUtil.merge( magicOption, param.option, { 'overwrite': true, 'recursive': true } ); zrUtil.merge( _optionBackup, param.option, { 'overwrite': true, 'recursive': true } ); zrUtil.merge( _optionRestore, param.option, { 'overwrite': true, 'recursive': true } ); _island.refresh(magicOption); _toolbox.refresh(magicOption); } // 停止动画 _zr.clearAnimation(); // 先来后到,安顺序刷新各种图表,图表内部refresh优化检查magicOption,无需更新则不更新~ for (var i = 0, l = _chartList.length; i < l; i++) { _chartList[i].refresh && _chartList[i].refresh(magicOption); } _zr.refresh(); } /** * 释放图表实例 */ function _disposeChartList() { // 停止动画 _zr.clearAnimation(); var len = _chartList.length; while (len--) { _chartList[len] && _chartList[len].dispose && _chartList[len].dispose(); } _chartList = []; self.chart = { island : _island }; self.component = { toolbox : _toolbox }; } /** * 非图表全局属性merge~~ */ function _mergeGlobalConifg(magicOption) { // 背景 if (typeof magicOption.backgroundColor == 'undefined') { magicOption.backgroundColor = _themeConfig.backgroundColor; } // 拖拽重计算相关 if (typeof magicOption.calculable == 'undefined') { magicOption.calculable = _themeConfig.calculable; } if (typeof magicOption.calculableColor == 'undefined') { magicOption.calculableColor = _themeConfig.calculableColor; } if (typeof magicOption.calculableHolderColor == 'undefined') { magicOption.calculableHolderColor = _themeConfig.calculableHolderColor; } // 孤岛显示连接符 if (typeof magicOption.nameConnector == 'undefined') { magicOption.nameConnector = _themeConfig.nameConnector; } if (typeof magicOption.valueConnector == 'undefined') { magicOption.valueConnector = _themeConfig.valueConnector; } // 动画相关 if (typeof magicOption.animation == 'undefined') { magicOption.animation = _themeConfig.animation; } if (typeof magicOption.animationThreshold == 'undefined') { magicOption.animationThreshold = _themeConfig.animationThreshold; } if (typeof magicOption.animationDuration == 'undefined') { magicOption.animationDuration = _themeConfig.animationDuration; } if (typeof magicOption.animationEasing == 'undefined') { magicOption.animationEasing = _themeConfig.animationEasing; } if (typeof magicOption.addDataAnimation == 'undefined') { magicOption.addDataAnimation = _themeConfig.addDataAnimation; } // 默认标志图形类型列表 /* if (typeof magicOption.symbolList == 'undefined') { magicOption.symbolList = _themeConfig.symbolList; } */ var zrColor = require('zrender/tool/color'); // 数值系列的颜色列表,不传则采用内置颜色,可配数组,借用zrender实例注入,会有冲突风险,先这样 if (magicOption.color && magicOption.color.length > 0) { _zr.getColor = function(idx) { return zrColor.getColor(idx, magicOption.color); }; } else { _zr.getColor = function(idx) { return zrColor.getColor(idx, _themeConfig.color); }; } // 降低图表内元素拖拽敏感度,单位ms,不建议外部干预 if (typeof magicOption.DRAG_ENABLE_TIME == 'undefined') { magicOption.DRAG_ENABLE_TIME = _themeConfig.DRAG_ENABLE_TIME; } } /** * 万能接口,配置图表实例任何可配置选项,多次调用时option选项做merge处理 * @param {Object} option * @param {boolean=} notMerge 多次调用时option选项是默认是合并(merge)的, * 如果不需求,可以通过notMerger参数为true阻止与上次option的合并 */ function setOption(option, notMerge) { var zrUtil = require('zrender/tool/util'); if (!notMerge) { zrUtil.merge( _option, zrUtil.clone(option), { 'overwrite': true, 'recursive': true } ); } else { _option = zrUtil.clone(option); } if (!_option.series || _option.series.length === 0) { return; } _optionBackup = zrUtil.clone(_option); _optionRestore = zrUtil.clone(_option); if (_option.legend && _option.legend.selected) { _selectedMap = _option.legend.selected; } else { _selectedMap = {}; } _island.clear(); _toolbox.reset(_option); _render(_option); return self; } /** * 返回内部持有的当前显示option克隆 */ function getOption() { var ecQuery = require('./util/ecQuery'); var zrUtil = require('zrender/tool/util'); if (ecQuery.query(_optionBackup, 'toolbox.show') && ecQuery.query(_optionBackup, 'toolbox.feature.magicType.show') ) { return zrUtil.clone(_getMagicOption()); } else { return zrUtil.clone(_getMagicOption(_island.getOption())); } } /** * 数据设置快捷接口 * @param {Array} series * @param {boolean=} notMerge 多次调用时option选项是默认是合并(merge)的, * 如果不需求,可以通过notMerger参数为true阻止与上次option的合并。 */ function setSeries(series, notMerge) { if (!notMerge) { self.setOption({series: series}); } else { _option.series = series; self.setOption(_option, notMerge); } return self; } /** * 返回内部持有的当前显示series克隆 */ function getSeries() { return getOption().series; } /** * 动态数据添加 * 形参为单组数据参数,多组时为数据,内容同[seriesIdx, data, isShift, additionData] * @param {number} seriesIdx 系列索引 * @param {number | Object} data 增加数据 * @param {boolean=} isHead 是否队头加入,默认,不指定或false时为队尾插入 * @param {boolean=} dataGrow 是否增长数据队列长度,默认,不指定或false时移出目标数组对位数据 * @param {string=} additionData 是否增加类目轴(饼图为图例)数据,附加操作同isHead和dataGrow */ function addData(seriesIdx, data, isHead, dataGrow, additionData) { var ecQuery = require('./util/ecQuery'); var magicOption; if (ecQuery.query(_optionBackup, 'toolbox.show') && ecQuery.query(_optionBackup, 'toolbox.feature.magicType.show') ) { magicOption = _getMagicOption(); } else { magicOption = _getMagicOption(_island.getOption()); } var zrUtil = require('zrender/tool/util'); var params = seriesIdx instanceof Array ? seriesIdx : [[seriesIdx, data, isHead, dataGrow, additionData]]; var axisIdx; var legendDataIdx; //_optionRestore 和 _optionBackup都要同步 for (var i = 0, l = params.length; i < l; i++) { seriesIdx = params[i][0]; data = params[i][1]; isHead = params[i][2]; dataGrow = params[i][3]; additionData = params[i][4]; if (_optionRestore.series[seriesIdx]) { if (isHead) { _optionRestore.series[seriesIdx].data.unshift(data); _optionBackup.series[seriesIdx].data.unshift(data); if (!dataGrow) { _optionRestore.series[seriesIdx].data.pop(); data = _optionBackup.series[seriesIdx].data.pop(); } } else { _optionRestore.series[seriesIdx].data.push(data); _optionBackup.series[seriesIdx].data.push(data); if (!dataGrow) { _optionRestore.series[seriesIdx].data.shift(); data = _optionBackup.series[seriesIdx].data.shift(); } } if (typeof additionData != 'undefined' && _optionRestore.series[seriesIdx].type == ecConfig.CHART_TYPE_PIE && _optionBackup.legend && _optionBackup.legend.data ) { magicOption.legend.data = _optionBackup.legend.data; if (isHead) { _optionRestore.legend.data.unshift(additionData); _optionBackup.legend.data.unshift(additionData); } else { _optionRestore.legend.data.push(additionData); _optionBackup.legend.data.push(additionData); } if (!dataGrow) { legendDataIdx = zrUtil.indexOf( _optionBackup.legend.data, data.name ); legendDataIdx != -1 && ( _optionRestore.legend.data.splice( legendDataIdx, 1 ), _optionBackup.legend.data.splice( legendDataIdx, 1 ) ); } _selectedMap[additionData] = true; } else if (typeof additionData != 'undefined' && typeof _optionRestore.xAxis != 'undefined' && typeof _optionRestore.yAxis != 'undefined' ) { // x轴类目 axisIdx = _optionRestore.series[seriesIdx].xAxisIndex || 0; if (typeof _optionRestore.xAxis[axisIdx].type == 'undefined' || _optionRestore.xAxis[axisIdx].type == 'category' ) { if (isHead) { _optionRestore.xAxis[axisIdx].data.unshift( additionData ); _optionBackup.xAxis[axisIdx].data.unshift( additionData ); if (!dataGrow) { _optionRestore.xAxis[axisIdx].data.pop(); _optionBackup.xAxis[axisIdx].data.pop(); } } else { _optionRestore.xAxis[axisIdx].data.push( additionData ); _optionBackup.xAxis[axisIdx].data.push( additionData ); if (!dataGrow) { _optionRestore.xAxis[axisIdx].data.shift(); _optionBackup.xAxis[axisIdx].data.shift(); } } } // y轴类目 axisIdx = _optionRestore.series[seriesIdx].yAxisIndex || 0; if (_optionRestore.yAxis[axisIdx].type == 'category') { if (isHead) { _optionRestore.yAxis[axisIdx].data.unshift( additionData ); _optionBackup.yAxis[axisIdx].data.unshift( additionData ); if (!dataGrow) { _optionRestore.yAxis[axisIdx].data.pop(); _optionBackup.yAxis[axisIdx].data.pop(); } } else { _optionRestore.yAxis[axisIdx].data.push( additionData ); _optionBackup.yAxis[axisIdx].data.push( additionData ); if (!dataGrow) { _optionRestore.yAxis[axisIdx].data.shift(); _optionBackup.yAxis[axisIdx].data.shift(); } } } } } } magicOption.legend && (magicOption.legend.selected = _selectedMap); // dataZoom同步数据 for (var i = 0, l = _chartList.length; i < l; i++) { if (magicOption.addDataAnimation && _chartList[i].addDataAnimation ) { _chartList[i].addDataAnimation(params); } if (_chartList[i].type == ecConfig.COMPONENT_TYPE_DATAZOOM ) { _chartList[i].silence(true); _chartList[i].init(magicOption); _chartList[i].silence(false); } } _island.refresh(magicOption); _toolbox.refresh(magicOption); setTimeout(function(){ _messageCenter.dispatch( ecConfig.EVENT.REFRESH, '', {option: magicOption} ); }, magicOption.addDataAnimation ? 500 : 0); return self; } /** * 获取当前dom */ function getDom() { return dom; } /** * 获取当前zrender实例,可用于添加额为的shape和深度控制 */ function getZrender() { return _zr; } /** * 获取Base64图片dataURL * @param {string} imgType 图片类型,支持png|jpeg,默认为png * @return imgDataURL */ function getDataURL(imgType) { if (!_canvasSupported) { return ''; } if (_chartList.length === 0) { // 渲染为图片 var imgId = 'IMG' + self.id; var img = document.getElementById(imgId); if (img) { return img.src; } } // 清除可能存在的tooltip元素 self.component.tooltip && self.component.tooltip.hideTip(); imgType = imgType || 'png'; if (imgType != 'png' && imgType != 'jpeg') { imgType = 'png'; } var bgColor = _option.backgroundColor && _option.backgroundColor.replace(' ','') == 'rgba(0,0,0,0)' ? '#fff' : _option.backgroundColor; return _zr.toDataURL('image/' + imgType, bgColor); } /** * 获取img * @param {string} imgType 图片类型,支持png|jpeg,默认为png * @return img dom */ function getImage(imgType) { var imgDom = document.createElement('img'); imgDom.src = getDataURL(imgType); imgDom.title = (_optionRestore.title && _optionRestore.title.text) || 'ECharts'; return imgDom; } /** * 获取多图联动的Base64图片dataURL * @param {string} imgType 图片类型,支持png|jpeg,默认为png * @return imgDataURL */ function getConnectedDataURL(imgType) { if (!isConnected()) { return getDataURL(imgType); } var tempDom; var domSize = [ dom.offsetLeft, dom.offsetTop, dom.offsetWidth, dom.offsetHeight ]; var imgList = { 'self' : { img : self.getDataURL(imgType), left : domSize[0], top : domSize[1], right : domSize[0] + domSize[2], bottom : domSize[1] + domSize[3] } }; var minLeft = imgList.self.left; var minTop = imgList.self.top; var maxRight = imgList.self.right; var maxBottom = imgList.self.bottom; for (var c in _connected) { tempDom = _connected[c].getDom(); domSize = [ tempDom.offsetLeft, tempDom.offsetTop, tempDom.offsetWidth, tempDom.offsetHeight ]; imgList[c] = { img : _connected[c].getDataURL(imgType), left : domSize[0], top : domSize[1], right : domSize[0] + domSize[2], bottom : domSize[1] + domSize[3] }; minLeft = Math.min(minLeft, imgList[c].left); minTop = Math.min(minTop, imgList[c].top); maxRight = Math.max(maxRight, imgList[c].right); maxBottom = Math.max(maxBottom, imgList[c].bottom); } var zrDom = document.createElement('div'); zrDom.style.position = 'absolute'; zrDom.style.left = '-4000px'; zrDom.style.width = (maxRight - minLeft) + 'px'; zrDom.style.height = (maxBottom - minTop) + 'px'; document.body.appendChild(zrDom); var zrImg = require('zrender').init(zrDom); for (var c in imgList) { zrImg.addShape({ shape:'image', style : { x : imgList[c].left - minLeft, y : imgList[c].top - minTop, image : imgList[c].img } }); } zrImg.render(); var bgColor = _option.backgroundColor && _option.backgroundColor.replace(' ','') == 'rgba(0,0,0,0)' ? '#fff' : _option.backgroundColor; var image = zrImg.toDataURL('image/png', bgColor); setTimeout(function(){ zrImg.dispose(); zrDom.parentNode.removeChild(zrDom); zrDom = null; },100); return image; } /** * 获取多图联动的img * @param {string} imgType 图片类型,支持png|jpeg,默认为png * @return img dom */ function getConnectedImage(imgType) { var imgDom = document.createElement('img'); imgDom.src = getConnectedDataURL(imgType); imgDom.title = (_optionRestore.title && _optionRestore.title.text) || 'ECharts'; return imgDom; } /** * 绑定事件 * @param {Object} eventName 事件名称 * @param {Object} eventListener 事件响应函数 */ function on(eventName, eventListener) { _messageCenter.bind(eventName, eventListener); return self; } /** * 解除事件绑定 * @param {Object} eventName 事件名称 * @param {Object} eventListener 事件响应函数 */ function un(eventName, eventListener) { _messageCenter.unbind(eventName, eventListener); return self; } /** * 多图联动 * @param connectTarget{ECharts | Array } connectTarget 联动目标 */ function connect(connectTarget) { if (!connectTarget) { return self; } if (!_connected) { _connected = {}; } if (connectTarget instanceof Array) { for (var i = 0, l = connectTarget.length; i < l; i++) { _connected[connectTarget[i].id] = connectTarget[i]; } } else { _connected[connectTarget.id] = connectTarget; } return self; } /** * 解除多图联动 * @param connectTarget{ECharts | Array } connectTarget 解除联动目标 */ function disConnect(connectTarget) { if (!connectTarget || !_connected) { return self; } if (connectTarget instanceof Array) { for (var i = 0, l = connectTarget.length; i < l; i++) { delete _connected[connectTarget[i].id]; } } else { delete _connected[connectTarget.id]; } for (var k in _connected) { return k, self; // 非空 } // 空,转为标志位 _connected = false; return self; } /** * 联动事件响应 */ function connectedEventHandler(param) { if (param.__echartsId != self.id) { // 来自其他联动图表的事件 _onevent(param); } } /** * 是否存在多图联动 */ function isConnected() { return !!_connected; } /** * 显示loading过渡 * @param {Object} loadingOption */ function showLoading(loadingOption) { _toolbox.hideDataView(); var zrUtil = require('zrender/tool/util'); loadingOption = loadingOption || {}; loadingOption.textStyle = loadingOption.textStyle || {}; var finalTextStyle = zrUtil.merge( zrUtil.clone(loadingOption.textStyle), _themeConfig.textStyle, { 'overwrite': false} ); loadingOption.textStyle.textFont = finalTextStyle.fontStyle + ' ' + finalTextStyle.fontWeight + ' ' + finalTextStyle.fontSize + 'px ' + finalTextStyle.fontFamily; loadingOption.textStyle.text = loadingOption.text || _themeConfig.loadingText; if (typeof loadingOption.x != 'undefined') { loadingOption.textStyle.x = loadingOption.x; } if (typeof loadingOption.y != 'undefined') { loadingOption.textStyle.y = loadingOption.y; } _zr.showLoading(loadingOption); return self; } /** * 隐藏loading过渡 */ function hideLoading() { _zr.hideLoading(); return self; } /** * 主题设置 */ function setTheme(theme) { var zrUtil = require('zrender/tool/util'); if (theme) { if (typeof theme === 'string') { // 默认主题 switch (theme) { case 'default': theme = require('./theme/default'); break; default: theme = require('./theme/default'); } } else { theme = theme || {}; } // 复位默认配置,别好心帮我改成_themeConfig = {}; for (var key in _themeConfig) { delete _themeConfig[key]; } for (var key in ecConfig) { _themeConfig[key] = zrUtil.clone(ecConfig[key]); } if (theme.color) { // 颜色数组随theme,不merge _themeConfig.color = []; } if (theme.symbolList) { // 默认标志图形类型列表,不merge _themeConfig.symbolList = []; } // 应用新主题 zrUtil.merge( _themeConfig, zrUtil.clone(theme), { 'overwrite': true, 'recursive': true } ); } if (!_canvasSupported) { // IE8- _themeConfig.textStyle.fontFamily = _themeConfig.textStyle.fontFamily2; } _optionRestore && self.restore(); } /** * 视图区域大小变化更新,不默认绑定,供使用方按需调用 */ function resize() { _zr.resize(); if (_option.renderAsImage && _canvasSupported) { // 渲染为图片重走render模式 _render(_option); return self; } // 停止动画 _zr.clearAnimation(); _island.resize(); _toolbox.resize(); // 先来后到,不能仅刷新自己,也不能在上一个循环中刷新,如坐标系数据改变会影响其他图表的大小 // 所以安顺序刷新各种图表,图表内部refresh优化无需更新则不更新~ for (var i = 0, l = _chartList.length; i < l; i++) { _chartList[i].resize && _chartList[i].resize(); } _zr.refresh(); _messageCenter.dispatch( ecConfig.EVENT.RESIZE ); return self; } /** * 清楚已渲染内容 ,clear后echarts实例可用 */ function clear() { _disposeChartList(); _zr.clear(); _option = {}; _optionBackup = {}; _optionRestore = {}; return self; } /** * 释放,dispose后echarts实例不可用 */ function dispose() { var key = dom.getAttribute(DOM_ATTRIBUTE_KEY); key && delete _instances[key]; _island.dispose(); _toolbox.dispose(); _messageCenter.unbind(); self.clear(); _zr.dispose(); _zr = null; self = null; return; } // 接口方法暴漏 self.setOption = setOption; self.setSeries = setSeries; self.addData = addData; self.getOption = getOption; self.getSeries = getSeries; self.getDom = getDom; self.getZrender = getZrender; self.getDataURL = getDataURL; self.getImage = getImage; self.getConnectedDataURL = getConnectedDataURL; self.getConnectedImage = getConnectedImage; self.on = on; self.un = un; self.connect = connect; self.disConnect = disConnect; self.connectedEventHandler = connectedEventHandler; self.isConnected = isConnected; self.showLoading = showLoading; self.hideLoading = hideLoading; self.setTheme = setTheme; self.resize = resize; self.refresh = refresh; self.restore = restore; self.clear = clear; self.dispose = dispose; } return self; }); define('echarts', ['echarts/echarts'], function (main) { return main; }); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:大规模散点图图形 * 可配图形属性: { // 基础属性 shape : 'symbol', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { pointList : {Array}, // 必须,二维数组,二维内容如下 x : {number}, // 必须,横坐标 y : {number}, // 必须,纵坐标数组 size : {number}, // 必须,半宽 type : {string=}, // 默认为'circle',图形类型 color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'symbol', id : '123456', zlevel : 1, style : { x : 200, y : [100,123,90,125], width : 150, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'echarts/util/shape/symbol',['require','zrender/tool/color','zrender/shape','zrender/shape/base','zrender/shape'],function(require) { function Symbol() { this.type = 'symbol'; } Symbol.prototype = { /** * 创建矩形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { var pointList = style.pointList; var rect = this.getRect(style); var ratio = window.devicePixelRatio || 1; // console.log(rect) // var ti = new Date(); // bbox取整 rect = { x : Math.floor(rect.x), y : Math.floor(rect.y), width : Math.floor(rect.width), height : Math.floor(rect.height) }; var pixels = ctx.getImageData( rect.x * ratio, rect.y * ratio, rect.width * ratio, rect.height * ratio ); var data = pixels.data; var idx; var zrColor = require('zrender/tool/color'); var color = zrColor.toArray(style.color); var r = color[0]; var g = color[1]; var b = color[2]; var width = rect.width; for (var i = 1, l = pointList.length; i < l; i++) { idx = ((Math.floor(pointList[i][0]) - rect.x) * ratio + (Math.floor(pointList[i][1])- rect.y) * width * ratio * ratio ) * 4; data[idx] = r; data[idx + 1] = g; data[idx + 2] = b; data[idx + 3] = 255; } ctx.putImageData(pixels, rect.x * ratio, rect.y * ratio); // console.log(new Date() - ti); return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var shape = require('zrender/shape'); return shape.get('polygon').getRect(style); }, isCover : function() { return false; } }; require('zrender/shape/base').derive(Symbol); require('zrender/shape').define('symbol', new Symbol()); return Symbol; } ); /** * echarts图表类:散点图 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/chart/scatter',['require','../component/base','./calculableBase','zrender/tool/color','../util/shape/symbol','../chart'],function(require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} series 数据 * @param {Object} component 组件 */ function Scatter(ecConfig, messageCenter, zr, option, component){ // 基类装饰 var ComponentBase = require('../component/base'); ComponentBase.call(this, ecConfig, zr); // 可计算特性装饰 var CalculableBase = require('./calculableBase'); CalculableBase.call(this, zr, option); var zrColor = require('zrender/tool/color'); var self = this; self.type = ecConfig.CHART_TYPE_SCATTER; var series; // 共享数据源,不要修改跟自己无关的项 var _zlevelBase = self.getZlevelBase(); var _sIndex2ColorMap = {}; // series默认颜色索引,seriesIndex索引到color var _symbol = ecConfig.symbolList; var _sIndex2ShapeMap = {}; // series图形类型,seriesIndex索引到_symbol function _buildShape() { self.selectedMap = {}; var legend = component.legend; var seriesArray = []; var serie; // 临时映射变量 var serieName; // 临时映射变量 var iconShape; var iconType; for (var i = 0, l = series.length; i < l; i++) { serie = series[i]; serieName = serie.name; if (serie.type == ecConfig.CHART_TYPE_SCATTER) { series[i] = self.reformOption(series[i]); _sIndex2ShapeMap[i] = self.query(serie, 'symbol') || _symbol[i % _symbol.length]; if (legend){ self.selectedMap[serieName] = legend.isSelected(serieName); _sIndex2ColorMap[i] = zrColor.alpha(legend.getColor(serieName), 0.5); iconShape = legend.getItemShape(serieName); if (iconShape) { // 回调legend,换一个更形象的icon iconShape.shape = 'icon'; var iconType = _sIndex2ShapeMap[i]; iconShape.style.brushType = iconType.match('empty') ? 'stroke' : 'both'; iconType = iconType.replace('empty', '').toLowerCase(); if (iconType.match('star')) { iconShape.style.n = (iconType.replace('star','') - 0) || 5; iconType = 'star'; } if (iconType.match('image')) { iconShape.style.image = iconType.replace( new RegExp('^image:\\/\\/'), '' ); iconShape.style.x += Math.round( (iconShape.style.width - iconShape.style.height) / 2 ); iconShape.style.width = iconShape.style.height; iconType = 'image'; } iconShape.style.iconType = iconType; legend.setItemShape(serieName, iconShape); } } else { self.selectedMap[serieName] = true; _sIndex2ColorMap[i] = zr.getColor(i); } if (self.selectedMap[serieName]) { seriesArray.push(i); } } } if (seriesArray.length === 0) { return; } _buildSeries(seriesArray); for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } /** * 构建类目轴为水平方向的散点图系列 */ function _buildSeries(seriesArray) { var seriesIndex; var serie; var data; var value; var xAxis; var yAxis; var pointList = {}; var x; var y; for (var j = 0, k = seriesArray.length; j < k; j++) { seriesIndex = seriesArray[j]; serie = series[seriesIndex]; if (serie.data.length === 0) { continue; } xAxis = component.xAxis.getAxis(serie.xAxisIndex || 0); yAxis = component.yAxis.getAxis(serie.yAxisIndex || 0); pointList[seriesIndex] = []; for (var i = 0, l = serie.data.length; i < l; i++) { data = serie.data[i]; value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; if (value == '-' || value.length < 2) { // 数据格式不符 continue; } x = xAxis.getCoord(value[0]); y = yAxis.getCoord(value[1]); pointList[seriesIndex].push([ x, // 横坐标 y, // 纵坐标 i, // 数据index data.name || '' // 名称 ]); } _markMap(xAxis, yAxis, serie.data, pointList[seriesIndex]); self.buildMark( serie, seriesIndex, component, { xMarkMap : _needMarkMap(seriesIndex) ? _markMap(xAxis, yAxis, serie.data, pointList[seriesIndex]) : {} } ); } // console.log(pointList) _buildPointList(pointList); } function _needMarkMap(seriesIndex) { var serie = series[seriesIndex]; var mark = []; if (serie.markPoint && serie.markPoint.data) { mark.push(serie.markPoint.data); } if (serie.markLine && serie.markLine.data) { mark.push(serie.markLine.data); } var data; var len = mark.length; while (len--) { data = mark[len]; for (var i = 0, l = data.length; i < l; i++) { if (data[i].type == 'max' || data[i].type == 'min' || data[i].type == 'average' ) { return true; } } } return false; } function _markMap(xAxis, yAxis, data, pointList) { var xMarkMap = { min0 : Number.POSITIVE_INFINITY, max0 : Number.NEGATIVE_INFINITY, sum0 : 0, counter0 : 0, average0 : 0, min1 : Number.POSITIVE_INFINITY, max1 : Number.NEGATIVE_INFINITY, sum1 : 0, counter1 : 0, average1 : 0 }; var value; for (var i = 0, l = pointList.length; i < l; i++) { /** x, // 横坐标 y, // 纵坐标 i, // 数据index data.name || '' // 名称 */ value = data[pointList[i][2]].value || data[pointList[i][2]]; // 横轴 if (xMarkMap.min0 > value[0]) { xMarkMap.min0 = value[0]; xMarkMap.minY0 = pointList[i][1]; xMarkMap.minX0 = pointList[i][0]; } if (xMarkMap.max0 < value[0]) { xMarkMap.max0 = value[0]; xMarkMap.maxY0 = pointList[i][1]; xMarkMap.maxX0 = pointList[i][0]; } xMarkMap.sum0 += value[0]; xMarkMap.counter0++; // 纵轴 if (xMarkMap.min1 > value[1]) { xMarkMap.min1 = value[1]; xMarkMap.minY1 = pointList[i][1]; xMarkMap.minX1 = pointList[i][0]; } if (xMarkMap.max1 < value[1]) { xMarkMap.max1 = value[1]; xMarkMap.maxY1 = pointList[i][1]; xMarkMap.maxX1 = pointList[i][0]; } xMarkMap.sum1 += value[1]; xMarkMap.counter1++; } var gridX = component.grid.getX(); var gridXend = component.grid.getXend(); var gridY = component.grid.getY(); var gridYend = component.grid.getYend(); xMarkMap.average0 = (xMarkMap.sum0 / xMarkMap.counter0).toFixed(2) - 0; var x = xAxis.getCoord(xMarkMap.average0); // 横轴平均纵向 xMarkMap.averageLine0 = [ [x, gridYend], [x, gridY] ]; xMarkMap.minLine0 = [ [xMarkMap.minX0, gridYend], [xMarkMap.minX0, gridY] ]; xMarkMap.maxLine0 = [ [xMarkMap.maxX0, gridYend], [xMarkMap.maxX0, gridY] ]; xMarkMap.average1 = (xMarkMap.sum1 / xMarkMap.counter1).toFixed(2) - 0; var y = yAxis.getCoord(xMarkMap.average1); // 纵轴平均横向 xMarkMap.averageLine1 = [ [gridX, y], [gridXend, y] ]; xMarkMap.minLine1 = [ [gridX, xMarkMap.minY1], [gridXend, xMarkMap.minY1] ]; xMarkMap.maxLine1 = [ [gridX, xMarkMap.maxY1], [gridXend, xMarkMap.maxY1] ]; return xMarkMap; } /** * 生成折线和折线上的拐点 */ function _buildPointList(pointList) { var serie; var seriesPL; var singlePoint; var shape; for (var seriesIndex in pointList) { serie = series[seriesIndex]; seriesPL = pointList[seriesIndex]; if (serie.large && serie.data.length > serie.largeThreshold) { self.shapeList.push(_getLargeSymbol( seriesPL, self.getItemStyleColor( self.query( serie, 'itemStyle.normal.color' ), seriesIndex, -1 ) || _sIndex2ColorMap[seriesIndex] )); continue; } /* * pointlist=[ * 0 x, * 1 y, * 2 数据index * 3 名称 * ] */ for (var i = 0, l = seriesPL.length; i < l; i++) { singlePoint = seriesPL[i]; shape = _getSymbol( seriesIndex, // seriesIndex singlePoint[2], // dataIndex singlePoint[3], // name singlePoint[0], // x singlePoint[1] // y ); shape && self.shapeList.push(shape); } } // console.log(self.shapeList) } /** * 生成折线图上的拐点图形 */ function _getSymbol(seriesIndex, dataIndex, name, x, y) { var serie = series[seriesIndex]; var data = serie.data[dataIndex]; var dataRange = component.dataRange; var rangColor; if (dataRange) { rangColor = isNaN(data[2]) ? _sIndex2ColorMap[seriesIndex] : dataRange.getColor(data[2]); if (!rangColor) { return null; } } else { rangColor = _sIndex2ColorMap[seriesIndex]; } var itemShape = self.getSymbolShape( serie, seriesIndex, data, dataIndex, name, x, y, _sIndex2ShapeMap[seriesIndex], rangColor, 'rgba(0,0,0,0)', 'vertical' ); itemShape.zlevel = _zlevelBase; itemShape._mark = false; // 非mark itemShape._main = true; return itemShape; } function _getLargeSymbol(pointList, nColor) { return { shape : 'symbol', zlevel : _zlevelBase, _main : true, hoverable: false, style : { pointList : pointList, color : nColor, strokeColor : nColor } }; } // 位置转换 function getMarkCoord(serie, seriesIndex, mpData, markCoordParams) { var xAxis = component.xAxis.getAxis(serie.xAxisIndex); var yAxis = component.yAxis.getAxis(serie.yAxisIndex); var pos; if (mpData.type && (mpData.type == 'max' || mpData.type == 'min' || mpData.type == 'average') ) { // 特殊值内置支持 // 默认取纵值 var valueIndex = typeof mpData.valueIndex != 'undefined' ? mpData.valueIndex : 1; pos = [ markCoordParams.xMarkMap[mpData.type + 'X' + valueIndex], markCoordParams.xMarkMap[mpData.type + 'Y' + valueIndex], markCoordParams.xMarkMap[mpData.type + 'Line' + valueIndex], markCoordParams.xMarkMap[mpData.type + valueIndex] ]; } else { pos = [ typeof mpData.xAxis != 'string' && xAxis.getCoordByIndex ? xAxis.getCoordByIndex(mpData.xAxis || 0) : xAxis.getCoord(mpData.xAxis || 0), typeof mpData.yAxis != 'string' && yAxis.getCoordByIndex ? yAxis.getCoordByIndex(mpData.yAxis || 0) : yAxis.getCoord(mpData.yAxis || 0) ]; } return pos; } /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newZr * @param {Object} newSeries * @param {Object} newComponent */ function init(newOption, newComponent) { component = newComponent; refresh(newOption); } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; series = option.series; } self.clear(); _buildShape(); } /** * 值域响应 * @param {Object} param * @param {Object} status */ function ondataRange(param, status) { if (component.dataRange) { refresh(); status.needRefresh = true; } return; } /** * 动画设定 */ function animation() { var duration = self.query(option, 'animationDuration'); var easing = self.query(option, 'animationEasing'); var x; var y; var serie; for (var i = 0, l = self.shapeList.length; i < l; i++) { if (self.shapeList[i]._main) { if (self.shapeList[i].shape == 'symbol') { continue; } serie = series[self.shapeList[i]._seriesIndex]; x = self.shapeList[i]._x || 0; y = self.shapeList[i]._y || 0; zr.modShape( self.shapeList[i].id, { scale : [0, 0, x, y] }, true ); zr.animate(self.shapeList[i].id, '') .when( (self.query(serie,'animationDuration') || duration), {scale : [1, 1, x, y]} ) .start( self.query(serie, 'animationEasing') || easing ); } } self.animationMark(duration, easing); } // 重载基类方法 self.getMarkCoord = getMarkCoord; self.animation = animation; self.init = init; self.refresh = refresh; self.ondataRange = ondataRange; init(option, component); } // 动态扩展zrender shape:symbol require('../util/shape/symbol'); // 自注册 require('../chart').define('scatter', Scatter); return Scatter; }); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:蜡烛 * 可配图形属性: { // 基础属性 shape : 'candle', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { x : {number}, // 必须,横坐标 y : {Array}, // 必须,纵坐标数组 width : {number}, // 必须,宽度 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'candle', id : '123456', zlevel : 1, style : { x : 200, y : [100,123,90,125], width : 150, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'echarts/util/shape/candle',['require','zrender/tool/matrix','zrender/shape/base','zrender/shape'],function(require) { var matrix = require('zrender/tool/matrix'); function Candle() { this.type = 'candle'; } Candle.prototype = { _numberOrder : function(a, b) { return b - a; }, /** * 创建矩形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { style.y.sort(this._numberOrder); ctx.moveTo(style.x, style.y[3]); ctx.lineTo(style.x, style.y[2]); ctx.moveTo(style.x - style.width / 2, style.y[2]); ctx.rect( style.x - style.width / 2, style.y[2], style.width, style.y[1] - style.y[2] ); ctx.moveTo(style.x, style.y[1]); ctx.lineTo(style.x, style.y[0]); return; }, /** * 返回矩形区域,用于局部刷新和文字定位 * @param {Object} style */ getRect : function(style) { var lineWidth; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } else { lineWidth = 0; } return { x : Math.round(style.x - style.width / 2 - lineWidth / 2), y : Math.round(style.y[3] - lineWidth / 2), width : style.width + lineWidth, height : style.y[0] - style.y[3] + lineWidth }; }, isCover : function(e, x, y) { //对鼠标的坐标也做相同的变换 if(e.__needTransform && e._transform){ var inverseMatrix = []; matrix.invert(inverseMatrix, e._transform); var originPos = [x, y]; matrix.mulVector(originPos, inverseMatrix, [x, y, 1]); if (x == originPos[0] && y == originPos[1]) { // 避免外部修改导致的__needTransform不准确 if (Math.abs(e.rotation[0]) > 0.0001 || Math.abs(e.position[0]) > 0.0001 || Math.abs(e.position[1]) > 0.0001 || Math.abs(e.scale[0] - 1) > 0.0001 || Math.abs(e.scale[1] - 1) > 0.0001 ) { e.__needTransform = true; } else { e.__needTransform = false; } } x = originPos[0]; y = originPos[1]; } // 快速预判并保留判断矩形 var rect; if (e.style.__rect) { rect = e.style.__rect; } else { rect = this.getRect(e.style); rect = [ rect.x, rect.x + rect.width, rect.y, rect.y + rect.height ]; e.style.__rect = rect; } if (x >= rect[0] && x <= rect[1] && y >= rect[2] && y <= rect[3] ) { // 矩形内 return true; } else { return false; } } }; require('zrender/shape/base').derive(Candle); require('zrender/shape').define('candle', new Candle()); return Candle; } ); /** * echarts图表类:K线图 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/chart/k',['require','../component/base','./calculableBase','../util/ecData','../util/shape/candle','../chart'],function(require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} series 数据 * @param {Object} component 组件 */ function K(ecConfig, messageCenter, zr, option, component){ // 基类装饰 var ComponentBase = require('../component/base'); ComponentBase.call(this, ecConfig, zr); // 可计算特性装饰 var CalculableBase = require('./calculableBase'); CalculableBase.call(this, zr, option); var ecData = require('../util/ecData'); var self = this; self.type = ecConfig.CHART_TYPE_K; var series; // 共享数据源,不要修改跟自己无关的项 var _zlevelBase = self.getZlevelBase(); function _buildShape() { self.selectedMap = {}; // 水平垂直双向series索引 ,position索引到seriesIndex var _position2sIndexMap = { top : [], bottom : [] }; var xAxis; for (var i = 0, l = series.length; i < l; i++) { if (series[i].type == ecConfig.CHART_TYPE_K) { series[i] = self.reformOption(series[i]); xAxis = component.xAxis.getAxis(series[i].xAxisIndex); if (xAxis.type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY ) { _position2sIndexMap[xAxis.getPosition()].push(i); } } } //console.log(_position2sIndexMap) for (var position in _position2sIndexMap) { if (_position2sIndexMap[position].length > 0) { _buildSinglePosition( position, _position2sIndexMap[position] ); } } for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } /** * 构建单个方向上的K线图 * * @param {number} seriesIndex 系列索引 */ function _buildSinglePosition(position, seriesArray) { var mapData = _mapData(seriesArray); var locationMap = mapData.locationMap; var maxDataLength = mapData.maxDataLength; if (maxDataLength === 0 || locationMap.length === 0) { return; } _buildHorizontal(maxDataLength, locationMap); for (var i = 0, l = seriesArray.length; i < l; i++) { self.buildMark( series[seriesArray[i]], seriesArray[i], component ); } } /** * 数据整形 * 数组位置映射到系列索引 */ function _mapData(seriesArray) { var serie; // 临时映射变量 var serieName; // 临时映射变量 var legend = component.legend; var locationMap = []; // 需要返回的东西:数组位置映射到系列索引 var maxDataLength = 0; // 需要返回的东西:最大数据长度 // 计算需要显示的个数和分配位置并记在下面这个结构里 for (var i = 0, l = seriesArray.length; i < l; i++) { serie = series[seriesArray[i]]; serieName = serie.name; if (legend){ self.selectedMap[serieName] = legend.isSelected(serieName); } else { self.selectedMap[serieName] = true; } if (self.selectedMap[serieName]) { locationMap.push(seriesArray[i]); } // 兼职帮算一下最大长度 maxDataLength = Math.max(maxDataLength, serie.data.length); } return { locationMap : locationMap, maxDataLength : maxDataLength }; } /** * 构建类目轴为水平方向的K线图系列 */ function _buildHorizontal(maxDataLength, locationMap) { // 确定类目轴和数值轴,同一方向随便找一个即可 var seriesIndex; var serie; var xAxisIndex; var categoryAxis; var yAxisIndex; // 数值轴各异 var valueAxis; // 数值轴各异 var pointList = {}; var candleWidth; var data; var value; var barMaxWidth; for (var j = 0, k = locationMap.length; j < k; j++) { seriesIndex = locationMap[j]; serie = series[seriesIndex]; xAxisIndex = serie.xAxisIndex || 0; categoryAxis = component.xAxis.getAxis(xAxisIndex); candleWidth = serie.barWidth || Math.floor(categoryAxis.getGap() / 2); barMaxWidth = serie.barMaxWidth; if (barMaxWidth && barMaxWidth < candleWidth) { candleWidth = barMaxWidth; } yAxisIndex = serie.yAxisIndex || 0; valueAxis = component.yAxis.getAxis(yAxisIndex); pointList[seriesIndex] = []; for (var i = 0, l = maxDataLength; i < l; i++) { if (typeof categoryAxis.getNameByIndex(i) == 'undefined' ) { // 系列数据超出类目轴长度 break; } data = serie.data[i]; value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; if (value == '-' || value.length != 4) { // 数据格式不符 continue; } pointList[seriesIndex].push([ categoryAxis.getCoordByIndex(i), // 横坐标 candleWidth, valueAxis.getCoord(value[0]), // 纵坐标:开盘 valueAxis.getCoord(value[1]), // 纵坐标:收盘 valueAxis.getCoord(value[2]), // 纵坐标:最低 valueAxis.getCoord(value[3]), // 纵坐标:最高 i, // 数据index categoryAxis.getNameByIndex(i) // 类目名称 ]); } } // console.log(pointList) _buildKLine(pointList); } /** * 生成K线 */ function _buildKLine(pointList) { // normal: var nLineWidth; var nLineColor; var nLineColor0; // 阴线 var nColor; var nColor0; // 阴线 // emphasis: var eLineWidth; var eLineColor; var eLineColor0; var eColor; var eColor0; var serie; var queryTarget; var data; var seriesPL; var singlePoint; var candleType; for (var seriesIndex = 0, len = series.length; seriesIndex < len; seriesIndex++ ) { serie = series[seriesIndex]; seriesPL = pointList[seriesIndex]; if (serie.type == ecConfig.CHART_TYPE_K && typeof seriesPL != 'undefined' ) { // 多级控制 queryTarget = serie; nLineWidth = self.query( queryTarget, 'itemStyle.normal.lineStyle.width' ); nLineColor = self.query( queryTarget, 'itemStyle.normal.lineStyle.color' ); nLineColor0 = self.query( queryTarget, 'itemStyle.normal.lineStyle.color0' ); nColor = self.query( queryTarget, 'itemStyle.normal.color' ); nColor0 = self.query( queryTarget, 'itemStyle.normal.color0' ); eLineWidth = self.query( queryTarget, 'itemStyle.emphasis.lineStyle.width' ); eLineColor = self.query( queryTarget, 'itemStyle.emphasis.lineStyle.color' ); eLineColor0 = self.query( queryTarget, 'itemStyle.emphasis.lineStyle.color0' ); eColor = self.query( queryTarget, 'itemStyle.emphasis.color' ); eColor0 = self.query( queryTarget, 'itemStyle.emphasis.color0' ); /* * pointlist=[ * 0 x, * 1 width, * 2 y0, * 3 y1, * 4 y2, * 5 y3, * 6 dataIndex, * 7 categoryName * ] */ for (var i = 0, l = seriesPL.length; i < l; i++) { singlePoint = seriesPL[i]; data = serie.data[singlePoint[6]]; queryTarget = data; candleType = singlePoint[3] < singlePoint[2]; self.shapeList.push(_getCandle( seriesIndex, // seriesIndex singlePoint[6], // dataIndex singlePoint[7], // name singlePoint[0], // x singlePoint[1], // width singlePoint[2], // y开盘 singlePoint[3], // y收盘 singlePoint[4], // y最低 singlePoint[5], // y最高 // 填充颜色 candleType ? (self.query( // 阳 queryTarget, 'itemStyle.normal.color' ) || nColor) : (self.query( // 阴 queryTarget, 'itemStyle.normal.color0' ) || nColor0), // 线宽 self.query( queryTarget, 'itemStyle.normal.lineStyle.width' ) || nLineWidth, // 线色 candleType ? (self.query( // 阳 queryTarget, 'itemStyle.normal.lineStyle.color' ) || nLineColor) : (self.query( // 阴 queryTarget, 'itemStyle.normal.lineStyle.color0' ) || nLineColor0), //------------高亮 // 填充颜色 candleType ? (self.query( // 阳 queryTarget, 'itemStyle.emphasis.color' ) || eColor || nColor) : (self.query( // 阴 queryTarget, 'itemStyle.emphasis.color0' ) || eColor0 || nColor0), // 线宽 self.query( queryTarget, 'itemStyle.emphasis.lineStyle.width' ) || eLineWidth || nLineWidth, // 线色 candleType ? (self.query( // 阳 queryTarget, 'itemStyle.emphasis.lineStyle.color' ) || eLineColor || nLineColor) : (self.query( // 阴 queryTarget, 'itemStyle.emphasis.lineStyle.color0' ) || eLineColor0 || nLineColor0) )); } } } // console.log(self.shapeList) } /** * 生成K线图上的图形 */ function _getCandle( seriesIndex, dataIndex, name, x, width, y0, y1, y2, y3, nColor, nLinewidth, nLineColor, eColor, eLinewidth, eLineColor ) { var itemShape = { shape : 'candle', zlevel : _zlevelBase, clickable: true, style : { x : x, y : [y0, y1, y2, y3], width : width, color : nColor, strokeColor : nLineColor, lineWidth : nLinewidth, brushType : 'both' }, highlightStyle : { color : eColor, strokeColor : eLineColor, lineWidth : eLinewidth }, _seriesIndex: seriesIndex }; ecData.pack( itemShape, series[seriesIndex], seriesIndex, series[seriesIndex].data[dataIndex], dataIndex, name ); return itemShape; } // 位置转换 function getMarkCoord(serie, seriesIndex, mpData) { var xAxis = component.xAxis.getAxis(serie.xAxisIndex); var yAxis = component.yAxis.getAxis(serie.yAxisIndex); return [ typeof mpData.xAxis != 'string' && xAxis.getCoordByIndex ? xAxis.getCoordByIndex(mpData.xAxis || 0) : xAxis.getCoord(mpData.xAxis || 0), typeof mpData.yAxis != 'string' && yAxis.getCoordByIndex ? yAxis.getCoordByIndex(mpData.yAxis || 0) : yAxis.getCoord(mpData.yAxis || 0) ]; } /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newSeries * @param {Object} newComponent */ function init(newOption, newComponent) { component = newComponent; refresh(newOption); } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; series = option.series; } self.clear(); _buildShape(); } /** * 动画设定 */ function addDataAnimation(params) { var aniMap = {}; // seriesIndex索引参数 for (var i = 0, l = params.length; i < l; i++) { aniMap[params[i][0]] = params[i]; } var x; var dx; var y; var serie; var seriesIndex; var dataIndex; for (var i = 0, l = self.shapeList.length; i < l; i++) { seriesIndex = self.shapeList[i]._seriesIndex; if (aniMap[seriesIndex] && !aniMap[seriesIndex][3]) { // 有数据删除才有移动的动画 if (self.shapeList[i].shape == 'candle') { dataIndex = ecData.get(self.shapeList[i], 'dataIndex'); serie = series[seriesIndex]; if (aniMap[seriesIndex][2] && dataIndex == serie.data.length - 1 ) { // 队头加入删除末尾 zr.delShape(self.shapeList[i].id); continue; } else if (!aniMap[seriesIndex][2] && dataIndex === 0) { // 队尾加入删除头部 zr.delShape(self.shapeList[i].id); continue; } dx = component.xAxis.getAxis( serie.xAxisIndex || 0 ).getGap(); x = aniMap[seriesIndex][2] ? dx : -dx; y = 0; zr.animate(self.shapeList[i].id, '') .when( 500, {position : [x, y]} ) .start(); } } } } /** * 动画设定 */ function animation() { var duration = self.query(option, 'animationDuration'); var easing = self.query(option, 'animationEasing'); var x; var y; var serie; for (var i = 0, l = self.shapeList.length; i < l; i++) { if (self.shapeList[i].shape == 'candle') { serie = series[self.shapeList[i]._seriesIndex]; x = self.shapeList[i].style.x; y = self.shapeList[i].style.y[0]; zr.modShape( self.shapeList[i].id, { scale : [1, 0, x, y] }, true ); zr.animate(self.shapeList[i].id, '') .when( (self.query(serie,'animationDuration') || duration), {scale : [1, 1, x, y]} ) .start( self.query(serie, 'animationEasing') || easing ); } } self.animationMark(duration, easing); } // 重载基类方法 self.getMarkCoord = getMarkCoord; self.animation = animation; self.init = init; self.refresh = refresh; self.addDataAnimation = addDataAnimation; init(option, component); } // 动态扩展zrender shape:candle require('../util/shape/candle'); // 图表注册 require('../chart').define('k', K); return K; }); /** * echarts图表类:雷达图 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Neil (杨骥, yangji01@baidu.com) * */ define('echarts/chart/radar',['require','../component/base','./calculableBase','../util/ecData','zrender/tool/color','../util/accMath','../chart'],function(require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} series 数据 * @param {Object} component 组件 */ function Radar(ecConfig, messageCenter, zr, option, component) { // 基类装饰 var ComponentBase = require('../component/base'); ComponentBase.call(this, ecConfig, zr); // 可计算特性装饰 var CalculableBase = require('./calculableBase'); CalculableBase.call(this, zr, option); var ecData = require('../util/ecData'); var zrColor = require('zrender/tool/color'); var self = this; self.type = ecConfig.CHART_TYPE_RADAR; var series; // 共享数据源,不要修改跟自己无关的项 var serie; var _zlevelBase = self.getZlevelBase(); var _queryTarget; var _dropBoxList; var _symbol = ecConfig.symbolList; var _radarDataCounter; /** * 绘制图形 */ function _buildShape() { var legend = component.legend; self.selectedMap = {}; _dropBoxList = []; _radarDataCounter = 0; var serieName; for (var i = 0, l = series.length; i < l ; i ++) { if (series[i].type == ecConfig.CHART_TYPE_RADAR) { serie = self.reformOption(series[i]); serieName = serie.name || ''; // 系列图例开关 self.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true; if (self.selectedMap[serieName]) { _queryTarget = [serie, option]; // 添加可拖拽提示框,多系列共用一个极坐标,第一个优先 if (self.deepQuery(_queryTarget, 'calculable')) { _addDropBox(i); } _buildSingleRadar(i); self.buildMark( series[i], i, component ); } } } for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } /** * 构建数据图形 * @param {number} 序列的index */ function _buildSingleRadar(index) { var legend = component.legend; var iconShape; var data = serie.data; var defaultColor; var name; var pointList; var calculable = self.deepQuery(_queryTarget, 'calculable'); for (var i = 0; i < data.length; i ++) { name = data[i].name || ''; // 图例开关 self.selectedMap[name] = legend ? legend.isSelected(name) : true; if (!self.selectedMap[name]) { continue; } // 默认颜色策略 if (legend) { // 有图例则从图例中获取颜色定义 defaultColor = legend.getColor(name); iconShape = legend.getItemShape(name); if (iconShape) { // 回调legend,换一个更形象的icon iconShape.style.brushType = self.deepQuery( [data[i], serie], 'itemStyle.normal.areaStyle' ) ? 'both' : 'stroke'; legend.setItemShape(name, iconShape); } } else { // 全局颜色定义 defaultColor = zr.getColor(i); } pointList = _getPointList(serie.polarIndex, data[i]); // 添加拐点形状 _addSymbol(pointList, defaultColor, i, index); // 添加数据形状 _addDataShape( pointList, defaultColor, data[i], index, i, calculable ); _radarDataCounter++; } } /** * 获取数据的点集 * @param {number} polarIndex * @param {Array} 处理的数据 * @return {Array>} 点集 */ function _getPointList(polarIndex, dataArr) { var pointList = []; var vector; var polar = component.polar; for (var i = 0, l = dataArr.value.length; i < l; i++) { vector = polar.getVector(polarIndex, i, dataArr.value[i]); if (vector) { pointList.push(vector); } } return pointList; } /** * 添加拐点 * @param {Array>} pointList 点集 * @param {string} defaultColor 默认填充颜色 * @param {object} data 数据 * @param {number} serieIndex */ function _addSymbol(pointList, defaultColor, dataIndex, seriesIndex) { var itemShape; for (var i = 0, l = pointList.length; i < l; i++) { itemShape = self.getSymbolShape( series[seriesIndex], seriesIndex, series[seriesIndex].data[dataIndex], dataIndex, '', pointList[i][0], // x pointList[i][1], // y _symbol[_radarDataCounter % _symbol.length], defaultColor, '#fff', 'vertical' ); itemShape.zlevel = _zlevelBase + 1; self.shapeList.push(itemShape); } } /** * 添加数据图形 * @param {Array>} pointList 点集 * @param {string} defaultColor 默认填充颜色 * @param {object} data 数据 * @param {number} serieIndex * @param {number} dataIndex * @param {boolean} calcalable */ function _addDataShape( pointList, defaultColor, data, seriesIndex, dataIndex, calculable ) { // 多级控制 var queryTarget = [data, serie]; var nColor = self.getItemStyleColor( self.deepQuery( queryTarget, 'itemStyle.normal.color' ), seriesIndex, dataIndex, data ); var nLineWidth = self.deepQuery( queryTarget, 'itemStyle.normal.lineStyle.width' ); var nLineType = self.deepQuery( queryTarget, 'itemStyle.normal.lineStyle.type' ); var nAreaColor = self.deepQuery( queryTarget, 'itemStyle.normal.areaStyle.color' ); var nIsAreaFill = self.deepQuery( queryTarget, 'itemStyle.normal.areaStyle' ); var shape = { shape : 'polygon', zlevel : _zlevelBase, style : { pointList : pointList, brushType : nIsAreaFill ? 'both' : 'stroke', color : nAreaColor || nColor || zrColor.alpha(defaultColor,0.5), strokeColor : nColor || defaultColor, lineWidth : nLineWidth, lineType : nLineType }, highlightStyle : { brushType : self.deepQuery( queryTarget, 'itemStyle.emphasis.areaStyle' ) || nIsAreaFill ? 'both' : 'stroke', color : self.deepQuery( queryTarget, 'itemStyle.emphasis.areaStyle.color' ) || nAreaColor || nColor || zrColor.alpha(defaultColor,0.5), strokeColor : self.getItemStyleColor( self.deepQuery( queryTarget, 'itemStyle.emphasis.color' ), seriesIndex, dataIndex, data ) || nColor || defaultColor, lineWidth : self.deepQuery( queryTarget, 'itemStyle.emphasis.lineStyle.width' ) || nLineWidth, lineType : self.deepQuery( queryTarget, 'itemStyle.emphasis.lineStyle.type' ) || nLineType } }; ecData.pack( shape, series[seriesIndex], // 系列 seriesIndex, // 系列索引 data, // 数据 dataIndex, // 数据索引 data.name, // 数据名称 // 附加指标信息 component.polar.getIndicator(series[seriesIndex].polarIndex) ); if (calculable) { shape.draggable = true; self.setCalculable(shape); } self.shapeList.push(shape); } /** * 增加外围接受框 * @param {number} serie的序列 */ function _addDropBox(index) { var polarIndex = self.deepQuery( _queryTarget, 'polarIndex' ); if (!_dropBoxList[polarIndex]) { var shape = component.polar.getDropBox(polarIndex); shape.zlevel = _zlevelBase; self.setCalculable(shape); ecData.pack(shape, series, index, undefined, -1); self.shapeList.push(shape); _dropBoxList[polarIndex] = true; } } /** * 数据项被拖拽出去,重载基类方法 */ function ondragend(param, status) { if (!self.isDragend || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } var target = param.target; // 被拖拽图形元素 var seriesIndex = ecData.get(target, 'seriesIndex'); var dataIndex = ecData.get(target, 'dataIndex'); // 被拖拽的图形是饼图sector,删除被拖拽走的数据 component.legend && component.legend.del( series[seriesIndex].data[dataIndex].name ); series[seriesIndex].data.splice(dataIndex, 1); // 别status = {}赋值啊!! status.dragOut = true; status.needRefresh = true; // 处理完拖拽事件后复位 self.isDragend = false; return; } /** * 数据项被拖拽进来, 重载基类方法 */ function ondrop(param, status) { if (!self.isDrop || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } var target = param.target; // 拖拽安放目标 var dragged = param.dragged; // 当前被拖拽的图形对象 var seriesIndex = ecData.get(target, 'seriesIndex'); var dataIndex = ecData.get(target, 'dataIndex'); var data; var legend = component.legend; var value; if (dataIndex == -1) { data = { value : ecData.get(dragged, 'value'), name : ecData.get(dragged, 'name') }; series[seriesIndex].data.push(data); legend && legend.add( data.name, dragged.style.color || dragged.style.strokeColor ); } else { // 数据被拖拽到某个数据项上,数据修改 var accMath = require('../util/accMath'); data = series[seriesIndex].data[dataIndex]; legend && legend.del(data.name); data.name += option.nameConnector + ecData.get(dragged, 'name'); value = ecData.get(dragged, 'value'); for (var i = 0 ; i < value.length; i ++) { data.value[i] = accMath.accAdd(data.value[i], value[i]); } legend && legend.add( data.name, dragged.style.color || dragged.style.strokeColor ); } // 别status = {}赋值啊!! status.dragIn = status.dragIn || true; // 处理完拖拽事件后复位 self.isDrop = false; return; } /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newZr * @param {Object} newSeries * @param {Object} newComponent */ function init(newOption, newComponent) { component = newComponent; refresh(newOption); } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; series = option.series; } self.clear(); _buildShape(); } function animation() { var duration = self.query(option, 'animationDuration'); var easing = self.query(option, 'animationEasing'); var dataIndex; var seriesIndex; var data; var serie; var polarIndex; var polar = component.polar; var center; var item; var x; var y; for (var i = 0, l = self.shapeList.length; i < l; i++) { if (self.shapeList[i].shape == 'polygon') { item = self.shapeList[i]; seriesIndex = ecData.get(item, 'seriesIndex'); dataIndex = ecData.get(item, 'dataIndex'); serie = series[seriesIndex]; data = serie.data[dataIndex]; polarIndex = self.deepQuery( [data, serie, option], 'polarIndex'); center = polar.getCenter(polarIndex); x = center[0]; y = center[1]; zr.modShape( self.shapeList[i].id, { scale : [0.1, 0.1, x, y] }, true ); zr.animate(item.id, '') .when( (self.query(serie,'animationDuration') || duration) + dataIndex * 100, {scale : [1, 1, x, y]} ) .start( self.query(serie, 'animationEasing') || easing ); } } self.animationMark(duration, easing); } // 重载基类方法 self.animation = animation; self.init = init; self.refresh = refresh; self.ondrop = ondrop; self.ondragend = ondragend; init(option, component); } // 图表注册 require('../chart').define('radar', Radar); return Radar; }); /** * zrender * * @author pissang (https://github.com/pissang) * * shape类:chord * 可配图形属性: { // 基础属性 shape : 'candle', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { center : {array}, source0 : {number}, source1 : {number}, target0 : {number}, target1 : {number}, r : {number}, brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'candle', id : '123456', zlevel : 1, style : { x : 200, y : [100,123,90,125], width : 150, color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define('echarts/util/shape/chord',['require','zrender/tool/util','zrender/shape/base','zrender/shape'],function(require) { var util = require('zrender/tool/util'); function ChordShape() { this.type = 'chord'; } var _ctx = util.getContext(); ChordShape.prototype = { // center, source0, source1, target0, target1, r buildPath : function(ctx, style) { var PI2 = Math.PI * 2; var cx = style.center[0]; var cy = style.center[1]; var r = style.r; var s0 = style.source0 / 180 * Math.PI; var s1 = style.source1 / 180 * Math.PI; var t0 = style.target0 / 180 * Math.PI; var t1 = style.target1 / 180 * Math.PI; var sx0 = cx + Math.cos(PI2 - s0) * r; var sy0 = cy - Math.sin(PI2 - s0) * r; var sx1 = cx + Math.cos(PI2 - s1) * r; var sy1 = cy - Math.sin(PI2 - s1) * r; var tx0 = cx + Math.cos(PI2 - t0) * r; var ty0 = cy - Math.sin(PI2 - t0) * r; var tx1 = cx + Math.cos(PI2 - t1) * r; var ty1 = cy - Math.sin(PI2 - t1) * r; ctx.moveTo(sx0, sy0); ctx.arc(cx, cy, style.r, s0, s1, false); ctx.bezierCurveTo( (cx - sx1) * 0.70 + sx1, (cy - sy1) * 0.70 + sy1, (cx - tx0) * 0.70 + tx0, (cy - ty0) * 0.70 + ty0, tx0, ty0 ); // Chord to self if (style.source0 === style.target0 && style.source1 === style.target1) { return; } ctx.arc(cx, cy, style.r, t0, t1, false); ctx.bezierCurveTo( (cx - tx1) * 0.70 + tx1, (cy - ty1) * 0.70 + ty1, (cx - sx0) * 0.70 + sx0, (cy - sy0) * 0.70 + sy0, sx0, sy0 ); }, getRect : function(){ return { x : 0, y : 0, width : 0, height : 0 }; }, isCover : function(e, x, y) { if (!_ctx.isPointInPath) { // In ie return false; } //对鼠标的坐标也做相同的变换 if(e.__needTransform && e._transform){ var inverseMatrix = []; matrix.invert(inverseMatrix, e._transform); var originPos = [x, y]; matrix.mulVector(originPos, inverseMatrix, [x, y, 1]); if (x == originPos[0] && y == originPos[1]) { // 避免外部修改导致的__needTransform不准确 if (Math.abs(e.rotation[0]) > 0.0001 || Math.abs(e.position[0]) > 0.0001 || Math.abs(e.position[1]) > 0.0001 || Math.abs(e.scale[0] - 1) > 0.0001 || Math.abs(e.scale[1] - 1) > 0.0001 ) { e.__needTransform = true; } else { e.__needTransform = false; } } x = originPos[0]; y = originPos[1]; } _ctx.beginPath(); ChordShape.prototype.buildPath.call(null, _ctx, e.style); _ctx.closePath(); return _ctx.isPointInPath(x, y); } }; require('zrender/shape/base').derive(ChordShape); require('zrender/shape').define('chord', new ChordShape()); return ChordShape; }); define('echarts/util/kwargs',[],function(){ function kwargs(func, defaults) { /*jshint maxlen : 200*/ var removeComments = new RegExp('(\\/\\*[\\w\\\'\\,\\(\\)\\s\\r\\n\\*]*\\*\\/)|(\\/\\/[\\w\\s\\\'][^\\n\\r]*$)|(\\/]*>)', 'gim'); var removeWhitespc = new RegExp('\\s+', 'gim'); var matchSignature = new RegExp('function.*?\\((.*?)\\)', 'i'); // get the argument names from function source var names = func.toString() .replace(removeComments, '') .replace(removeWhitespc, '') .match(matchSignature)[1] .split(','); // Check the existance of default, if not create an object if(defaults !== Object(defaults)){ defaults = {}; } return function() { var args = Array.prototype.slice.call(arguments); var kwargs = args[args.length - 1]; // Check the existance of the kwargs if (kwargs && kwargs.constructor === Object) { args.pop(); }else{ kwargs = {}; } // Fill the arguments and apply them for (var i = 0; i < names.length; i++) { var name = names[i]; if (name in kwargs) { args[i] = kwargs[name]; }else if(name in defaults && args[i] === undefined){ args[i] = defaults[name]; } } return func.apply(this, args); }; } // As function prototype // Function.prototype.kwargs = kwargs; return kwargs; }); /** * Numpy like n-dimensional array proccessing class * http://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html * * @author pissang (https://github.com/pissang/) */ define('echarts/util/ndarray',['require','./kwargs'],function(require) { var kwargs = require('./kwargs'); var ArraySlice = Array.prototype.slice; // Polyfill of Typed Array this.Int32Array = window.Int32Array || Array; this.Int16Array = window.Int16Array || Array; this.Int8Array = window.Int8Array || Array; this.Uint32Array = window.Uint32Array || Array; this.Uint16Array = window.Uint16Array || Array; this.Uint8Array = window.Uint8Array || Array; this.Float32Array = window.Float32Array || Array; this.Float64Array = window.Float64Array || Array; // Map of numpy dtype and typed array // http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#arrays-dtypes // http://www.khronos.org/registry/typedarray/specs/latest/ var ArrayConstructor = { 'int32' : this.Int32Array, 'int16' : this.Int16Array, 'int8' : this.Int8Array, 'uint32' : this.Uint32Array, 'uint16' : this.Uint16Array, 'uint8' : this.Uint8Array, // 'uint8c' is not existed in numpy 'uint8c' : this.Uint8ClampedArray, 'float32' : this.Float32Array, 'float64' : this.Float64Array, 'number' : Array }; var dTypeStrideMap = { 'int32' : 4, 'int16' : 2, 'int8' : 1, 'uint32' : 4, 'uint16' : 2, 'uint8' : 1, 'uint8c' : 1, 'float32' : 4, 'float64' : 8, // Consider array stride is 1 'number' : 1 }; var E_ADD = 0; var E_SUB = 1; var E_MUL = 2; var E_DIV = 3; var E_MOD = 4; var E_AND = 5; var E_OR = 6; var E_XOR = 7; var E_EQL = 8; function guessDataType(arr) { if (typeof(arr) === 'undefined') { return 'number'; } switch(Object.prototype.toString.call(arr)) { case '[object Int32Array]': return 'int32'; case '[object Int16Array]': return 'int16'; case '[object Int8Array]': return 'int8'; case '[object Uint32Array]': return 'uint32'; case '[object Uint16Array]': return 'uint16'; case '[object Uint8Array]': return 'uint8'; case '[object Uint8ClampedArray]': return 'uint8c'; case '[object Float32Array]': return 'float32'; case '[object Float64Array]': return 'float64'; default: return 'number'; } } /** * NDArray * @param {Array|NDArray} array * @param {String} dtype */ var NDArray = function(array) { // Last argument describe the data type of ndarray var dtype = arguments[arguments.length-1]; if (typeof(dtype) == 'string') { this._dtype = dtype; } else { // Normal array this._dtype = guessDataType(array); } if (array && typeof(array) !== 'string') { if (array instanceof NDArray) { array._dtype = this._dtype; return array; } else if (typeof(array.length) !== 'undefined') { // Init from array this.initFromArray(array); } else if(typeof(array) === 'number') { // Init from shape this.initFromShape.apply(this, arguments); } } else { /** * _array * Initialized with an empty array * Data is continuous one-dimensional array, row-major * A [2, 2] dim empty array is stored like * [0,0, 0,0] * TODO : Consider column majors ? * @type {ArrayConstructor} */ this._array = new ArrayConstructor[this._dtype](); /** * _shape * a tuple array describe the dimension and size of each dimension * [10, 10] means a 10x10 array * @type {Array} */ this._shape = [0]; /** * _size * size of the storage array length * @type {Number} */ this._size = 0; } }; NDArray.prototype = { /** * Initialize from a normal js array. * * @param {Array} input * @return {NDArray} this */ initFromArray : function(input) { var dim = getDimension(input); var cursor = 0; function flatten(axis, _out, _in) { var len = _in.length; for (var i = 0; i < len; i++) { if (axis < dim-1) { flatten(axis+1, _out, _in[i]); } else { _out[cursor++] = _in[i]; } } } var shape = getShape(input); var size = getSize(shape); this._array = new ArrayConstructor[this._dtype](size); flatten(0, this._array, input); this._shape = shape; this._size = size; return this; }, /** * Initialize from the given shape description. * @param {Array} shape * @return {NDArray} this */ initFromShape : function(shape) { if (typeof(shape) == 'number') { shape = Array.prototype.slice.call(arguments); } if(shape) { var size = getSize(shape); if (this._dtype === 'number') { this._array = []; var data = this._array; for (var i = 0; i < size; i++) { data[i] = 0; } } else { this._array = new ArrayConstructor[this._dtype](size); } } this._shape = shape; this._size = getSize(shape); return this; }, /** * Fill the array with the given value. * @param {Number} value * @return {NDArray} this */ fill : function(value) { var data = this._array; for (var i = 0; i < data.length; i++) { data[i] = value; } return this; }, /** * Get ndarray shape copy. * @return {Array} */ shape : function() { // Create a copy return this._shape.slice(); }, /** * Get array size * @return {Number} */ size : function() { return this._size; }, /** * Get array data type. * 'int32' * 'int16' * 'int8' * 'uint32' * 'uint16' * 'uint8' * 'float32' * 'float64' * @return {String} */ dtype : function() { return this._dtype; }, /** * Get array dimension. * @return {[type]} [description] */ dimension : function() { return this._shape.length; }, /** * Tuple of bytes to step in each dimension when traversing an array. * @return {Array} */ strides : function() { var strides = calculateDimStrides(this._shape); var dTypeStride = dTypeStrideMap[this._dtype]; for (var i = 0; i < strides.length; i++) { strides[i] *= dTypeStride; } return strides; }, /** * Gives a new shape to an array without changing its data. * @param {Array} shape * @return {NDArray} */ reshape : function(shape) { if (typeof(shape) == 'number') { shape = Array.prototype.slice.call(arguments); } if (this._isShapeValid(shape)) { this._shape = shape; } else { throw new Error('Total size of new array must be unchanged'); } return this; }, _isShapeValid : function(shape) { return getSize(shape) === this._size; }, /** * Change shape and size of array in-place. * @param {Array} shape * @return {NDArray} */ resize : function(shape) { if (typeof(shape) == 'number') { shape = Array.prototype.slice.call(arguments); } var len = getSize(shape); if (len < this._size) { if (this._dtype === 'number') { this._array.length = len; } } else { if (this._dtype === 'number') { for (var i = this._array.length; i < len; i++) { // Fill the rest with zero this._array[i] = 0; } } else { // Reallocate new buffer var newArr = new ArrayConstructor[this._dtype](len); var originArr = this._array; // Copy data for (var i = 0; i < originArr.length; i++) { newArr[i] = originArr[i]; } this._array = newArr; } } this._shape = shape; this._size = len; return this; }, /** * Returns a new array with axes transposed. * @param {Array} [axes] * @param {NDArray} [out] * @return {NDArray} */ transpose : kwargs(function(axes, out) { var originAxes = []; for (var i = 0; i < this._shape.length; i++) { originAxes.push(i); } if (typeof(axes) === 'undefined') { axes = originAxes.slice(); } // Check if any axis is out of bounds for (var i = 0; i < axes.length; i++) { if (axes[i] >= this._shape.length) { throw new Error(axisOutofBoundsErrorMsg(axes[i])); } } // Has no effect on 1-D transpose if (axes.length <= 1) { return this; } var targetAxes = originAxes.slice(); for (var i = 0; i < Math.floor(axes.length / 2); i++) { for (var j = axes.length-1; j >= Math.ceil(axes.length / 2) ; j--) { // Swap axes targetAxes[axes[i]] = axes[j]; targetAxes[axes[j]] = axes[i]; } } return this._transposelike(targetAxes, out); }), /** * Return a new array with axis1 and axis2 interchanged. * @param {Number} axis1 * @param {Number} axis2 * @param {NDArray} out * @return {NDArray} */ swapaxes : kwargs(function(axis1, axis2, out) { return this.transpose([axis1, axis2], out); }), /** * Roll the specified axis backwards, until it lies in a given position. * @param {Number} axis * @param {Number} [start=0] * @param {NDArray} out * @return {NDArray} */ rollaxis : kwargs(function(axis, start, out) { if (axis >= this._shape.length) { throw new Error(axisOutofBoundsErrorMsg(axis)); } var axes = []; for (var i = 0; i < this._shape.length; i++) { axes.push(i); } axes.splice(axis, 1); axes.splice(start, 0, axis); return this._transposelike(axes, out); }, { start : 0}), // Base function for transpose-like operations _transposelike : function(axes, out) { var source = this._array; var shape = this._shape.slice(); var strides = calculateDimStrides(this._shape); var dim = shape.length; // Swap var tmpStrides = []; var tmpShape = []; for (var i = 0; i < axes.length; i++) { var axis = axes[i]; // swap to target axis tmpShape[i] = shape[axis]; tmpStrides[i] = strides[axis]; } strides = tmpStrides; shape = tmpShape; this._shape = shape; var transposedStrides = calculateDimStrides(this._shape); if (!out) { out = new NDArray(); out._shape = this._shape.slice(); out._dtype = this._dtype; out._size = this._size; } // FIXME in-place transpose? var transposedData = new ArrayConstructor[this._dtype](this._size); out._array = transposedData; // @param Item offset in current axis offset of the original array // @param Item offset in current axis offset of the transposed array function transpose(axis, offset, transposedOffset) { var size = shape[axis]; // strides in orginal array var stride = strides[axis]; // strides in transposed array var transposedStride = transposedStrides[axis]; if (axis < dim-1) { for (var i = 0; i < size; i++) { transpose( axis+1, offset + stride * i, transposedOffset + transposedStride * i ); } } else { for (var i = 0; i < size; i++) { // offset + stride * i is the index of the original array // transposedOffset + i is the index of the transposed array transposedData[transposedOffset + i] = source[offset + stride * i]; } } } transpose(0, 0, 0); return out; }, /** * Repeat elements of an array along axis * @param {Number} repeats * The number of repetitions for each element. * repeats is broadcasted to fit the shape of the given axis. * @param {Number} [axis] * The axis along which to repeat values. * By default, use the flattened input array, * and return a flat output array. * @param {NDArray} [out] * @return {NDArray} */ repeat : kwargs(function(repeats, axis, out) { var shape; // flattened input array if (typeof(axis) === 'undefined') { shape = [this._size]; axis = 0; } else { shape = this._shape.slice(); } var originShape = shape.slice(); shape[axis] *= repeats; if (!out) { out = new NDArray(this._dtype); out.initFromShape(shape); } else { if (!arrayEqual(shape, out._shape)) { throw new Error(broadcastErrorMsg(shape, out._shape)); } } var data = out._array; var stride = calculateDimStride(originShape, axis); var axisSize = originShape[axis]; var source = this._array; var offsetStride = stride * axisSize; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var k = 0; k < stride; k++) { var idx = offset + k; var idxRepeated = offset * repeats + k; for (var i = 0; i < axisSize; i++) { for (var j = 0; j < repeats; j++) { data[idxRepeated] = source[idx]; idxRepeated += stride; } idx += stride; } } } return out; }), choose : function() { console.warn('TODO'); }, take : function() { console.warn('TODO'); }, tile : function() { console.warn('TODO'); }, /** * Preprocess for array calculation * max, min, argmax, argmin, sum, ptp, val, mean * Which will reduce one axis if the axis is given * * @param {Number} axis * @param {NDArray} out * @param {Function} funcWithAxis * @param {Function} funcFlatten * @return {Number|NDArray} */ _withPreprocess1 : function(axis, out, funcWithAxis, funcFlatten) { var source = this._array; if (!this._size) { return; } if (typeof(axis)!=='undefined') { if (axis < 0) { axis = this._shape.length + axis; } if (axis >= this._shape.length || axis < 0) { throw new Error(axisOutofBoundsErrorMsg(axis)); } var shape = this._shape.slice(); shape.splice(axis, 1); if (out && !arrayEqual(shape, out._shape)) { throw new Error(broadcastErrorMsg(shape, out._shape)); } if (!out) { out = new NDArray(this._dtype); out.initFromShape(shape); } var data = out._array; var stride = calculateDimStride(this._shape, axis); var axisSize = this._shape[axis]; var offsetStride = stride * axisSize; funcWithAxis.call( this, data, source, offsetStride, axisSize, stride ); return out; } else { return funcFlatten.call(this, source); } }, /** * Preprocess for array calculation cumsum, cumprod * Which will keep the shape if axis is given * and flatten if axis is undefined * @param {Number} axis * @param {NDArray} out * @param {Function} funcWithAxis * @param {Function} funcFlatten * @return {NDArray} */ _withPreprocess2 : function(axis, out, funcWithAxis, funcFlatten) { var source = this._array; if (!this._size) { return; } if (out && !arrayEqual(this._shape, out._shape)) { throw new Error(broadcastErrorMsg(this._shape, out._shape)); } if (!out) { out = new NDArray(this._dtype); out.initFromShape(this._shape); } var data = out._array; if (typeof(axis)!=='undefined') { if (axis < 0) { axis = this._shape.length + axis; } if (axis >= this._shape.length || axis < 0) { throw new Error(axisOutofBoundsErrorMsg(axis)); } if (axis >= this._shape.length) { throw new Error(axisOutofBoundsErrorMsg(axis)); } var stride = calculateDimStride(this._shape, axis); var axisSize = this._shape[axis]; var offsetStride = stride * axisSize; funcWithAxis.call( this, data, source, offsetStride, axisSize, stride ); } else { out.reshape([this._size]); funcFlatten.call(this, data, source); } return out; }, /** * Get the max value of ndarray * If the axis is given, the max is only calculate in this dimension * Example, for the given ndarray * [[3, 9], * [4, 8]] * >>> max(0) * [4, 9] * >>> max(1) * [9, 8] * * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ max : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { var cursor = 0; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var idx = i + offset; var max = source[idx]; for (var j = 0; j < axisSize; j++) { var d = source[idx]; if (d > max) { max = d; } idx += stride; } data[cursor++] = max; } } } function withFlatten(source) { var max = source[0]; for (var i = 1; i < this._size; i++) { if (source[i] > max) { max = source[i]; } } return max; } return function(axis, out) { return this._withPreprocess1( axis, out, withAxis, withFlatten ); }; })()), /** * Return the minimum of an array or minimum along an axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ min : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { var cursor = 0; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var idx = i + offset; var min = source[idx]; for (var j = 0; j < axisSize; j++) { var d = source[idx]; if (d < min) { min = d; } idx += stride; } data[cursor++] = min; } } } function withFlatten(source) { var min = source[0]; for (var i = 1; i < this._size; i++) { if (source[i] < min) { min = source[i]; } } return min; } return function(axis, out) { return this._withPreprocess1( axis, out, withAxis, withFlatten ); }; })()), /** * Return indices of the maximum values along an axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ argmax : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { var cursor = 0; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var dataIdx = 0; var idx = i + offset; var max = source[idx]; for (var j = 0; j < axisSize; j++) { var d = source[idx]; if (d > max) { max = d; dataIdx = j; } idx += stride; } data[cursor++] = dataIdx; } } } function withFlatten(source) { var max = source[0]; var idx = 0; for (var i = 1; i < this._size; i++) { if (source[i] > max) { idx = i; max = source[i]; } } return idx; } return function(axis, out) { return this._withPreprocess1( axis, out, withAxis, withFlatten ); }; })()), /** * Indices of the minimum values along an axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ argmin : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { var cursor = 0; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var dataIdx = 0; var idx = i + offset; var min = source[idx]; for (var j = 0; j < axisSize; j++) { var d = source[idx]; if (d < min) { min = d; dataIdx = j; } idx += stride; } data[cursor++] = dataIdx; } } } function withFlatten(source) { var min = source[0]; var idx = 0; for (var i = 1; i < this._size; i++) { if (source[i] < min) { idx = i; min = source[i]; } } return idx; } return function(axis, out) { return this._withPreprocess1( axis, out, withAxis, withFlatten ); }; })()), /** * Return the sum of the array elements over the given axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ sum : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { var cursor = 0; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var sum = 0; var idx = i + offset; for (var j = 0; j < axisSize; j++) { sum += source[idx]; idx += stride; } data[cursor++] = sum; } } } function withFlatten(source) { var sum = 0; for (var i = 0; i < this._size; i++) { sum += source[i]; } return sum; } return function(axis, out) { return this._withPreprocess1( axis, out, withAxis, withFlatten ); }; })()), /** * Return the product of the array elements over the given axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ prod : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { var cursor = 0; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var prod = 1; var idx = i + offset; for (var j = 0; j < axisSize; j++) { prod *= source[idx]; idx += stride; } data[cursor++] = prod; } } } function withFlatten(source) { var prod = 1; for (var i = 0; i < this._size; i++) { prod *= source[i]; } return prod; } return function(axis, out) { return this._withPreprocess1( axis, out, withAxis, withFlatten ); }; })()), /** * Returns the average of the array elements along given axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ mean : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { var cursor = 0; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var sum = 0; var idx = i + offset; for (var j = 0; j < axisSize; j++) { sum += source[idx]; idx += stride; } var mean = sum / axisSize; data[cursor++] = mean; } } } function withFlatten(source) { var sum = 0; var len = source.length; for (var i = 0; i < len; i++) { sum += source[i]; } var mean = sum / len; return mean; } return function(axis, out) { return this._withPreprocess1( axis, out, withAxis, withFlatten ); }; })()), /** * Return the variance of the array elements over the given axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ 'var' : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { var cursor = 0; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var sum = 0; var idx = i + offset; for (var j = 0; j < axisSize; j++) { sum += source[idx]; idx += stride; } var mean = sum / axisSize; var moments = 0; idx = i + offset; for (var j = 0; j < axisSize; j++) { var diff = source[idx] - mean; moments += diff * diff; idx += stride; } data[cursor++] = moments / axisSize; } } } function withFlatten(source) { var sum = 0; var len = source.length; for (var i = 0; i < len; i++) { sum += source[i]; } var mean = sum / len; var moments = 0; for (var i = 0; i < len; i++) { var diff = source[i] - mean; moments += diff * diff; } return moments / len; } return function(axis, out) { return this._withPreprocess1( axis, out, withAxis, withFlatten ); }; })()), /** * Return the standard derivatione of the array elements * over the given axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ std : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { var cursor = 0; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var sum = 0; var idx = i + offset; for (var j = 0; j < axisSize; j++) { sum += source[idx]; idx += stride; } var mean = sum / axisSize; var moments = 0; idx = i + offset; for (var j = 0; j < axisSize; j++) { var diff = source[idx] - mean; moments += diff * diff; idx += stride; } data[cursor++] = Math.sqrt(moments / axisSize); } } } function withFlatten(source) { var sum = 0; var len = source.length; for (var i = 0; i < len; i++) { sum += source[i]; } var mean = sum / len; var moments = 0; for (var i = 0; i < len; i++) { var diff = source[i] - mean; moments += diff * diff; } return Math.sqrt(moments / len); } return function(axis, out) { return this._withPreprocess1( axis, out, withAxis, withFlatten ); }; })()), /** * Peak to peak (maximum - minimum) value along a given axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ ptp : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { var cursor = 0; for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var idx = offset + i; var min = source[idx]; var max = source[idx]; for (var j = 0; j < axisSize; j++) { var d = source[idx]; if (d < min) { min = d; } if (d > max) { max = d; } idx += stride; } data[cursor++] = max - min; } } } function withFlatten(source) { var min = source[0]; var max = source[0]; for (var i = 1; i < this._size; i++) { if (source[i] < min) { min = source[i]; } if (source[i] > max) { max = source[i]; } } return max - min; } return function(axis, out) { return this._withPreprocess1( axis, out, withAxis, withFlatten ); }; })()), /** * * @param {Number} [axis=-1] * @param {string} [order='ascending'] * 'ascending' | 'descending' * @return {NDArray} */ // FIXME : V8 is quick sort, firefox and safari is merge sort // order : ascending or desc sort : kwargs(function(axis, order) { if (axis < 0) { axis = this._shape.length + axis; } var compareFunc; if (order === 'ascending') { compareFunc = function(a, b) { return a - b; }; } else if( order === 'descending') { compareFunc = function(a, b) { return b - a; }; } var source = this._array; var stride = calculateDimStride(this._shape, axis); var axisSize = this._shape[axis]; var offsetStride = stride * axisSize; var tmp = new Array(axisSize); for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var idx = offset + i; for (var j = 0; j < axisSize; j++) { tmp[j] = source[idx]; idx += stride; } tmp.sort(compareFunc); var idx = offset + i; // Copy back for (var j = 0; j < axisSize; j++) { source[idx] = tmp[j]; idx += stride; } } } return this; }, {axis : -1, order : 'ascending'}), /** * * @param {Number} [axis=-1] * @param {string} [order='ascending'] * 'ascending' | 'descending' * @param {NDArray} [out] * @return {NDArray} */ argsort : kwargs(function(axis, order, out) { if (axis < 0) { axis = this._shape.length + axis; } if (!this._size) { return; } if (out && !arrayEqual(this._shape, out._shape)) { throw new Error(broadcastErrorMsg(this._shape, out._shape)); } if (!out) { out = new NDArray(this._dtype); out.initFromShape(this._shape); } var data = out._array; var compareFunc; if (order === 'ascending') { compareFunc = function(a, b) { return tmp[a] - tmp[b]; }; } else if( order === 'descending') { compareFunc = function(a, b) { return tmp[b] - tmp[a]; }; } var source = this._array; var stride = calculateDimStride(this._shape, axis); var axisSize = this._shape[axis]; var offsetStride = stride * axisSize; var tmp = new Array(axisSize); var indexList = new Array(axisSize); for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var idx = offset + i; for (var j = 0; j < axisSize; j++) { tmp[j] = source[idx]; indexList[j] = j; idx += stride; } indexList.sort(compareFunc); // Copy back var idx = offset + i; for (var j = 0; j < axisSize; j++) { data[idx] = indexList[j]; idx += stride; } } } return out; }, {axis : -1, order : 'ascending'}), /** * Return the cumulative sum of the elements along the given axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ cumsum : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var idx = offset + i; var prevIdx = idx; data[idx] = source[idx]; for (var j = 1; j < axisSize; j++) { prevIdx = idx; idx += stride; data[idx] = data[prevIdx] + source[idx]; } } } } function withFlatten(data, source) { data[0] = source[0]; for (var i = 1; i < data.length; i++) { data[i] = data[i-1] + source[i]; } } return function(axis, out) { return this._withPreprocess2( axis, out, withAxis, withFlatten ); }; })()), /** * Return the cumulative product of the elements along the given axis. * @param {Number} [axis] * @param {NDArray} out * @return {NDArray} */ cumprod : kwargs((function() { function withAxis(data, source, offsetStride, axisSize, stride) { for (var offset = 0; offset < this._size; offset+=offsetStride) { for (var i = 0; i < stride; i++) { var idx = offset + i; var prevIdx = idx; data[idx] = source[idx]; for (var j = 1; j < axisSize; j++) { prevIdx = idx; idx += stride; data[idx] = data[prevIdx] * source[idx]; } } } } function withFlatten(data, source) { data[0] = source[0]; for (var i = 1; i < data.length; i++) { data[i] = data[i-1] * source[i]; } } return function(axis, out) { return this._withPreprocess2( axis, out, withAxis, withFlatten ); }; })()), /** * Dot product of two arrays. * * @param {NDArray|Number} b * @param {NDArray} [out] * @return {NDArray|Number} */ dot : function() { console.warn('TODO'); }, /** * Mapped to region [min, max] * @param {Number} mappedMin * @param {Number} mappedMax */ map : function(mappedMin, mappedMax) { var input = this._array; var output = this._array; var min = input[0]; var max = input[0]; var l = this._size; for (var i = 1; i < l; i++) { var val = input[i]; if (val < min) { min = val; } if (val > max) { max = val; } } var range = max - min; var mappedRange = mappedMax - mappedMin; for (var i = 0; i < l; i++) { if (range === 0) { output[i] = mappedMin; } else { var val = input[i]; var percent = (val - min) / range; output[i] = mappedRange * percent + mappedMin; } } return this; }, /** * Add */ add : function(rightOperand, out) { return this.binaryOperation( this, rightOperand, E_ADD, out ); }, /** * Substract */ sub : function(rightOperand, out) { return this.binaryOperation( this, rightOperand, E_SUB, out ); }, /** * Multiply */ mul : function(rightOperand, out) { return this.binaryOperation( this, rightOperand, E_MUL, out ); }, /** * Divide */ div : function(rightOperand, out) { return this.binaryOperation( this, rightOperand, E_DIV, out ); }, /** * mod */ mod : function(rightOperand, out) { return this.binaryOperation( this, rightOperand, E_MOD, out ); }, /** * and */ and : function(rightOperand, out) { return this.binaryOperation( this, rightOperand, E_AND, out ); }, /** * or */ or : function(rightOperand, out) { return this.binaryOperation( this, rightOperand, E_OR, out ); }, /** * xor */ xor : function(rightOperand, out) { return this.binaryOperation( this, rightOperand, E_XOR, out ); }, /** * equal */ equal : function(rightOperand) { return this.binaryOperation( this, rightOperand, E_EQL, out ); }, binaryOperation : function(lo, ro, op, out) { // Broadcasting // http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html var shape = []; var isLoScalar = typeof(lo) === 'number'; var isRoScalar = typeof(ro) === 'number'; if (isLoScalar) { shape = ro._shape.slice(); } else if (isRoScalar) { shape = lo._shape.slice(); } else { // Starts with the trailing dimensions var cl = lo._shape.length-1; var cr = ro._shape.length-1; var loBroadCasted = lo; var roBroadCasted = ro; while (cl >= 0 && cr >= 0) { if (lo._shape[cl] == 1) { shape.unshift(ro._shape[cr]); loBroadCasted = lo.repeat(ro._shape[cr], cl); } else if(ro._shape[cr] == 1) { shape.unshift(lo._shape[cl]); roBroadCasted = ro.repeat(lo._shape[cl], cr); } else if(ro._shape[cr] == lo._shape[cl]) { shape.unshift(lo._shape[cl]); } else { throw new Error(broadcastErrorMsg(lo._shape, ro._shape)); } cl --; cr --; } for (var i = cl; i >= 0; i--) { shape.unshift(lo._shape[i]); } for (var i = cr; i >= 0; i--) { shape.unshift(ro._shape[i]); } lo = loBroadCasted; ro = roBroadCasted; } if (!out) { out = new NDArray(this._dtype); out.initFromShape(shape); } else { if (! arrayEqual(shape, out._shape)) { throw new Error(broadcastErrorMsg(shape, out._shape)); } } var outData = out._array; var diffAxis; var isLoLarger; var loData; var roData; if (isLoScalar) { diffAxis = ro._shape.length-1; isLoLarger = false; loData = lo; roData = ro._array; } else if(isRoScalar) { diffAxis = lo._shape.length-1; isLoLarger = true; roData = ro; loData = lo._array; } else { diffAxis = Math.abs(lo._shape.length - ro._shape.length); isLoLarger = lo._shape.length >= ro._shape.length; loData = lo._array; roData = ro._array; } var stride = calculateDimStride(shape, diffAxis); var axisSize = shape[diffAxis]; var offsetStride = stride * axisSize; var offsetRepeats = out._size / offsetStride; var _a, _b, res; var idx = 0; if (isLoLarger) { if(isRoScalar) { for (var c = 0; c < offsetRepeats; c++) { for (var i = 0; i < offsetStride; i++) { _a = loData[idx]; _b = roData; switch (op) { case E_ADD: res = _a + _b; break; case E_SUB: res = _a - _b; break; case E_MUL: res = _a * _b; break; case E_DIV: res = _a / _b; break; case E_MOD: res = _a % _b; break; case E_AND: res = _a & _b; break; case E_OR: res = _a | _b; break; case E_XOR: res = _a ^ _b; break; case E_EQL: res = _a == _b; break; default: throw new Error('Unkown operation ' + op); } outData[idx] = res; idx ++; } } } else { for (var c = 0; c < offsetRepeats; c++) { for (var i = 0; i < offsetStride; i++) { _a = loData[idx]; _b = roData[i]; switch (op) { case E_ADD: res = _a + _b; break; case E_SUB: res = _a - _b; break; case E_MUL: res = _a * _b; break; case E_DIV: res = _a / _b; break; case E_MOD: res = _a % _b; break; case E_AND: res = _a & _b; break; case E_OR: res = _a | _b; break; case E_XOR: res = _a ^ _b; break; case E_EQL: res = _a == _b; break; default: throw new Error('Unkown operation ' + op); } outData[idx] = res; idx ++; } } } } else { if (isLoScalar) { for (var c = 0; c < offsetRepeats; c++) { for (var i = 0; i < offsetStride; i++) { _a = loData; _b = roData[idx]; switch (op) { case E_ADD: res = _a + _b; break; case E_SUB: res = _a - _b; break; case E_MUL: res = _a * _b; break; case E_DIV: res = _a / _b; break; case E_MOD: res = _a % _b; break; case E_AND: res = _a & _b; break; case E_OR: res = _a | _b; break; case E_XOR: res = _a ^ _b; break; case E_EQL: res = _a == _b; break; default: throw new Error('Unkown operation ' + op); } outData[idx] = res; idx ++; } } } else { for (var c = 0; c < offsetRepeats; c++) { for (var i = 0; i < offsetStride; i++) { _a = loData[idx]; _b = roData[i]; switch (op) { case E_ADD: res = _a + _b; break; case E_SUB: res = _a - _b; break; case E_MUL: res = _a * _b; break; case E_DIV: res = _a / _b; break; case E_MOD: res = _a % _b; break; case E_AND: res = _a & _b; break; case E_OR: res = _a | _b; break; case E_XOR: res = _a ^ _b; break; case E_EQL: res = _a == _b; break; default: throw new Error('Unkown operation ' + op); } outData[idx] = res; idx ++; } } } } return out; }, /** * negtive */ neg : function() { var data = this._array; for (var i = 0; i < this._size; i++) { data[i] = -data[i]; } return this; }, /** * @return {NDArray} this */ sin : function() { return this._mathAdapter(Math.sin); }, /** * @return {NDArray} this */ cos : function() { return this._mathAdapter(Math.cos); }, /** * @return {NDArray} this */ tan : function() { return this._mathAdapter(Math.tan); }, /** * @return {NDArray} this */ abs : function() { return this._mathAdapter(Math.abs); }, /** * @return {NDArray} this */ log : function() { return this._mathAdapter(Math.log); }, /** * @return {NDArray} this */ sqrt : function() { return this._mathAdapter(Math.sqrt); }, /** * @return {NDArray} this */ ceil : function() { return this._mathAdapter(Math.ceil); }, /** * @return {NDArray} this */ floor : function() { return this._mathAdapter(Math.floor); }, /** * @return {NDArray} this */ pow : function(exp) { var data = this._array; for (var i = 0; i < this._size; i++) { data[i] = Math.pow(data[i], exp); } return this; }, _mathAdapter : function(mathFunc) { var data = this._array; for (var i = 0; i < this._size; i++) { data[i] = mathFunc(data[i]); } return this; }, /** * @param {Number} decimals * @return {NDArray} this */ round : function(decimals) { decimals = Math.floor(decimals || 0); var offset = Math.pow(10, decimals); var data = this._array; if (decimals === 0) { for (var i = 0; i < this._size; i++) { data[i] = Math.round(data[i]); } } else { for (var i = 0; i < this._size; i++) { data[i] = Math.round(data[i] * offset) / offset; } } return this; }, /** * @param {Number} min * @param {Number} max * Clip to [min, max] */ clip : function(min, max) { // TODO : Support array_like param var data = this._array; for (var i = 0; i < this._size; i++) { data[i] = Math.max(Math.min(data[i], max), min); } return this; }, /** * Indexing array, support range indexing * @param {string} index * Index syntax can be an integer 1, 2, 3 * Or more complex range indexing * '1:2' * '1:2, 1:2' * '1:2, :' * More about the indexing syntax can check the doc of numpy ndarray * @param {NDArray} [out] * @return {NDArray} New created sub array, or out if given */ get : function(index, out) { if (typeof(index) == 'number') { index = index.toString(); } var strides = calculateDimStrides(this._shape); var res = this._parseRanges(index); var ranges = res[0]; var shape = res[1]; if (ranges.length > this._shape.length) { throw new Error('Too many indices'); } // Get data var len = ranges.length; var data; if (shape.length) { out = new NDArray(this._dtype); out.initFromShape(shape); data = out._array; } else { data = []; } var source = this._array; var cursor = 0; function getPiece(axis, offset) { var range = ranges[axis]; var stride = strides[axis]; if (axis < len-1) { if (range[2] > 0) { for (var i = range[0]; i < range[1]; i += range[2]) { getPiece(axis+1, offset + stride * i); } } else { for (var i = range[0]; i > range[1]; i += range[2]) { getPiece(axis+1, offset + stride * i); } } } else { if (range[2] > 0) { for (var i = range[0]; i < range[1]; i += range[2]) { for (var j = 0; j < stride; j++) { data[cursor++] = source[i*stride + j + offset]; } } } else { for (var i = range[0]; i > range[1]; i += range[2]) { for (var j = 0; j < stride; j++) { data[cursor++] = source[i*stride + j + offset]; } } } } } getPiece(0, 0); if (shape.length) { // Return scalar return out; } else { return data[0]; } }, /** * * @param {string} index * index syntax can be an integer 1, 2, 3 * Or more complex range indexing * '1:2' * '1:2, 1:2' * '1:2, :' * More about the indexing syntax can check the doc of numpy ndarray * @param {NDArray} ndarray Ndarray data source * @return {NDArray} this */ set : function(index, narray) { if (typeof(index) == 'number') { index = index.toString(); } var strides = calculateDimStrides(this._shape); var res = this._parseRanges(index); var ranges = res[0]; var shape = res[1]; if (ranges.length > this._shape.length) { throw new Error('Too many indices'); } var isScalar = typeof(narray) == 'number'; var len = ranges.length; var data = this._array; if (isScalar) { // Set with a single scalar var source = narray; } else { if (!arrayEqual(shape, narray.shape())) { throw new Error(broadcastErrorMsg(shape, narray.shape())); } var source = narray._array; } var cursor = 0; var setPiece = function(axis, offset) { var range = ranges[axis]; var stride = strides[axis]; if (axis < len-1) { if (range[2] > 0) { for (var i = range[0]; i < range[1]; i += range[2]) { setPiece(axis+1, offset + stride * i); } } else { for (var i = range[0]; i > range[1]; i += range[2]) { setPiece(axis+1, offset + stride * i); } } } else { if (range[2] > 0) { for (var i = range[0]; i < range[1]; i += range[2]) { for (var j = 0; j < stride; j++) { if (isScalar) { data[i*stride + j + offset] = source; } else { data[i*stride + j + offset] = source[cursor++]; } } } } else { for (var i = range[0]; i > range[1]; i += range[2]) { for (var j = 0; j < stride; j++) { if (isScalar) { data[i*stride + j + offset] = source; } else { data[i*stride + j + offset] = source[cursor++]; } } } } } }; setPiece(0, 0); return this; }, /** * Insert values along the given axis before the given indices. * @param {Number|Array} obj * Object that defines the index or indices before * which values is inserted. * @param {Number|Array|NDArray} values * Values to insert * @param {Number} [axis] * @return {NDArray} this */ insert : kwargs(function(obj, values, axis) { var data = this._array; var isObjScalar = false; if (typeof(obj) === 'number') { obj = [obj]; isObjScalar = true; } if (typeof(values) === 'number') { values = new NDArray([values]); } else if (values instanceof Array) { values = new NDArray(values); } if (typeof(axis) === 'undefined') { this._shape = [this._size]; axis = 0; } // Checking if indices is valid var prev = obj[0]; var axisSize = this._shape[axis]; for (var i = 0; i < obj.length; i++) { if (obj[i] < 0) { obj[i] = axisSize + obj[i]; } if (obj[i] > axisSize) { throw new Error(indexOutofBoundsErrorMsg(obj[i])); } if (obj[i] < prev) { throw new Error('Index must be in ascending order'); } prev = obj[i]; } // Broadcasting var targetShape = this._shape.slice(); if (isObjScalar) { targetShape.splice(axis, 1); } else { targetShape[axis] = obj.length; } var sourceShape = values._shape; var cs = sourceShape.length - 1; var ct = targetShape.length - 1; var valueBroadcasted = values; while (cs >= 0 && ct >= 0) { if (sourceShape[cs] === 1) { valueBroadcasted = values.repeat(targetShape[ct], cs); } else if(sourceShape[cs] !== targetShape[ct]) { throw new Error(broadcastErrorMsg(sourceShape, targetShape)); } cs --; ct --; } values = valueBroadcasted; // Calculate indices to insert var stride = calculateDimStride(this._shape, axis); var axisSize = this._shape[axis]; var offsetStride = axisSize * stride; var offsetRepeats = this._size / offsetStride; var objLen = obj.length; var indices = new Uint32Array(offsetRepeats * objLen); var cursor = 0; for (var offset = 0; offset < this._size; offset += offsetStride) { for (var i = 0; i < objLen; i++) { var objIdx = obj[i]; indices[cursor++] = offset + objIdx * stride; } } var resShape = this._shape.slice(); resShape[axis] += obj.length; var resSize = getSize(resShape); if (this._array.length < resSize) { var data = new ArrayConstructor[this._dtype](resSize); } else { var data = this._array; } var source = this._array; var valuesArr = values._array; var idxCursor = indices.length - 1; var end = this._size; var start = indices[idxCursor]; var dataCursor = resSize - 1; var valueCursor = values._size - 1; while (idxCursor >= 0) { // Copy source data; for (var i = end - 1; i >= start; i--) { data[dataCursor--] = source[i]; } end = start; start = indices[--idxCursor]; // Copy inserted data; for (var i = 0; i < stride; i++) { if (valueCursor < 0) { valueCursor = values._size - 1; } data[dataCursor--] = valuesArr[valueCursor--]; } } // Copy the rest for (var i = end - 1; i >= 0; i--) { data[dataCursor--] = source[i]; } this._array = data; this._shape = resShape; this._size = resSize; return this; }), append : function() { console.warn('TODO'); }, /** * Delete values along the axis * @param {Array|Number} obj * @param {Number} [axis] * @return {NDArray} this */ 'delete' : kwargs(function(obj, axis) { var data = this._array; if (typeof(obj) === 'number') { obj = [obj]; } var size = this._size; if (typeof(axis) === 'undefined') { this._shape = [size]; axis = 0; } var stride = calculateDimStride(this._shape, axis); var axisSize = this._shape[axis]; var offsetStride = stride * axisSize; var cursor = 0; for (var offset = 0; offset < size; offset += offsetStride) { var start = 0; var end = obj[0]; var objCursor = 0; while(objCursor < obj.length) { if (end < 0) { end = end + axisSize; } if (end > axisSize) { throw new Error(indexOutofBoundsErrorMsg(end)); } if (end < start) { throw new Error('Index must be in ascending order'); } for (var i = start; i < end; i++) { for (var j = 0; j < stride; j++) { data[cursor++] = data[i * stride + j + offset]; } } start = end + 1; end = obj[++objCursor]; } // Copy the rest for (var i = start; i < axisSize; i++) { for (var j = 0; j < stride; j++) { data[cursor++] = data[i * stride + j + offset]; } } } this._shape[axis] -= obj.length; this._size = getSize(this._shape); return this; }), _parseRanges : function(index) { var rangesStr = index.split(/\s*,\s*/); // Parse range of each axis var ranges = []; var shape = []; var j = 0; for (var i = 0; i < rangesStr.length; i++) { if (rangesStr[i] === '...') { var end = this._shape.length - (rangesStr.length - i); while (j <= end) { ranges.push([0, this._shape[j], 1]); shape.push(this._shape[j]); j++; } } else { var range = parseRange(rangesStr[i], this._shape[j]); ranges.push(range); if(rangesStr[i].indexOf(':') >= 0) { var size = Math.floor((range[1] - range[0]) / range[2]); size = size < 0 ? 0 : size; // Get a range not a item shape.push(size); } j++; } } // Copy the lower dimension size for (; j < this._shape.length; j++) { shape.push(this._shape[j]); } return [ranges, shape]; }, /** * Export normal js array * @return {Array} */ toArray : function() { var data = this._array; var cursor = 0; var shape = this._shape; var dim = shape.length; function create(axis, out) { var len = shape[axis]; for (var i = 0; i < len; i++) { if (axis < dim-1) { create(axis+1, out[i] = []); } else { out[i] = data[cursor++]; } } } var output = []; create(0, output); return output; }, /** * Create a copy of self * @return {NDArray} */ copy : function() { var numArr = new NDArray(); numArr._array = ArraySlice.call(this._array); numArr._shape = this._shape.slice(); numArr._dtype = this._dtype; numArr._size = this._size; return numArr; }, constructor : NDArray }; /** * * @param {Number} [min=0] * @param {Number} max * @param {Number} [step=1] * @param {string} [dtype] * @return {NDArray} */ NDArray.range = kwargs(function(min, max, step, dtype) { var args = ArraySlice.call(arguments); // Last argument describe the data type of ndarray var lastArg = args[args.length-1]; if (typeof(lastArg) == 'string') { var dtype = lastArg; args.pop(); } if (args.length === 1) { max = args[0]; step = 1; min = 0; } else if(args.length == 2) { step = 1; } dtype = dtype || 'number'; var array = new ArrayConstructor[dtype](Math.ceil((max - min)/step)); var cursor = 0; for (var i = min; i < max; i+=step) { array[cursor++] = i; } var ndarray = new NDArray(); ndarray._array = array; ndarray._shape = [array.length]; ndarray._dtype = dtype; ndarray._size = array.length; return ndarray; }); /** * * @param {Array} shape * @param {String} [dtype] * @return {NDArray} */ NDArray.zeros = kwargs(function(shape, dtype) { var ret = new NDArray(dtype); ret.initFromShape(shape); return ret; }); /** * Python like array indexing * http://www.python.org/dev/peps/pep-0204/ * * @param {string} index * index can be a simple integer 1,2,3, * or a range 2:10, 2:10:1 * example : * 2:10 => [2, 10, 1], * 10:2:-2 => [10, 2, -2], * : => [0, dimSize, 1], * ::-1 => [dimSize-1, -1, -1], * @param {number} dimSize * @return {Array} a tuple array [startOffset, endOffset, sliceStep] */ function parseRange(index, dimSize) { if (index.indexOf(':') >= 0) { // Range indexing; var res = index.split(/\s*:\s*/); var step = parseInt(res[2] || 1, 10); var start, end; if (step === 0) { throw new Error('Slice step cannot be zero'); } else if (step > 0) { start = parseInt(res[0] || 0, 10); end = parseInt(res[1] || dimSize, 10); } else { start = parseInt(res[0] || dimSize - 1, 10); end = parseInt(res[1] || -1, 10); } // Negtive offset if (start < 0) { start = dimSize + start; } // Negtive offset if (end < 0 && res[1]) { end = dimSize + end; } if (step > 0) { // Clamp to [0-dimSize] start = Math.max(Math.min(dimSize, start), 0); // Clamp to [0-dimSize] end = Math.max(Math.min(dimSize, end), 0); } else { // Clamp to [0-dimSize) start = Math.max(Math.min(dimSize-1, start), -1); // Clamp to [0-dimSize) end = Math.max(Math.min(dimSize-1, end), -1); } return [start, end, step]; } else { var start = parseInt(index, 10); // Negtive offset if (start < 0) { start = dimSize + start; } if (start < 0 || start > dimSize) { throw new Error(indexOutofBoundsErrorMsg(index)); } // Clamp to [0-dimSize) start = Math.max(Math.min(dimSize-1, start), 0); return [start, start+1, 1]; } } function getSize(shape) { var size = shape[0]; for (var i = 1; i < shape.length; i++) { size *= shape[i]; } return size; } function getDimension(array) { var dim = 1; var el = array[0]; while (el instanceof Array) { el = el[0]; dim ++; } return dim; } function getShape(array) { var shape = [array.length]; var el = array[0]; while (el instanceof Array) { shape.push(el.length); el = el[0]; } return shape; } function calculateDimStride(shape, axis) { if (axis == shape.length-1) { return 1; } var stride = shape[axis+1]; for (var i = axis+2; i < shape.length; i++) { stride *= shape[i]; } return stride; } function calculateDimStrides(shape) { // Calculate stride of each axis var strides = []; var tmp = 1; var len = getSize(shape); for (var i = 0; i < shape.length; i++) { tmp *= shape[i]; strides.push(len / tmp); } return strides; } function arrayEqual(arr1, arr2) { if (arr1.length !== arr2.length) { return false; } for (var i = 0; i 0) { sector.style.brushType = 'both'; } if (sector.highlightStyle.lineWidth > 0) { sector.highlightStyle.brushType = 'both'; } ecData.pack( sector, chordSeries[0], 0, data[i], 0, group.name ); if (showLabel) { var halfAngle = [_start + _end] / 2; halfAngle %= 360; // Constrain to [0,360] var isRightSide = halfAngle <= 90 || halfAngle >= 270; halfAngle = halfAngle * Math.PI / 180; var v = [Math.cos(halfAngle), -Math.sin(halfAngle)]; var distance = showScaleText ? 45 : 20; var start = vec2.scale([], v, outerRadius + distance); vec2.add(start, start, center); var labelShape = { shape : 'text', id : zr.newShapeId(self.type), zlevel : _zlevelBase - 1, hoverable : false, style : { x : start[0], y : start[1], text : group.name, textAlign : isRightSide ? 'left' : 'right', color : labelColor } }; labelShape.style.textColor = self.deepQuery( [group, chordSerieSample], 'itemStyle.normal.label.textStyle.color' ) || '#fff'; labelShape.style.textFont = self.getFont(self.deepQuery( [group, chordSerieSample], 'itemStyle.normal.label.textStyle' )); zr.addShape(labelShape); self.shapeList.push(labelShape); } sector.onmouseover = createMouseOver(i); sector.onmouseout = createMouseOut(); self.shapeList.push(sector); sectorShapes.push(sector); zr.addShape(sector); } } function _buildChords(angles, dataArr) { var len = angles.length; if (!len) { return; } var len2 = angles[0][0].length; var chordLineStyle = chordSerieSample.itemStyle.normal.chordStyle.lineStyle; var chordLineStyleEmphsis = chordSerieSample.itemStyle.emphasis.chordStyle.lineStyle; for (var i = 0; i < len; i++) { for (var j = 0; j < len; j++) { for (var k = 0; k < len2; k++) { if (chordShapes[j][i][k]) { continue; } var angleIJ0 = angles[i][j][k][0]; var angleJI0 = angles[j][i][k][0]; var angleIJ1 = angles[i][j][k][1]; var angleJI1 = angles[j][i][k][1]; if (angleIJ0 - angleJI1 === 0 || angleJI0 - angleJI1 === 0) { chordShapes[i][j][k] = null; continue; } var color; if (len2 === 1) { if (angleIJ1 - angleIJ0 <= angleJI1 - angleJI0) { color = getColor(groups[i].name); } else { color = getColor(groups[j].name); } } else { color = getColor(chordSeries[k].name); } var s0 = !clockWise ? (360 - angleIJ1) : angleIJ0; var s1 = !clockWise ? (360 - angleIJ0) : angleIJ1; var t0 = !clockWise ? (360 - angleJI1) : angleJI0; var t1 = !clockWise ? (360 - angleJI0) : angleJI1; var chord = { id : zr.newShapeId(self.type), shape : 'chord', zlevel : _zlevelBase, style : { center : center, r : innerRadius, source0 : s0 - startAngle, source1 : s1 - startAngle, target0 : t0 - startAngle, target1 : t1 - startAngle, brushType : 'both', opacity : 0.5, color : color, lineWidth : chordLineStyle.width, strokeColor : chordLineStyle.color }, highlightStyle : { brushType : 'both', lineWidth : chordLineStyleEmphsis.width, strokeColor : chordLineStyleEmphsis.color } }; ecData.pack( chord, chordSeries[k], k, dataArr[i][j][k], 0, groups[i].name, groups[j].name, dataArr[j][i][k] ); chordShapes[i][j][k] = chord; self.shapeList.push(chord); zr.addShape(chord); } } } } function _buildScales( values, unitPostfix, angles, unitValue ) { for (var i = 0; i < angles.length; i++) { var subStartAngle = angles[i][0]; var subEndAngle = angles[i][1]; var scaleAngle = subStartAngle; while (scaleAngle < subEndAngle) { var thelta = ((clockWise ? (360 - scaleAngle) : scaleAngle) + startAngle) / 180 * Math.PI; var v = [ Math.cos(thelta), -Math.sin(thelta) ]; var start = vec2.scale([], v, outerRadius + 1); vec2.add(start, start, center); var end = vec2.scale([], v, outerRadius + scaleLineLength); vec2.add(end, end, center); var scaleShape = { shape : 'line', id : zr.newShapeId(self.type), zlevel : _zlevelBase - 1, hoverable : false, style : { xStart : start[0], yStart : start[1], xEnd : end[0], yEnd : end[1], lineCap : 'round', brushType : 'stroke', strokeColor : '#666' } }; self.shapeList.push(scaleShape); zr.addShape(scaleShape); scaleAngle += scaleUnitAngle; } if (!showScaleText) { continue; } var scaleTextAngle = subStartAngle; var step = unitValue * 5 * scaleUnitAngle; var scaleValues = NDArray.range(0, values[i], step).toArray(); while (scaleTextAngle < subEndAngle) { var thelta = clockWise ? (360 - scaleTextAngle) : scaleTextAngle; thelta = (thelta + startAngle) % 360; var isRightSide = thelta <= 90 || thelta >= 270; var textShape = { shape : 'text', id : zr.newShapeId(self.type), zlevel : _zlevelBase - 1, hoverable : false, style : { x : isRightSide ? outerRadius + scaleLineLength + 4 : -outerRadius - scaleLineLength - 4, y : 0, text : Math.round(scaleValues.shift()*10)/10 + unitPostfix, textAlign : isRightSide ? 'left' : 'right' }, position : center.slice(), rotation : isRightSide ? [thelta / 180 * Math.PI, 0, 0] : [ (thelta + 180) / 180 * Math.PI, 0, 0 ] }; self.shapeList.push(textShape); zr.addShape(textShape); scaleTextAngle += scaleUnitAngle * 5; } } } function normalizeValue(values) { var result = []; var max = new NDArray(values).max(); var unitPostfix, unitScale; if (max > 10000) { unitPostfix = 'k'; unitScale = 1 / 1000; } else if (max > 10000000) { unitPostfix = 'm'; unitScale = 1 / 1000000; } else if (max > 10000000000) { unitPostfix = 'b'; unitScale = 1 / 1000000000; } else { unitPostfix = ''; unitScale = 1; } for (var i = 0; i < values.length; i++) { result[i] = values[i] * unitScale; } return [result, unitPostfix]; } function init(newOption, newComponent) { component = newComponent; refresh(newOption); } function refresh(newOption) { if (newOption) { option = newOption; series = option.series; } self.clear(); legend = component.legend; if (legend) { getColor = legend.getColor; isSelected = legend.isSelected; } else { var colorIndices = {}; var colorMap = {}; var count = 0; getColor = function(key) { if (colorMap[key]) { return colorMap[key]; } if (colorIndices[key] === undefined) { colorIndices[key] = count++; } // key is serie name for (var i = 0; i < chordSeries.length; i++) { if (chordSeries[i].name === key) { colorMap[key] = self.query( chordSeries[i], 'itemStyle.normal.color' ); break; } } if (!colorMap[key]) { var len = groups.length; // key is group name for (var i = 0; i < len; i++) { if (groups[i].name === key) { colorMap[key] = self.query( groups[i], 'itemStyle.normal.color' ); break; } } } if (!colorMap[key]) { colorMap[key] = zr.getColor(colorIndices[key]); } return colorMap[key]; }; isSelected = function() { return true; }; } _buildShape(); } function reformOption(opt) { var _merge = zrUtil.merge; opt = _merge( opt || {}, ecConfig.chord, { 'overwrite' : false, 'recursive' : true } ); opt.itemStyle.normal.label.textStyle = _merge( opt.itemStyle.normal.label.textStyle || {}, ecConfig.textStyle, { 'overwrite' : false, 'recursive' : true } ); } self.init = init; self.refresh = refresh; self.reformOption = reformOption; init(option, component); } require('../chart').define('chord', Chord); return Chord; }); /** * echarts图表类:力导向图 * * @author pissang (https://github.com/pissang/) * */ define('echarts/chart/force',['require','../component/base','./calculableBase','../util/ecData','zrender/config','zrender/tool/event','zrender/tool/util','zrender/tool/vector','../util/ndarray','../chart'],function(require) { var requestAnimationFrame = window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(func){setTimeout(func, 16);}; // 保存节点的位置,改变数据时能够有更好的动画效果 var nodeInitialPos = {}; /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} series 数据 * @param {Object} component 组件 */ function Force(ecConfig, messageCenter, zr, option, component) { // 基类装饰 var ComponentBase = require('../component/base'); ComponentBase.call(this, ecConfig, zr); // 可计算特性装饰 var CalculableBase = require('./calculableBase'); CalculableBase.call(this, zr, option); var ecData = require('../util/ecData'); var zrConfig = require('zrender/config'); var zrEvent = require('zrender/tool/event'); // var zrColor = require('zrender/tool/color'); var zrUtil = require('zrender/tool/util'); var vec2 = require('zrender/tool/vector'); var NDArray = require('../util/ndarray'); var legend; var self = this; self.type = ecConfig.CHART_TYPE_FORCE; var series; var forceSerie; var nodeShapes = []; var linkShapes = []; // 节点分类 var categories = []; // 默认节点样式 var nodeStyle; var nodeEmphasisStyle; // 默认边样式 var linkStyle; var linkEmphasisStyle; var rawNodes; var rawLinks; // nodes和links过滤后的原始数据 var filteredNodes = []; var filteredLinks = []; // nodes和links的权重, 用来计算引力和斥力 var nodeWeights = []; var linkWeights = []; // 节点的受力 var nodeForces = []; // 节点的位置 var nodePositions = []; var nodePrePositions = []; // 节点的质量 var nodeMasses = []; var temperature; var k; //- ----------外部参数 var density; var initSize; var coolDown; var centripetal; // var initializeSize; // defined but never used var attractiveness; //- ---------- var stepTime = 1/60; var viewportWidth; var viewportHeight; var centroid = []; var mouseX, mouseY; function _buildShape() { legend = component.legend; temperature = 1.0; viewportWidth = zr.getWidth(); viewportHeight = zr.getHeight(); centroid = [viewportWidth/2, viewportHeight/2]; var serieName; for (var i = 0, l = series.length; i < l; i++) { var serie = series[i]; if (serie.type === ecConfig.CHART_TYPE_FORCE) { series[i] = self.reformOption(series[i]); serieName = series[i].name || ''; // 系列图例开关 self.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true; if (!self.selectedMap[serieName]) { continue; } self.buildMark( series[i], i, component ); forceSerie = serie; var minRadius = self.query(serie, 'minRadius'); var maxRadius = self.query(serie, 'maxRadius'); // ----------获取外部参数 attractiveness = self.query( serie, 'attractiveness' ); density = self.query(serie, 'density'); initSize = self.query(serie, 'initSize'); centripetal = self.query(serie, 'centripetal'); coolDown = self.query(serie, 'coolDown'); // ---------- categories = self.query(serie, 'categories'); // 同步selected状态 for (var j = 0, len = categories.length; j < len; j++) { if (categories[j].name) { if (legend){ self.selectedMap[j] = legend.isSelected(categories[j].name); } else { self.selectedMap[j] = true; } } } linkStyle = self.query( serie, 'itemStyle.normal.linkStyle' ); linkEmphasisStyle = self.query( serie, 'itemStyle.emphasis.linkStyle' ); nodeStyle = self.query( serie, 'itemStyle.normal.nodeStyle' ); nodeEmphasisStyle = self.query( serie, 'itemStyle.emphasis.nodeStyle' ); rawNodes = self.query(serie, 'nodes'); rawLinks = zrUtil.clone(self.query(serie, 'links')); _preProcessData(rawNodes, rawLinks); // Reset data nodePositions = []; nodePrePositions = []; nodeMasses = []; nodeWeights = []; linkWeights = []; nodeMasses = []; nodeShapes = []; linkShapes = []; var area = viewportWidth * viewportHeight; // Formula in 'Graph Drawing by Force-directed Placement' k = 0.5 / attractiveness * Math.sqrt(area / filteredNodes.length); // 这两方法里需要加上读取self.selectedMap判断当前系列是否显示的逻辑 _buildLinkShapes(filteredNodes, filteredLinks); _buildNodeShapes(filteredNodes, minRadius, maxRadius); } } } function _preProcessData(nodes, links) { var filteredNodeMap = []; var cursor = 0; filteredNodes = _filter(nodes, function(node, idx) { if (!node) { return; } if (node.ignore) { return; } if (self.selectedMap[node.category]) { filteredNodeMap[idx] = cursor++; return true; } else { filteredNodeMap[idx] = -1; } }); var source; var target; var ret; filteredLinks = _filter(links, function(link, idx){ source = link.source; target = link.target; ret = true; if (filteredNodeMap[source] >= 0) { link.source = filteredNodeMap[source]; } else { ret = false; } if (filteredNodeMap[target] >= 0) { link.target = filteredNodeMap[target]; } else { ret = false; } // 保存原始链接中的index link.rawIndex = idx; return ret; }); } function _buildNodeShapes(nodes, minRadius, maxRadius) { // 将值映射到minRadius-maxRadius的范围上 var radius = []; var l = nodes.length; for (var i = 0; i < l; i++) { var node = nodes[i]; if (node.value !== undefined) { radius.push(node.value); } else { radius.push(1); } } var narr = new NDArray(radius); radius = narr.map(minRadius, maxRadius) .toArray(); var max = narr.max(); if (max !== 0) { nodeWeights = narr.mul(1/max, narr).toArray(); } for (var i = 0; i < l; i++) { var node = nodes[i]; var x, y; var r = radius[i]; var initPos; if (node.initial !== undefined) { initPos = node.initial; } else if (nodeInitialPos[node.name] !== undefined) { initPos = nodeInitialPos[node.name]; } else { initPos = _randomInSquare( viewportWidth/2, viewportHeight/2, initSize ); } var x = initPos[0]; var y = initPos[1]; // 初始化位置 nodePositions[i] = vec2.create(x, y); nodePrePositions[i] = vec2.create(x, y); // 初始化受力 nodeForces[i] = vec2.create(0, 0); // 初始化质量 nodeMasses[i] = r * r * density * 0.035; var shape = { id : zr.newShapeId(self.type), shape : 'circle', style : { r : r, x : 0, y : 0 }, clickable : true, highlightStyle : {}, position : [x, y], __forceIndex : i }; // Label var labelStyle; if (self.query(forceSerie, 'itemStyle.normal.label.show') ) { shape.style.text = node.name; shape.style.textPosition = 'inside'; labelStyle = self.query( forceSerie, 'itemStyle.normal.label.textStyle' ) || {}; shape.style.textColor = labelStyle.color || '#fff'; shape.style.textAlign = labelStyle.align || 'center'; shape.style.textBaseline = labelStyle.baseline || 'middle'; shape.style.textFont = self.getFont(labelStyle); } if (self.query(forceSerie, 'itemStyle.emphasis.label.show')) { shape.highlightStyle.text = node.name; shape.highlightStyle.textPosition = 'inside'; labelStyle = self.query( forceSerie, 'itemStyle.emphasis.label.textStyle' ) || {}; shape.highlightStyle.textColor = labelStyle.color || '#fff'; shape.highlightStyle.textAlign = labelStyle.align || 'center'; shape.highlightStyle.textBaseline = labelStyle.baseline || 'middle'; shape.highlightStyle.textFont = self.getFont(labelStyle); } // 优先级 node.style > category.style > defaultStyle zrUtil.merge(shape.style, nodeStyle); zrUtil.merge(shape.highlightStyle, nodeEmphasisStyle); if (typeof(node.category) !== 'undefined') { var category = categories[node.category]; if (category) { if (legend) { shape.style.color = legend.getColor(category.name); } var style = category.itemStyle; if (style) { if (style.normal) { zrUtil.merge(shape.style, style.normal, { overwrite : true }); } if (style.emphasis) { zrUtil.merge( shape.highlightStyle, style.emphasis, { overwrite : true } ); } } } } if (typeof(node.itemStyle) !== 'undefined') { var style = node.itemStyle; if(style.normal ){ zrUtil.merge(shape.style, style.normal, { overwrite : true }); } if(style.normal ){ zrUtil.merge(shape.highlightStyle, style.emphasis, { overwrite : true }); } } // 拖拽特性 self.setCalculable(shape); shape.dragEnableTime = 0; shape.ondragstart = self.shapeHandler.ondragstart; shape.draggable = true; nodeShapes.push(shape); self.shapeList.push(shape); var categoryName = ''; if (typeof(node.category) !== 'undefined') { var category = categories[node.category]; categoryName = (category && category.name) || ''; } // !!Pack data before addShape ecData.pack( shape, // category { name : categoryName }, // series index 0, // data node, // data index zrUtil.indexOf(rawNodes, node), // name node.name || '', // value node.value ); zr.addShape(shape); } // _normalize(nodeMasses, nodeMasses); } function _buildLinkShapes(nodes, links) { var l = links.length; for (var i = 0; i < l; i++) { var link = links[i]; // var source = nodes[link.source]; // var target = nodes[link.target]; if (link.weight !== undefined) { linkWeights.push(link.weight); } else { linkWeights.push(1); } var linkShape = { id : zr.newShapeId(self.type), shape : 'line', style : { xStart : 0, yStart : 0, xEnd : 0, yEnd : 0, lineWidth : 1 }, clickable : true, highlightStyle : {} }; zrUtil.merge(linkShape.style, linkStyle); zrUtil.merge(linkShape.highlightStyle, linkEmphasisStyle); if (typeof(link.itemStyle) !== 'undefined') { if(link.itemStyle.normal){ zrUtil.merge(linkShape.style, link.itemStyle.normal, { overwrite : true }); } if(link.itemStyle.emphasis){ zrUtil.merge( linkShape.highlightStyle, link.itemStyle.emphasis, { overwrite : true } ); } } linkShapes.push(linkShape); self.shapeList.push(linkShape); var source = filteredNodes[link.source]; var target = filteredNodes[link.target]; var link = rawLinks[link.rawIndex]; ecData.pack( linkShape, // serie forceSerie, // serie index 0, // link data { source : link.source, target : link.target, weight : link.weight || 0 }, // link data index link.rawIndex, // source name - target name source.name + ' - ' + target.name, // link weight link.weight || 0, // special // 这一项只是为了表明这是条边 true ); zr.addShape(linkShape); } var narr = new NDArray(linkWeights); var max = narr.max(); if (max !== 0) { linkWeights = narr.mul(1/max, narr).toArray(); } } function _updateLinkShapes(){ for (var i = 0, l = filteredLinks.length; i < l; i++) { var link = filteredLinks[i]; var linkShape = linkShapes[i]; var sourceShape = nodeShapes[link.source]; var targetShape = nodeShapes[link.target]; linkShape.style.xStart = sourceShape.position[0]; linkShape.style.yStart = sourceShape.position[1]; linkShape.style.xEnd = targetShape.position[0]; linkShape.style.yEnd = targetShape.position[1]; } } function _update(stepTime) { var len = nodePositions.length; var v12 = []; // 计算节点之间斥力 var k2 = k*k; // Reset force for (var i = 0; i < len; i++) { nodeForces[i][0] = 0; nodeForces[i][1] = 0; } for (var i = 0; i < len; i++) { for (var j = i+1; j < len; j++){ var w1 = nodeWeights[i]; var w2 = nodeWeights[j]; var p1 = nodePositions[i]; var p2 = nodePositions[j]; // 节点1到2的向量 vec2.sub(v12, p2, p1); var d = vec2.length(v12); // 距离大于500忽略斥力 if(d > 500){ continue; } if(d < 5){ d = 5; } vec2.scale(v12, v12, 1 / d); var forceFactor = 1 * (w1 + w2) * k2 / d; //节点1受到的力 vec2.scaleAndAdd( nodeForces[i], nodeForces[i], v12, -forceFactor ); //节点2受到的力 vec2.scaleAndAdd( nodeForces[j], nodeForces[j], v12, forceFactor ); } } // 计算节点之间引力 for (var i = 0, l = filteredLinks.length; i < l; i++) { var link = filteredLinks[i]; var w = linkWeights[i]; var s = link.source; var t = link.target; var p1 = nodePositions[s]; var p2 = nodePositions[t]; vec2.sub(v12, p2, p1); var d2 = vec2.lengthSquare(v12); if (d2 === 0) { continue; } var forceFactor = w * d2 / k / Math.sqrt(d2); // 节点1受到的力 vec2.scaleAndAdd( nodeForces[s], nodeForces[s], v12, forceFactor ); // 节点2受到的力 vec2.scaleAndAdd( nodeForces[t], nodeForces[t], v12, -forceFactor ); } // 到质心的向心力 for (var i = 0, l = filteredNodes.length; i < l; i++){ var p = nodePositions[i]; vec2.sub(v12, centroid, p); var d2 = vec2.lengthSquare(v12); var forceFactor = d2 * centripetal / (100 * Math.sqrt(d2)); vec2.scaleAndAdd( nodeForces[i], nodeForces[i], v12, forceFactor ); } var velocity = []; // 计算位置(verlet积分) for (var i = 0, l = nodePositions.length; i < l; i++) { var name = filteredNodes[i].name; if (filteredNodes[i].fixed) { // 拖拽同步 vec2.set(nodePositions[i], mouseX, mouseY); vec2.set(nodePrePositions[i], mouseX, mouseY); vec2.set(nodeShapes[i].position, mouseX, mouseY); if (filteredNodes[i].initial !== undefined) { vec2.set(filteredNodes[i].initial, mouseX, mouseY); } if (nodeInitialPos[name] !== undefined) { vec2.set(nodeInitialPos[name], mouseX, mouseY); } continue; } var p = nodePositions[i]; var __P = nodePrePositions[i]; vec2.sub(velocity, p, __P); __P[0] = p[0]; __P[1] = p[1]; vec2.scaleAndAdd( velocity, velocity, nodeForces[i], stepTime / nodeMasses[i] ); // Damping vec2.scale(velocity, velocity, temperature); // 防止速度太大 velocity[0] = Math.max(Math.min(velocity[0], 100), -100); velocity[1] = Math.max(Math.min(velocity[1], 100), -100); vec2.add(p, p, velocity); vec2.copy(nodeShapes[i].position, p); if (name) { if (nodeInitialPos[name] === undefined) { nodeInitialPos[name] = vec2.create(); } vec2.copy(nodeInitialPos[name], p); } else { if (filteredNodes[i].initial === undefined) { filteredNodes[i].initial = vec2.create(); } vec2.copy(filteredNodes[i].initial, p); } // if(isNaN(p[0]) || isNaN(p[1])){ // throw new Error('NaN'); // } } } function _step(){ if (temperature < 0.01) { return; } _update(stepTime); _updateLinkShapes(); var tmp = {}; for (var i = 0; i < nodeShapes.length; i++) { var shape = nodeShapes[i]; tmp.position = shape.position; zr.modShape(shape.id, tmp, true); } tmp = {}; for (var i = 0; i < linkShapes.length; i++) { var shape = linkShapes[i]; tmp.style = shape.style; zr.modShape(shape.id, tmp, true); } zr.refresh(); // Cool Down temperature *= coolDown; } var _updating; function init(newOption, newComponent) { option = newOption; component = newComponent; series = option.series; self.clear(); _buildShape(); _updating = true; function cb() { if (_updating) { _step(); requestAnimationFrame(cb); } } requestAnimationFrame(cb); } function refresh(newOption) { if (newOption) { option = newOption; series = option.series; } self.clear(); _buildShape(); temperature = 1.0; } function dispose(){ _updating = false; } /** * 输出动态视觉引导线 */ self.shapeHandler.ondragstart = function() { self.isDragstart = true; }; function onclick() { } /** * 拖拽开始 */ function ondragstart(param) { if (!self.isDragstart || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } var shape = param.target; var idx = shape.__forceIndex; var node = filteredNodes[idx]; node.fixed = true; // 处理完拖拽事件后复位 self.isDragstart = false; zr.on(zrConfig.EVENT.MOUSEMOVE, _onmousemove); } /** * 数据项被拖拽出去,重载基类方法 */ function ondragend(param, status) { if (!self.isDragend || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } var shape = param.target; var idx = shape.__forceIndex; var node = filteredNodes[idx]; node.fixed = false; // 别status = {}赋值啊!! status.dragIn = true; //你自己refresh的话把他设为false,设true就会重新调refresh接口 status.needRefresh = false; // 处理完拖拽事件后复位 self.isDragend = false; zr.un(zrConfig.EVENT.MOUSEMOVE, _onmousemove); } // 拖拽中位移信息 function _onmousemove(param) { temperature = 0.8; mouseX = zrEvent.getX(param.event); mouseY = zrEvent.getY(param.event); } self.init = init; self.refresh = refresh; self.ondragstart = ondragstart; self.ondragend = ondragend; self.dispose = dispose; self.onclick = onclick; init(option, component); } /* function _randomInCircle(x, y, radius) { var theta = Math.random() * Math.PI * 2; var r = radius * Math.random(); return [ Math.cos(theta) * r + x, Math.sin(theta) * r + y ]; } */ function _randomInSquare(x, y, size) { return [ (Math.random() - 0.5) * size + x, (Math.random() - 0.5) * size + y ]; } function _filter(array, callback){ var len = array.length; var result = []; for(var i = 0; i < len; i++){ if(callback(array[i], i)){ result.push(array[i]); } } return result; } // 图表注册 require('../chart').define('force', Force); return Force; }); /** * 地图参数 * key为地图类型: { * getGeoJson: 地图数据加载 * } */ define('echarts/util/mapData/params',['require'],function(require) { function decode(json){ if (!json.UTF8Encoding) { return json; } var features = json.features; for (var f = 0; f < features.length; f++) { var feature = features[f]; var coordinates = feature.geometry.coordinates; var encodeOffsets = feature.geometry.encodeOffsets; for (var c = 0; c < coordinates.length; c++) { var coordinate = coordinates[c]; if (feature.geometry.type === 'Polygon') { coordinates[c] = decodePolygon( coordinate, encodeOffsets[c] ); } else if (feature.geometry.type === 'MultiPolygon') { for (var c2 = 0; c2 < coordinate.length; c2++) { var polygon = coordinate[c2]; coordinate[c2] = decodePolygon( polygon, encodeOffsets[c][c2] ); } } } } // Has been decoded json.UTF8Encoding = false; return json; } function decodePolygon(coordinate, encodeOffsets) { var result = []; var prevX = encodeOffsets[0]; var prevY = encodeOffsets[1]; for (var i = 0; i < coordinate.length; i+=2) { var x = coordinate.charCodeAt(i) - 64; var y = coordinate.charCodeAt(i+1) - 64; // ZigZag decoding x = (x >> 1) ^ (-(x & 1)); y = (y >> 1) ^ (-(y & 1)); // Delta deocding x += prevX; y += prevY; prevX = x; prevY = y; // Dequantize result.push([x / 1024, y / 1024]); } return result; } var mapParams = { 'world': { getGeoJson: function(callback) { require(['./geoJson/world_geo'], function(md){ callback(decode(md)); }); } }, 'china': { getGeoJson: function(callback) { require(['./geoJson/china_geo'], function(md){ callback(decode(md)); }); } }, '南海诸岛' : { textCoord : [126, 25], getPath : function(leftTop, scale) { // scale.x : width = 10.51 : 64 var pList = [ [ [0,3.5],[7,11.2],[15,11.9],[30,7],[42,0.7],[52,0.7], [56,7.7],[59,0.7],[64,0.7],[64,0],[5,0],[0,3.5] ], [ [13,16.1],[19,14.7],[16,21.7],[11,23.1],[13,16.1] ], [ [12,32.2],[14,38.5],[15,38.5],[13,32.2],[12,32.2] ], [ [16,47.6],[12,53.2],[13,53.2],[18,47.6],[16,47.6] ], [ [6,64.4],[8,70],[9,70],[8,64.4],[6,64.4] ], [ [23,82.6],[29,79.8],[30,79.8],[25,82.6],[23,82.6] ], [ [37,70.7],[43,62.3],[44,62.3],[39,70.7],[37,70.7] ], [ [48,51.1],[51,45.5],[53,45.5],[50,51.1],[48,51.1] ], [ [51,35],[51,28.7],[53,28.7],[53,35],[51,35] ], [ [52,22.4],[55,17.5],[56,17.5],[53,22.4],[52,22.4] ], [ [58,12.6],[62,7],[63,7],[60,12.6],[58,12.6] ], [ [0,3.5],[0,93.1],[64,93.1],[64,0],[63,0],[63,92.4], [1,92.4],[1,3.5],[0,3.5] ] ]; var str = ''; var left = leftTop[0]; var top = leftTop[1]; for (var i = 0, l = pList.length; i < l; i++) { str += 'M ' + ((pList[i][0][0] * scale+ left).toFixed(2) - 0) + ' ' + ((pList[i][0][1] * scale + top).toFixed(2) - 0) + ' '; for (var j = 1, k = pList[i].length; j < k; j++) { str += 'L ' + ((pList[i][j][0] * scale + left).toFixed(2) - 0) + ' ' + ((pList[i][j][1] * scale + top).toFixed(2) - 0) + ' '; } } return str + ' Z'; } }, '新疆': { getGeoJson: function(callback) { require(['./geoJson/xin_jiang_geo'], function(md){ callback(decode(md)); }); } }, '西藏': { getGeoJson: function(callback) { require(['./geoJson/xi_zang_geo'], function(md){ callback(decode(md)); }); } }, '内蒙古': { getGeoJson: function(callback) { require(['./geoJson/nei_meng_gu_geo'], function(md){ callback(decode(md)); }); } }, '青海': { getGeoJson: function(callback) { require(['./geoJson/qing_hai_geo'], function(md){ callback(decode(md)); }); } }, '四川': { getGeoJson: function(callback) { require(['./geoJson/si_chuan_geo'], function(md){ callback(decode(md)); }); } }, '黑龙江': { getGeoJson: function(callback) { require(['./geoJson/hei_long_jiang_geo'], function(md){ callback(decode(md)); }); } }, '甘肃': { getGeoJson: function(callback) { require(['./geoJson/gan_su_geo'], function(md){ callback(decode(md)); }); } }, '云南': { getGeoJson: function(callback) { require(['./geoJson/yun_nan_geo'], function(md){ callback(decode(md)); }); } }, '广西': { getGeoJson: function(callback) { require(['./geoJson/guang_xi_geo'], function(md){ callback(decode(md)); }); } }, '湖南': { getGeoJson: function(callback) { require(['./geoJson/hu_nan_geo'], function(md){ callback(decode(md)); }); } }, '陕西': { getGeoJson: function(callback) { require(['./geoJson/shan_xi_1_geo'], function(md){ callback(decode(md)); }); } }, '广东': { getGeoJson: function(callback) { require(['./geoJson/guang_dong_geo'], function(md){ callback(decode(md)); }); } }, '吉林': { getGeoJson: function(callback) { require(['./geoJson/ji_lin_geo'], function(md){ callback(decode(md)); }); } }, '河北': { getGeoJson: function(callback) { require(['./geoJson/he_bei_geo'], function(md){ callback(decode(md)); }); } }, '湖北': { getGeoJson: function(callback) { require(['./geoJson/hu_bei_geo'], function(md){ callback(decode(md)); }); } }, '贵州': { getGeoJson: function(callback) { require(['./geoJson/gui_zhou_geo'], function(md){ callback(decode(md)); }); } }, '山东': { getGeoJson: function(callback) { require(['./geoJson/shan_dong_geo'], function(md){ callback(decode(md)); }); } }, '江西': { getGeoJson: function(callback) { require(['./geoJson/jiang_xi_geo'], function(md){ callback(decode(md)); }); } }, '河南': { getGeoJson: function(callback) { require(['./geoJson/he_nan_geo'], function(md){ callback(decode(md)); }); } }, '辽宁': { getGeoJson: function(callback) { require(['./geoJson/liao_ning_geo'], function(md){ callback(decode(md)); }); } }, '山西': { getGeoJson: function(callback) { require(['./geoJson/shan_xi_2_geo'], function(md){ callback(decode(md)); }); } }, '安徽': { getGeoJson: function(callback) { require(['./geoJson/an_hui_geo'], function(md){ callback(decode(md)); }); } }, '福建': { getGeoJson: function(callback) { require(['./geoJson/fu_jian_geo'], function(md){ callback(decode(md)); }); } }, '浙江': { getGeoJson: function(callback) { require(['./geoJson/zhe_jiang_geo'], function(md){ callback(decode(md)); }); } }, '江苏': { getGeoJson: function(callback) { require(['./geoJson/jiang_su_geo'], function(md){ callback(decode(md)); }); } }, '重庆': { getGeoJson: function(callback) { require(['./geoJson/chong_qing_geo'], function(md){ callback(decode(md)); }); } }, '宁夏': { getGeoJson: function(callback) { require(['./geoJson/ning_xia_geo'], function(md){ callback(decode(md)); }); } }, '海南': { getGeoJson: function(callback) { require(['./geoJson/hai_nan_geo'], function(md){ callback(decode(md)); }); } }, '台湾': { getGeoJson: function(callback) { require(['./geoJson/tai_wan_geo'], function(md){ callback(decode(md)); }); } }, '北京': { getGeoJson: function(callback) { require(['./geoJson/bei_jing_geo'], function(md){ callback(decode(md)); }); } }, '天津': { getGeoJson: function(callback) { require(['./geoJson/tian_jin_geo'], function(md){ callback(decode(md)); }); } }, '上海': { getGeoJson: function(callback) { require(['./geoJson/shang_hai_geo'], function(md){ callback(decode(md)); }); } }, '香港': { getGeoJson: function(callback) { require(['./geoJson/xiang_gang_geo'], function(md){ callback(decode(md)); }); } }, '澳门': { getGeoJson: function(callback) { require(['./geoJson/ao_men_geo'], function(md){ callback(decode(md)); }); } } }; return { decode : decode, params : mapParams }; }); /** * 地图文本位置修正 */ define('echarts/util/mapData/textFixed',[],function() { // fix = [xFixed, yFixed, scale] // textX += fix[0]; // textY += fix[1]; return { //'南海诸岛' : [32, 83], // 全国 '广东': [0, -10], '香港': [10, 10], '澳门': [-10, 18], '黑龙江' : [0, 20], //'北京': [-10, 0], '天津': [5, 5], // 广东 '深圳市': [-35, 0], // 云南 '红河哈尼族彝族自治州' : [0, 20], '楚雄彝族自治州': [-5, 15], // 新疆 '石河子市': [-5, 5], '五家渠市': [0, -10], '昌吉回族自治州': [10, 10], // 海南 '昌江黎族自治县': [0,20], '陵水黎族自治县': [0,20], '东方市': [0,20], // 陕西 '渭南市': [0,20] }; }); /** * 经纬度坐标,优先于自定计算 */ define('echarts/util/mapData/geoCoord',[],function() { return { 'Russia' : [100, 60], 'United States of America' : [-99, 38] }; }); /** * echarts地图一般投射算法 * modify from GeoMap v0.5.3 https://github.com/x6doooo/GeoMap * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/util/projection/normal',[],function() { function getBbox(json, specialArea) { specialArea = specialArea || {}; if (!json.srcSize) { parseSrcSize(json, specialArea); } return json.srcSize; } function parseSrcSize(json, specialArea) { specialArea = specialArea || {}; convertorParse.xmin = 360; convertorParse.xmax = -360; convertorParse.ymin = 180; convertorParse.ymax = -180; var shapes = json.features; var geometries; var shape; for (var i = 0, len = shapes.length; i < len; i++) { shape = shapes[i]; if (shape.properties.name && specialArea[shape.properties.name]) { continue; } if (shape.type == 'Feature') { convertorParse[shape.geometry.type]( shape.geometry.coordinates ); } else if (shape.type == 'GeometryCollection') { geometries = shape.geometries; for (var j = 0, len2 = geometries.length; j < len2; j++) { convertorParse[geometries[j].type]( geometries[j].coordinates ); } } } json.srcSize = { left : convertorParse.xmin.toFixed(4)*1, top : convertorParse.ymin.toFixed(4)*1, width : (convertorParse.xmax - convertorParse.xmin).toFixed(4)*1, height : (convertorParse.ymax - convertorParse.ymin).toFixed(4)*1 }; return json; } var convertor = { //调整俄罗斯东部到地图右侧与俄罗斯相连 'formatPoint' : function(p) { return [ ((p[0] < -168.5 && p[1] > 63.8) ? p[0] + 360 : p[0]) + 168.5, 90 - p[1] ]; }, 'makePoint' : function(p) { var self = this; var point = self.formatPoint(p); // for cp if (self._bbox.xmin > p[0]) { self._bbox.xmin = p[0]; } if (self._bbox.xmax < p[0]) { self._bbox.xmax = p[0]; } if (self._bbox.ymin > p[1]) { self._bbox.ymin = p[1]; } if (self._bbox.ymax < p[1]) { self._bbox.ymax = p[1]; } var x = (point[0] - convertor.offset.x) * convertor.scale.x + convertor.offset.left; var y = (point[1] - convertor.offset.y) * convertor.scale.y + convertor.offset.top; return [x, y]; }, 'Point' : function(coordinates) { coordinates = this.makePoint(coordinates); return coordinates.join(','); }, 'LineString' : function(coordinates) { var str = ''; var point; for (var i = 0, len = coordinates.length; i < len; i++) { point = convertor.makePoint(coordinates[i]); if (i === 0) { str = 'M' + point.join(','); } else { str = str + 'L' + point.join(','); } } return str; }, 'Polygon' : function(coordinates) { var str = ''; for (var i = 0, len = coordinates.length; i < len; i++) { str = str + convertor.LineString(coordinates[i]) + 'z'; } return str; }, 'MultiPoint' : function(coordinates) { var arr = []; for (var i = 0, len = coordinates.length; i < len; i++) { arr.push(convertor.Point(coordinates[i])); } return arr; }, 'MultiLineString' : function(coordinates) { var str = ''; for (var i = 0, len = coordinates.length; i < len; i++) { str += convertor.LineString(coordinates[i]); } return str; }, 'MultiPolygon' : function(coordinates) { var str = ''; for (var i = 0, len = coordinates.length; i < len; i++) { str += convertor.Polygon(coordinates[i]); } return str; } }; var convertorParse = { 'formatPoint' : convertor.formatPoint, 'makePoint' : function(p) { var self = this; var point = self.formatPoint(p); var x = point[0]; var y = point[1]; if (self.xmin > x) { self.xmin = x; } if (self.xmax < x) { self.xmax = x; } if (self.ymin > y) { self.ymin = y; } if (self.ymax < y) { self.ymax = y; } }, 'Point' : function(coordinates) { this.makePoint(coordinates); }, 'LineString' : function(coordinates) { for (var i = 0, len = coordinates.length; i < len; i++) { this.makePoint(coordinates[i]); } }, 'Polygon' : function(coordinates) { for (var i = 0, len = coordinates.length; i < len; i++) { this.LineString(coordinates[i]); } }, 'MultiPoint' : function(coordinates) { for (var i = 0, len = coordinates.length; i < len; i++) { this.Point(coordinates[i]); } }, 'MultiLineString' : function(coordinates) { for (var i = 0, len = coordinates.length; i < len; i++) { this.LineString(coordinates[i]); } }, 'MultiPolygon' : function(coordinates) { for (var i = 0, len = coordinates.length; i < len; i++) { this.Polygon(coordinates[i]); } } }; function geoJson2Path(json, transform, specialArea) { specialArea = specialArea || {}; convertor.scale = null; convertor.offset = null; if (!json.srcSize) { parseSrcSize(json, specialArea); } transform.offset = { x : json.srcSize.left, y : json.srcSize.top, left : transform.OffsetLeft || 0, top : transform.OffsetTop || 0 }; convertor.scale = transform.scale; convertor.offset = transform.offset; var shapes = json.features; var geometries; var pathArray = []; var val; var shape; for (var i = 0, len = shapes.length; i < len; i++) { shape = shapes[i]; if (shape.properties.name && specialArea[shape.properties.name]) { // 忽略specialArea continue; } if (shape.type == 'Feature') { pushApath(shape.geometry, shape); } else if (shape.type == 'GeometryCollection') { geometries = shape.geometries; for (var j = 0, len2 = geometries.length; j < len2; j++) { val = geometries[j]; pushApath(val, val); } } } var shapeType; var shapeCoordinates; var str; function pushApath(gm, shape) { shapeType = gm.type; shapeCoordinates = gm.coordinates; convertor._bbox = { xmin : 360, xmax : -360, ymin : 180, ymax : -180 }; str = convertor[shapeType](shapeCoordinates); pathArray.push({ //type : shapeType, path : str, cp : shape.properties.cp ? convertor.makePoint(shape.properties.cp) : convertor.makePoint([ (convertor._bbox.xmin + convertor._bbox.xmax) / 2, (convertor._bbox.ymin + convertor._bbox.ymax) / 2 ]), properties : shape.properties, id : shape.id }); } return pathArray; } /** * 平面坐标转经纬度 * @param {Array} p */ function pos2geo(obj, p) { var x; var y; if (p instanceof Array) { x = p[0] * 1; y = p[1] * 1; } else { x = p.x * 1; y = p.y * 1; } x = x / obj.scale.x + obj.offset.x - 168.5; x = x > 180 ? x - 360 : x; y = 90 - (y / obj.scale.y + obj.offset.y); return [x, y]; } /** * 经纬度转平面坐标 * @param {Array | Object} p */ function geo2pos(obj, p) { convertor.offset = obj.offset; convertor.scale = obj.scale; return p instanceof Array ? convertor.makePoint([p[0] * 1, p[1] * 1]) : convertor.makePoint([p.x * 1, p.y * 1]); } return { getBbox : getBbox, geoJson2Path : geoJson2Path, pos2geo : pos2geo, geo2pos : geo2pos }; }); /** * echarts图表类:地图 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/chart/map',['require','../component/base','./calculableBase','../util/ecData','zrender/config','zrender/tool/util','zrender/tool/event','../util/mapData/params','../util/mapData/textFixed','../util/mapData/geoCoord','../util/projection/normal','../util/projection/normal','../util/projection/normal','../util/projection/normal','../chart'],function(require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} series 数据 * @param {Object} component 组件 */ function Map(ecConfig, messageCenter, zr, option, component){ // 基类装饰 var ComponentBase = require('../component/base'); ComponentBase.call(this, ecConfig, zr); // 可计算特性装饰 var CalculableBase = require('./calculableBase'); CalculableBase.call(this, zr, option); var ecData = require('../util/ecData'); var zrConfig = require('zrender/config'); var zrUtil = require('zrender/tool/util'); var zrEvent = require('zrender/tool/event'); var self = this; self.type = ecConfig.CHART_TYPE_MAP; var series; // 共享数据源,不要修改跟自己无关的项 var _zlevelBase = self.getZlevelBase(); var _selectedMode; // 选择模式 var _hoverable; // 悬浮高亮模式,索引到图表 var _showLegendSymbol; // 显示图例颜色标识 var _selected = {}; // 地图选择状态 var _mapTypeMap = {}; // 图例类型索引 var _mapDataMap = {}; // 根据地图类型索引bbox,transform,path var _shapeListMap = {}; // 名字到shapeList关联映射 var _nameMap = {}; // 个性化地名 var _specialArea = {}; // 特殊 var _refreshDelayTicket; // 滚轮缩放时让refresh飞一会 var _mapDataRequireCounter; var _mapParams = require('../util/mapData/params').params; var _textFixed = require('../util/mapData/textFixed'); var _geoCoord = require('../util/mapData/geoCoord'); // 漫游相关信息 var _roamMap = {}; var _needRoam; var _mx; var _my; var _mousedown; var _justMove; // 避免移动响应点击 var _curMapType; // 当前移动的地图类型 var _markAnimation = false; function _buildShape() { self.selectedMap = {}; var legend = component.legend; var seriesName; var valueData = {}; var mapType; var data; var name; var mapSeries = {}; var mapValuePrecision = {}; _selectedMode = {}; _hoverable = {}; _showLegendSymbol = {}; var valueCalculation = {}; _needRoam = false; for (var i = 0, l = series.length; i < l; i++) { if (series[i].type == ecConfig.CHART_TYPE_MAP) { // map series[i] = self.reformOption(series[i]); mapType = series[i].mapType; mapSeries[mapType] = mapSeries[mapType] || {}; mapSeries[mapType][i] = true; mapValuePrecision[mapType] = mapValuePrecision[mapType] || series[i].mapValuePrecision; _roamMap[mapType] = series[i].roam || _roamMap[mapType]; _needRoam = _needRoam || _roamMap[mapType]; _nameMap[mapType] = series[i].nameMap || _nameMap[mapType] || {}; if (series[i].textFixed) { zrUtil.mergeFast( _textFixed, series[i].textFixed, true, false ); } if (series[i].geoCoord) { zrUtil.mergeFast( _geoCoord, series[i].geoCoord, true, false ); } _selectedMode[mapType] = _selectedMode[mapType] || series[i].selectedMode; if (typeof _hoverable[mapType] == 'undefined' || _hoverable[mapType] // false 1票否决 ) { _hoverable[mapType] = series[i].hoverable; } if (typeof _showLegendSymbol[mapType] == 'undefined' || _showLegendSymbol[mapType] // false 1票否决 ) { _showLegendSymbol[mapType] = series[i].showLegendSymbol; } valueCalculation[mapType] = valueCalculation[mapType] || series[i].mapValueCalculation; seriesName = series[i].name; self.selectedMap[seriesName] = legend ? legend.isSelected(seriesName) : true; if (self.selectedMap[seriesName]) { valueData[mapType] = valueData[mapType] || {}; data = series[i].data; for (var j = 0, k = data.length; j < k; j++) { name = _nameChange(mapType, data[j].name); valueData[mapType][name] = valueData[mapType][name] || {seriesIndex : []}; for (var key in data[j]) { if (key != 'value') { valueData[mapType][name][key] = data[j][key]; } else if (!isNaN(data[j].value)) { typeof valueData[mapType][name].value == 'undefined' && (valueData[mapType][name].value = 0); valueData[mapType][name].value += data[j].value; } } //索引有该区域的系列样式 valueData[mapType][name].seriesIndex.push(i); } } } } _mapDataRequireCounter = 0; for (var mt in valueData) { _mapDataRequireCounter++; } for (var mt in valueData) { if (valueCalculation[mt] && valueCalculation[mt] == 'average') { for (var k in valueData[mt]) { valueData[mt][k].value = (valueData[mt][k].value / valueData[mt][k].seriesIndex.length) .toFixed( mapValuePrecision[mt] ) - 0; } } _mapDataMap[mt] = _mapDataMap[mt] || {}; if (_mapDataMap[mt].mapData) { // 已经缓存了则直接用 _mapDataCallback(mt, valueData[mt], mapSeries[mt])( _mapDataMap[mt].mapData ); } else if (_mapParams[mt.replace(/\|.*/, '')].getGeoJson) { // 特殊区域 _specialArea[mt] = _mapParams[mt.replace(/\|.*/, '')].specialArea || _specialArea[mt]; _mapParams[mt.replace(/\|.*/, '')].getGeoJson( _mapDataCallback(mt, valueData[mt], mapSeries[mt]) ); } } } /** * @param {string} mt mapType * @parma {Object} vd valueData * @param {Object} ms mapSeries */ function _mapDataCallback(mt, vd, ms) { return function(md) { if (!self) { // 异步地图数据回调时有可能实例已经被释放 return; } // 缓存这份数据 if (mt.indexOf('|') != -1) { // 子地图,加工一份新的mapData md = _getSubMapData(mt, md); } _mapDataMap[mt].mapData = md; _buildMap( mt, // 类型 _getProjectionData( // 地图数据 mt, md, ms ), vd, // 用户数据 ms // 系列 ); _buildMark(mt, ms); if (--_mapDataRequireCounter <= 0) { _shapeListMap = {}; for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); // 通过name关联shape,用于onmouseover if (self.shapeList[i].shape == 'path' && typeof self.shapeList[i].style._text != 'undefined' ) { _shapeListMap[self.shapeList[i].style._text] = self.shapeList[i]; } } zr.refresh(); if (!_markAnimation) { _markAnimation = true; if (option.animation && !option.renderAsImage) { self.animationMark(option.animationDuration); } } else { self.animationEffect(); } } }; } function _getSubMapData(mapType, mapData) { var subType = mapType.replace(/^.*\|/, ''); var features = mapData.features; for (var i = 0, l = features.length; i < l; i++) { if (features[i].properties && features[i].properties.name == subType ) { features = features[i]; if (subType == 'United States of America' && features.geometry.coordinates.length > 1 // 未被简化 ) { features = { geometry: { coordinates: features.geometry .coordinates.slice(5,6), type: features.geometry.type }, id: features.id, properties: features.properties, type: features.type }; } break; } } return { 'type' : 'FeatureCollection', 'features':[ features ] }; } /** * 按需加载相关地图 */ function _getProjectionData(mapType, mapData, mapSeries) { var normalProjection = require('../util/projection/normal'); var province = []; // bbox永远不变 var bbox = _mapDataMap[mapType].bbox || normalProjection.getBbox( mapData, _specialArea[mapType] ); //console.log(bbox) var transform; //console.log(1111,transform) if (!_mapDataMap[mapType].hasRoam) { // 第一次或者发生了resize,需要判断 transform = _getTransform( bbox, mapSeries ); } else { //经过用户漫游不再响应resize transform = _mapDataMap[mapType].transform; } //console.log(bbox,transform) var lastTransform = _mapDataMap[mapType].lastTransform || {scale:{}}; var pathArray; if (transform.left != lastTransform.left || transform.top != lastTransform.top || transform.scale.x != lastTransform.scale.x || transform.scale.y != lastTransform.scale.y ) { // 发生过变化,需要重新生成pathArray // 一般投射 //console.log(transform) pathArray = normalProjection.geoJson2Path( mapData, transform, _specialArea[mapType] ); lastTransform = zrUtil.clone(transform); } else { transform = _mapDataMap[mapType].transform; pathArray = _mapDataMap[mapType].pathArray; } _mapDataMap[mapType].bbox = bbox; _mapDataMap[mapType].transform = transform; _mapDataMap[mapType].lastTransform = lastTransform; _mapDataMap[mapType].pathArray = pathArray; //console.log(pathArray) var position = [transform.left, transform.top]; for (var i = 0, l = pathArray.length; i < l; i++) { /* for test console.log( mapData.features[i].properties.cp, // 经纬度度 pathArray[i].cp // 平面坐标 ); console.log( pos2geo(mapType, pathArray[i].cp), // 平面坐标转经纬度 geo2pos(mapType, mapData.features[i].properties.cp) ) */ province.push(_getSingleProvince( mapType, pathArray[i], position )); } if (_specialArea[mapType]) { for (var area in _specialArea[mapType]) { province.push(_getSpecialProjectionData( mapType, mapData, area, _specialArea[mapType][area], position )); } } // 中国地图加入南海诸岛 if (mapType == 'china') { var leftTop = geo2pos( mapType, _geoCoord['南海诸岛'] || _mapParams['南海诸岛'].textCoord ); // scale.x : width = 10.51 : 64 var scale = transform.scale.x / 10.5; var textPosition = [ 32 * scale + leftTop[0], 83 * scale + leftTop[1] ]; if (_textFixed['南海诸岛']) { textPosition[0] += _textFixed['南海诸岛'][0]; textPosition[1] += _textFixed['南海诸岛'][1]; } province.push({ text : _nameChange(mapType, '南海诸岛'), path : _mapParams['南海诸岛'].getPath( leftTop, scale ), position : position, textX : textPosition[0], textY : textPosition[1] }); } return province; } /** * 特殊地区投射数据 */ function _getSpecialProjectionData( mapType, mapData, areaName, mapSize, position ) { //console.log('_getSpecialProjectionData--------------') // 构造单独的geoJson地图数据 mapData = _getSubMapData('x|' + areaName, mapData); // bbox var normalProjection = require('../util/projection/normal'); var bbox = normalProjection.getBbox(mapData); //console.log('bbox', bbox) // transform var leftTop = geo2pos( mapType, [mapSize.left, mapSize.top] ); var rightBottom = geo2pos( mapType, [mapSize.left + mapSize.width, mapSize.top + mapSize.height] ); //console.log('leftright' , leftTop, rightBottom); var width = Math.abs(rightBottom[0] - leftTop[0]); var height = Math.abs(rightBottom[1] - leftTop[1]); var mapWidth = bbox.width; var mapHeight = bbox.height; //var minScale; var xScale = (width / 0.75) / mapWidth; var yScale = height / mapHeight; if (xScale > yScale) { xScale = yScale * 0.75; width = mapWidth * xScale; } else { yScale = xScale; xScale = yScale * 0.75; height = mapHeight * yScale; } var transform = { OffsetLeft : leftTop[0], OffsetTop : leftTop[1], //width: width, //height: height, scale : { x : xScale, y : yScale } }; //console.log('**',areaName, transform) var pathArray = normalProjection.geoJson2Path( mapData, transform ); //console.log(pathArray) return _getSingleProvince( mapType, pathArray[0], position ); } function _getSingleProvince(mapType, path, position) { var textPosition; var name = path.properties.name; if (_geoCoord[name]) { textPosition = geo2pos( mapType, _geoCoord[name] ); } else if (path.cp) { textPosition = [path.cp[0], path.cp[1]]; } /* else { textPosition = geo2pos( mapType, [bbox.left + bbox.width / 2, bbox.top + bbox.height / 2] ); } */ if (_textFixed[name]) { textPosition[0] += _textFixed[name][0]; textPosition[1] += _textFixed[name][1]; } //console.log(textPosition) return { text : _nameChange(mapType, name), path : path.path, position : position, textX : textPosition[0], textY : textPosition[1] }; } /** * 获取缩放 */ function _getTransform(bbox, mapSeries) { var mapLocation; var x; var cusX; var y; var cusY; var width; var height; var zrWidth = zr.getWidth(); var zrHeight = zr.getHeight(); //上下左右留空 var padding = Math.round(Math.min(zrWidth, zrHeight) * 0.02); for (var key in mapSeries) { mapLocation = series[key].mapLocation; cusX = mapLocation.x || cusX; cusY = mapLocation.y || cusY; width = mapLocation.width || width; height = mapLocation.height || height; } //x = isNaN(cusX) ? padding : cusX; x = self.parsePercent(cusX, zrWidth); x = isNaN(x) ? padding : x; //y = isNaN(cusY) ? padding : cusY; y = self.parsePercent(cusY, zrHeight); y = isNaN(y) ? padding : y; if (typeof width == 'undefined') { width = isNaN(cusX) ? zrWidth - 2 * padding : zrWidth - x - 2 * padding; } else { width = self.parsePercent(width, zrWidth); } if (typeof height == 'undefined') { height = isNaN(cusY) ? zrHeight - 2 * padding : zrHeight - y - 2 * padding; } else { height = self.parsePercent(height, zrHeight); } var mapWidth = bbox.width; var mapHeight = bbox.height; //var minScale; var xScale = (width / 0.75) / mapWidth; var yScale = height / mapHeight; if (xScale > yScale) { //minScale = yScale; xScale = yScale * 0.75; width = mapWidth * xScale; } else { //minScale = xScale; yScale = xScale; xScale = yScale * 0.75; height = mapHeight * yScale; } //console.log(minScale) //width = mapWidth * minScale; //height = mapHeight * minScale; if (isNaN(cusX)) { switch (cusX + '') { case 'center' : x = Math.floor((zrWidth - width) / 2); break; case 'right' : x = zrWidth - width; break; //case 'left' : default: //x = padding; break; } } //console.log(cusX,x,zrWidth,width,'kener') if (isNaN(cusY)) { switch (cusY + '') { case 'center' : y = Math.floor((zrHeight - height) / 2); break; case 'bottom' : y = zrHeight - height; break; //case 'top' : default: //y = padding; break; } } //console.log(x,y,width,height) return { left : x, top : y, width: width, height: height, //scale : minScale * 50, // wtf 50 scale : { x : xScale, y : yScale } //translate : [x + width / 2, y + height / 2] }; } /** * 构建地图 * @param {Object} mapData 图形数据 * @param {Object} valueData 用户数据 */ function _buildMap(mapType, mapData, valueData, mapSeries) { var legend = component.legend; var dataRange = component.dataRange; var seriesName; var name; var data; var value; var queryTarget; var defaultOption = ecConfig.map; var color; var font; var style; var highlightStyle; var shape; var textShape; for (var i = 0, l = mapData.length; i < l; i++) { style = zrUtil.clone(mapData[i]); highlightStyle = zrUtil.clone(style); name = style.text; data = valueData[name]; // 多系列合并后的数据 if (data) { queryTarget = [data]; // level 3 seriesName = ''; for (var j = 0, k = data.seriesIndex.length; j < k; j++) { // level 2 queryTarget.push(series[data.seriesIndex[j]]); seriesName += series[data.seriesIndex[j]].name + ' '; if (legend && _showLegendSymbol[mapType] && legend.hasColor(series[data.seriesIndex[j]].name) ) { self.shapeList.push({ shape : 'circle', zlevel : _zlevelBase + 1, position : style.position, _mapType : mapType, style : { x : style.textX + 3 + j * 7, y : style.textY - 10, r : 3, color : legend.getColor( series[data.seriesIndex[j]].name ) }, hoverable : false }); } } queryTarget.push(defaultOption); // level 1 value = data.value; } else { data = '-'; seriesName = ''; queryTarget = []; for (var key in mapSeries) { queryTarget.push(series[key]); } queryTarget.push(defaultOption); value = '-'; } // 值域控件控制 color = (dataRange && !isNaN(value)) ? dataRange.getColor(value) : null; // 常规设置 style.brushType = 'both'; style.color = color || self.getItemStyleColor( self.deepQuery(queryTarget, 'itemStyle.normal.color'), data.seriesIndex, -1, data ) || self.deepQuery( queryTarget, 'itemStyle.normal.areaStyle.color' ); style.strokeColor = self.deepQuery(queryTarget, 'itemStyle.normal.borderColor'); style.lineWidth = self.deepQuery(queryTarget, 'itemStyle.normal.borderWidth'); style.lineJoin = 'round'; style.text = _getLabelText(name, value, queryTarget, 'normal'); style._text = name; style.textAlign = 'center'; style.textColor = self.deepQuery( queryTarget, 'itemStyle.normal.label.textStyle.color' ); font = self.deepQuery( queryTarget, 'itemStyle.normal.label.textStyle' ); style.textFont = self.getFont(font); if (!self.deepQuery(queryTarget, 'itemStyle.normal.label.show')) { style.textColor = 'rgba(0,0,0,0)'; // 默认不呈现文字 } // 文字标签避免覆盖单独一个shape textShape = { shape : 'text', zlevel : _zlevelBase + 1, hoverable: _hoverable[mapType], position : style.position, _mapType : mapType, style : { brushType: 'both', x : style.textX, y : style.textY, text : _getLabelText(name, value, queryTarget, 'normal'), _text : name, textAlign : 'center', color : style.textColor, strokeColor : 'rgba(0,0,0,0)', textFont : style.textFont } }; textShape._style = zrUtil.clone(textShape.style); textShape.highlightStyle = zrUtil.clone(textShape.style); // labelInteractive && (textShape.highlightStyle.strokeColor = 'yellow'); style.textColor = 'rgba(0,0,0,0)'; // 把图形的text隐藏 // 高亮 highlightStyle.brushType = 'both'; highlightStyle.color = self.getItemStyleColor( self.deepQuery(queryTarget, 'itemStyle.emphasis.color'), data.seriesIndex, -1, data ) || self.deepQuery( queryTarget, 'itemStyle.emphasis.areaStyle.color' ) || style.color; highlightStyle.strokeColor = self.deepQuery( queryTarget, 'itemStyle.emphasis.borderColor' ) || style.strokeColor; highlightStyle.lineWidth = self.deepQuery( queryTarget, 'itemStyle.emphasis.borderWidth' ) || style.lineWidth; highlightStyle._text = name; if (self.deepQuery(queryTarget, 'itemStyle.emphasis.label.show')) { highlightStyle.text = _getLabelText( name, value, queryTarget, 'emphasis' ); highlightStyle.textAlign = 'center'; highlightStyle.textColor = self.deepQuery( queryTarget, 'itemStyle.emphasis.label.textStyle.color' ) || style.textColor; font = self.deepQuery( queryTarget, 'itemStyle.emphasis.label.textStyle' ) || font; highlightStyle.textFont = self.getFont(font); highlightStyle.textPosition = 'specific'; textShape.highlightStyle.color = highlightStyle.textColor; textShape.highlightStyle.textFont = highlightStyle.textFont; } else { highlightStyle.textColor = 'rgba(0,0,0,0)'; // 把图形的text隐藏 } shape = { shape : 'path', zlevel : _zlevelBase, hoverable: _hoverable[mapType], position : style.position, style : style, highlightStyle : highlightStyle, _style: zrUtil.clone(style), _mapType: mapType }; if (_selectedMode[mapType] && _selected[name] || (data.selected && _selected[name] !== false) ) { textShape.style = zrUtil.clone( textShape.highlightStyle ); shape.style = zrUtil.clone(shape.highlightStyle); } if (_selectedMode[mapType]) { _selected[name] = typeof _selected[name] != 'undefined' ? _selected[name] : data.selected; _mapTypeMap[name] = mapType; if (typeof data.selectable == 'undefined' || data.selectable) { textShape.clickable = true; textShape.onclick = self.shapeHandler.onclick; shape.clickable = true; shape.onclick = self.shapeHandler.onclick; } } if (typeof data.hoverable != 'undefined') { // 数据级优先 textShape.hoverable = shape.hoverable = data.hoverable; if (data.hoverable) { textShape.onmouseover = self.shapeHandler.onmouseover; } } else if (_hoverable[mapType]){ // 系列级,补充一个关联响应 textShape.onmouseover = self.shapeHandler.onmouseover; } // console.log(name,shape); ecData.pack( textShape, { name: seriesName, tooltip: self.deepQuery(queryTarget, 'tooltip') }, 0, data, 0, name ); self.shapeList.push(textShape); ecData.pack( shape, { name: seriesName, tooltip: self.deepQuery(queryTarget, 'tooltip') }, 0, data, 0, name ); self.shapeList.push(shape); } //console.log(_selected); } // 添加标注 function _buildMark(mapType, mapSeries) { var position = [ _mapDataMap[mapType].transform.left, _mapDataMap[mapType].transform.top ]; for (var sIdx in mapSeries) { self.buildMark( series[sIdx], sIdx, component, { mapType : mapType }, { position : position, _mapType : mapType } ); } } // 位置转换 function getMarkCoord(serie, seriesIndex, mpData, markCoordParams) { return _geoCoord[mpData.name] ? geo2pos( markCoordParams.mapType, _geoCoord[mpData.name] ) : [0, 0]; } function _nameChange(mapType, name) { return _nameMap[mapType][name] || name; } /** * 根据lable.format计算label text */ function _getLabelText(name, value, queryTarget, status) { var formatter = self.deepQuery( queryTarget, 'itemStyle.' + status + '.label.formatter' ); if (formatter) { if (typeof formatter == 'function') { return formatter( name, value ); } else if (typeof formatter == 'string') { formatter = formatter.replace('{a}','{a0}') .replace('{b}','{b0}'); formatter = formatter.replace('{a0}', name) .replace('{b0}', value); return formatter; } } else { return name; } } function _findMapTypeByPos(mx, my) { var transform; var left; var top; var width; var height; for (var mapType in _mapDataMap) { transform = _mapDataMap[mapType].transform; if (!transform || !_roamMap[mapType]) { continue; } left = transform.left; top = transform.top; width = transform.width; height = transform.height; if (mx >= left && mx <= (left + width) && my >= top && my <= (top + height) ) { return mapType; } } return; } /** * 滚轮缩放 */ function _onmousewheel(param) { var event = param.event; var mx = zrEvent.getX(event); var my = zrEvent.getY(event); var delta = zrEvent.getDelta(event); //delta = delta > 0 ? (-1) : 1; var mapType = _findMapTypeByPos(mx, my); if (mapType) { var transform = _mapDataMap[mapType].transform; var left = transform.left; var top = transform.top; var width = transform.width; var height = transform.height; // 位置转经纬度 geoAndPos = pos2geo(mapType, [mx - left, my - top]); if (delta > 0) { delta = 1.2; // 放大 transform.scale.x *= delta; transform.scale.y *= delta; transform.width = width * delta; transform.height = height * delta; } else { // 缩小 delta = 1.2; transform.scale.x /= delta; transform.scale.y /= delta; transform.width = width / delta; transform.height = height / delta; } _mapDataMap[mapType].hasRoam = true; _mapDataMap[mapType].transform = transform; // 经纬度转位置 geoAndPos = geo2pos(mapType, geoAndPos); // 保持视觉中心 transform.left -= geoAndPos[0] - (mx - left); transform.top -= geoAndPos[1] - (my - top); _mapDataMap[mapType].transform = transform; // 让refresh飞一会 clearTimeout(_refreshDelayTicket); _refreshDelayTicket = setTimeout(refresh, 100); messageCenter.dispatch( ecConfig.EVENT.MAP_ROAM, param.event, {type : 'scale'} ); zrEvent.stop(event); } } function _onmousedown(param) { var target = param.target; if (target && target.draggable) { return; } var event = param.event; var mx = zrEvent.getX(event); var my = zrEvent.getY(event); var mapType = _findMapTypeByPos(mx, my); if (mapType) { _mousedown = true; _mx = mx; _my = my; _curMapType = mapType; setTimeout(function(){ zr.on(zrConfig.EVENT.MOUSEMOVE, _onmousemove); zr.on(zrConfig.EVENT.MOUSEUP, _onmouseup); },50); } } function _onmousemove(param) { if (!_mousedown || !self) { return; } var event = param.event; var mx = zrEvent.getX(event); var my = zrEvent.getY(event); var transform = _mapDataMap[_curMapType].transform; transform.hasRoam = true; transform.left -= _mx - mx; transform.top -= _my - my; _mx = mx; _my = my; _mapDataMap[_curMapType].transform = transform; var position = [transform.left, transform.top]; var mod = {position : [transform.left, transform.top]}; for (var i = 0, l = self.shapeList.length; i < l; i++) { if(self.shapeList[i]._mapType == _curMapType) { self.shapeList[i].position = position; zr.modShape(self.shapeList[i].id, mod, true); } } messageCenter.dispatch( ecConfig.EVENT.MAP_ROAM, param.event, {type : 'move'} ); self.clearAnimationShape(); zr.refresh(); _justMove = true; zrEvent.stop(event); } function _onmouseup(param) { var event = param.event; _mx = zrEvent.getX(event); _my = zrEvent.getY(event); _mousedown = false; setTimeout(function(){ _justMove && self.animationEffect(); _justMove = false; zr.un(zrConfig.EVENT.MOUSEMOVE, _onmousemove); zr.un(zrConfig.EVENT.MOUSEUP, _onmouseup); },100); } /** * 点击响应 */ function onclick(param) { if (!self.isClick || !param.target || _justMove) { // 没有在当前实例上发生点击直接返回 return; } var target = param.target; var name = target.style._text; var len = self.shapeList.length; var mapType = target._mapType || ''; if (_selectedMode[mapType] == 'single') { for (var p in _selected) { // 同一地图类型 if (_selected[p] && _mapTypeMap[p] == mapType) { // 复位那些生效shape(包括文字) for (var i = 0; i < len; i++) { if (self.shapeList[i].style._text == p) { self.shapeList[i].style = self.shapeList[i]._style; zr.modShape( self.shapeList[i].id, self.shapeList[i] ); } } p != name && (_selected[p] = false); } } } _selected[name] = !_selected[name]; // 更新当前点击shape(包括文字) for (var i = 0; i < len; i++) { if (self.shapeList[i].style._text == name) { if (_selected[name]) { self.shapeList[i].style = zrUtil.clone( self.shapeList[i].highlightStyle ); } else { self.shapeList[i].style = self.shapeList[i]._style; } zr.modShape( self.shapeList[i].id, {style : self.shapeList[i].style} ); } } messageCenter.dispatch( ecConfig.EVENT.MAP_SELECTED, param.event, {selected : _selected} ); zr.refresh(); } /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newSeries * @param {Object} newComponent */ function init(newOption, newComponent) { component = newComponent; _selected = {}; _mapTypeMap = {}; _mapDataMap = {}; _nameMap = {}; _roamMap = {}; _specialArea = {}; _markAnimation = false; refresh(newOption); if (_needRoam) { zr.on(zrConfig.EVENT.MOUSEWHEEL, _onmousewheel); zr.on(zrConfig.EVENT.MOUSEDOWN, _onmousedown); } } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; series = option.series; } self.clear(); _buildShape(); zr.refreshHover(); } /** * 值域响应 * @param {Object} param * @param {Object} status */ function ondataRange(param, status) { if (component.dataRange) { refresh(); status.needRefresh = true; } return; } /** * 平面坐标转经纬度 */ function pos2geo(mapType, p) { if (!_mapDataMap[mapType].transform) { return null; } return require('../util/projection/normal').pos2geo( _mapDataMap[mapType].transform, p ); } /** * 公开接口 : 平面坐标转经纬度 */ function getGeoByPos(mapType, p) { if (!_mapDataMap[mapType].transform) { return null; } var position = [ _mapDataMap[mapType].transform.left, _mapDataMap[mapType].transform.top ]; if (p instanceof Array) { p[0] -= position[0]; p[1] -= position[1]; } else { p.x -= position[0]; p.y -= position[1]; } return pos2geo(mapType, p); } /** * 经纬度转平面坐标 * @param {Object} p */ function geo2pos(mapType, p) { if (!_mapDataMap[mapType].transform) { return null; } return require('../util/projection/normal').geo2pos( _mapDataMap[mapType].transform, p ); } /** * 公开接口 : 经纬度转平面坐标 */ function getPosByGeo(mapType, p) { if (!_mapDataMap[mapType].transform) { return null; } var pos = geo2pos(mapType, p); pos[0] += _mapDataMap[mapType].transform.left; pos[1] += _mapDataMap[mapType].transform.top; return pos; } /** * 公开接口 : 地图参考坐标 */ function getMapPosition(mapType) { if (!_mapDataMap[mapType].transform) { return null; } return [ _mapDataMap[mapType].transform.left, _mapDataMap[mapType].transform.top ]; } /* function appendShape(mapType, shapeList) { shapeList = shapeList instanceof Array ? shapeList : [shapeList]; for (var i = 0, l = shapeList.length; i < l; i++) { if (typeof shapeList[i].id == 'undefined') { shapeList[i].id = zr.newShapeId(self.type); } if (typeof shapeList[i].zlevel == 'undefined') { shapeList[i].zlevel = _zlevelBase + 1; } shapeList[i]._mapType = mapType; self.shapeList.push(shapeList[i]); zr.addShape(shapeList[i]); } zr.refresh(); } */ /** * 释放后实例不可用 */ function dispose() { self.clear(); self.shapeList = null; self = null; if (_needRoam) { zr.un(zrConfig.EVENT.MOUSEWHEEL, _onmousewheel); zr.un(zrConfig.EVENT.MOUSEDOWN, _onmousedown); } } /** * 输出关联区域 */ self.shapeHandler.onmouseover = function(param) { var target = param.target; var name = target.style._text; if (_shapeListMap[name]) { zr.addHoverShape(_shapeListMap[name]); } }; // 重载基类方法 self.getMarkCoord = getMarkCoord; self.dispose = dispose; self.init = init; self.refresh = refresh; self.ondataRange = ondataRange; self.onclick = onclick; // 稳定接口 self.pos2geo = pos2geo; self.geo2pos = geo2pos; self.getMapPosition = getMapPosition; self.getPosByGeo = getPosByGeo; self.getGeoByPos = getGeoByPos; //self.appendShape = appendShape; init(option, component); } // 图表注册 require('../chart').define('map', Map); return Map; }); define('echarts/util/mapData/geoJson/an_hui_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"3415","properties":{"name":"六安市","cp":[116.3123,31.8329],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@„„nJ‚UXUVƒ°U„ÑnU@mlLVaVln@@bn@VU@xlb@lšLnKlšƒVI„JšUVxnI@lVL@b„Ž°VX@˜b„x„nVVUnVVnU‚›@kX@VwV@„al¥UUnUWa@ƒ@wĸU„LU¥lKUa@aUI@alLVaUƒ¯anƒWkUKm@XV@VaXlW@aU_UWVUƒI¯@ma¯W¯™™I@UU@WWU@U@@UU@VkV@@WUUm@UaU@„lK@IUK„L@KWmXUWaXI@ƒ@a@a@U@U@KV¥lw„k°b²JVIVKlV@UX„la„Ul`œUVLVVVUšJ„U@Lnm@_VK@KUIW@™J@Xk@WW@U—ƒmm™XmWk@kK@aUUƒVmmkUwUmWL™@WmU@™UJmUULkKWakLWVkIƒlƒwULƒW@X°lUJ@°ULƒWV—wmJ@bmb¯Vkm@@WkWm¯wƒL@lkXƒWmXym¯UImJUbkV™@Vn¯„@V@lUbƒ@mk@maUxmlUbULWn@J—LmKUkWKkwUKƒbm„X„WxkVUKmLkVV@JUUWL@xkJUUƒV@X@VVlUbVX@xk¤šx‚¼œxWxn„‚nn@Þ¼„JVb°aVn„@šmlnXU„JlbVlkz@‚lUŽlXJmxVxXnWxXÈWlUŽ@šUxU@VX@xUL@šUÆmLnV@lWXk@@JlbXblnlJ"],"encodeOffsets":[[118710,33351]]}},{"type":"Feature","id":"3408","properties":{"name":"安庆市","cp":[116.7517,30.5255],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@n°‚znW„XlW@k„K°xXn‚l@Xn@l‚°Una@anI˜xXU„ŽVK@¯VIkW¯X@‚„VK„x„klJXUlKXblLVKnVVIšŽV@Xn‚@šŽXKVnVxlŽnn„UlmV@²óUkV™lW„b„lƒšƒn@VVVIn@lw@WVIXblV„@Èx‚aUaVIVVnKVLšK„ƒln@b²K@»U£ƒÑķƒġÝÅb™K™a@Im@ۍ„@kWÓkkmKÅnóJƒUÅ£›W@w„ĕ@wĉţ¯¯ƒUkK±l¯Uƒ¥UÑkÝUķ»Ý¥¯™JƒIUŽVbUl¯ÈV¼VJU¼Vb@bkLUl@„VJ@bUXǚ@lkVmXmKkLVxš‚Ž„VƒL@VkVVVlzW˜kbmLUUUbVbUV™šlÒnJlUnLllUL@bU„Vx„l‚LXVƦÈVU¦WJ"],"encodeOffsets":[[118834,31759]]}},{"type":"Feature","id":"3411","properties":{"name":"滁州市","cp":[118.1909,32.536],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@š„@`nnl@„xšK@X°KXV˜IXVlbXVWnX‚lL@šÈ»‚LVan@VJ„êVVn@‚X@laÞbVaƒyn@„_‚xnWVXnWl@VnUVkI@l‚nXKVLVV@V@kW@LlVô„@J@bVnnKnkVa@»lç@ƒnwšKma™UUUVњ@n™mWXalI@alVn@VwUaVU„@„nlaôJnU„VVXlJšaXXVK@UšV@VWx@nXVWšXVšUlLUbV‚ULVVnUVbUbVbš@@a„KÆnnKVK@U@UU@@a„@Vƒ°¯ÈJVIlķ@aa˜UaVKU_@mkxUI@aƒUlyU@@™wkKWmUbUnUVWbkJW_J@bƒn@Vm@@KULk@V@@bVbÅm@LW@UVVbkK@UkKWL@VULUKWIUJUbkK@_WVXU›Jka@XƒVa@kšy@aVIUUW@@m„UlLœKWÑUKVan@UkVmmIXKƒaVaUwVU@UmykU¯@±UUL@WUIVUU@KkIWaƒaU@kUUaǃUó»mKƒk¯@y@kWK@bkI¯`mn™l¯XWlkVUzUJlbUbVJl@nnm„@VULV`XnWƗbmUUn™JmUknƒJ¯km@ƒyk@kU›xL@VUbmnn¤lX@`™z@JmaULUVl@Xn@xllkXWa—aW@UVmUbƒ@mVXšWxXbWbUŽƒÒnVVnVVUL"],"encodeOffsets":[[120004,33520]]}},{"type":"Feature","id":"3418","properties":{"name":"宣城市","cp":[118.8062,30.6244],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@Vb@„XL˜JXxlIXxlVlV@I²¤šnlUnVšU@VULWVUJ@Lnb@lV@UnV@@VVVlLnbnJ‚UVkUUVWn@@anUVnVJVIV‚@@nUJVbUb‚„@VUbVK@bn@VbnIlxkllXVlXKWUXUlL°¤UVVb@bš„UlkXW‚ƒxXz@‚„Ila„UlƒnUlJVInVÆJ„U„LVUnV„K°@VnlVnxV@XLlK@wVL@KnUlJXU˜bnKVLX„lUw@VWlLXKm@@a„@VLnmlIVVnKn@škVašVlwk@@a@k@ƒVIUa™@maUa@wna@kmWƒ™UUmVUIVǗ@aƒKm™aƒ™kU™J@InmUUaVa„k‚lX@Vk@m@VU@wnK@alKVUkUkKƒbmUkmƒ@U£WVk@@UÝbbƒaÇx@b@WVUa¯ƒ@wVwUUV@VwnK@KWaŁ@KšIUyUI@WmXó™UbWaKm™@km@IUyƒIUaWKƒx@zUKUL@llVUnkLVVkJWX@VUKUVƒIkVWakb@VWb@n@JkXUlmL@xkL@`VxšLUÈUJ@Vm@@bmIUlUL@VUVVbknm@mKUw™KVÈ@J@LV±kkJUIƒl"],"encodeOffsets":[[120803,31247]]}},{"type":"Feature","id":"3412","properties":{"name":"阜阳市","cp":[115.7629,32.9919],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@V™nƒš@ša„k°aš±@‚¥@UUI@aUmlwUUx›b@¥XU@mmI@a@Kn@@_W@@W„I@mšUVVXUl@XaV@‚K@I@a„LX@aVI°K@KVL„UUw‚yXkšK@kšKÆbXnlK@k@a„JlU@w@U@»@aXKWƒn_‚JXkVKnƒ@°LlKXƒW@¯Uƒ@aUK@kmJUw™VƒIUJ™„kŽmL™K@kka@wUVm@@am@UkUbkK@nmVƒÒ¯VU„WVVmIƒƒULk@ƒƒma@kkKƒƒ@nUbUamU™`UUVUkKVkkƒW@@bkmƒnƒmUXVKXVƒL@VƒbU„m‚™bVXJ@nmKÅI@KWKUXVJUL@VUKUX@KUKWL@LUJmaXXm@kVVV@L@VUL@VlK@L@V@LUK@VUb@UUU@°@nVxU`‚Lkn@`@XVJ@X™Vm„k@UKmV¯LVVn±Wm@Ub@JlLUl„@VLk„@lmVVn@bnV@V°IV™šaVJXI°K°V@XXVlVVU„nšKVlUš„bWXnV@bV`U„„@@m@@‚ƒ@nxmn@bXVlL@¤nb„Ul¦šVVUnJVU„Vl@@bÞL"],"encodeOffsets":[[118418,34392]]}},{"type":"Feature","id":"3413","properties":{"name":"宿州市","cp":[117.5208,33.6841],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@@UWU@bkW@aWU@aUIkWV™lLXb„lVIUVV@‚mn@V_n@VaUK@I‚@UašanJVU„@lV„UVnnKVVlaUa„I@wnK‚Lnll@nVlk@wVKXkl@@b„bUJ@V‚U@U„UUyVk@aVUXwlWXX‚WU¹@aU™@WUI@mlUšn„J@Il@šaXbV@VKl@XxVL@W„IšJlb„@„al@„IUUm@@aVK@¥¯—@mUķ¯bWƒk£Vm@akm@VaÅ@UVWaƒ@UJWkƒJ—UƒbWbU@UlƒXk@ƒamV@K¯nk@ƒlU@Uxmz@bU`ÇbUbÅVm£U@Ww™x@akLUK@UlakwUJWVkLmaUal@n_ƒmVUnKVUUmÅXWa™@kJmx@XUJ@bVLXxl@VVUVV„UbkLWbU@@lUVV„VVX„›K@XkJ@nU@@bV@VxUVlb„U@xXLWŽn@UxVbVĊ„V@b@XV`mnkJ@kUKmbƒaU@VbnbÆx@XU@@`k@@bl„™@@bkL@WƒakXWaU@Vmkx@XWW@@wUUUbƒJ™U¯V™@¯ÞU@WxXŽlL@bkb@ŽlVlnb™JW@kkU@mbkaWJ—IVlmz¯`UnU@mb™@@„ƒ`@bkVlœnV@b@šV@„aVxn@Vx‚KXnl@nbVK„bVK@a„_V@Vƒ„w@W„LlwnK@UmIU@VWš@šUÈ@lKnal„wš@@V°@šaUmlUUw@„ƒV@@UXK"],"encodeOffsets":[[119836,35061]]}},{"type":"Feature","id":"3410","properties":{"name":"黄山市","cp":[118.0481,29.9542],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@lXnlWX@VUJVnUJVzXJVx„kVJlI²l‚U@K@IUǚLVxnLn@lmUaVU@UVKVknJ@an@@UVIVǙKUw@_lK@wnKVklW@I@mXa@UlaXblU„JVUVL@UXWlIUUlKVmkU@kVKVL@y„wXLVb„JVz@Jlnš@nŽ‚LXbVaôšnW@la@UVWUa@@a@mk@WIk@VwUa¯¥m@UUVK@ImK@aX£ƒkK›ÅV™a™™ƒ_@±ƒakXWW—LƒƒƒnU@@a@¯mK@L™JUWwUV™VmbXX@lWLn`mzUJUb™Lƒ„k@makVWmkX™ambkKknƒaƒ@ƒaƒb@‚U@Unm@—ƒWVƒ@VbUbUJWIk@@lmL@°UVUVm„nš™@@kmWkb@xƒ_m@@aU@b@JlŽUz™lWxXn„@‚b²@l`„IVl„UlL@VšK„nVbUl@VlIn@@b„bVWUk‚@@bX@Valb@bnb°Vn@„xVKlbVnV@V‚x„L@ln@UXVV‚L˜"],"encodeOffsets":[[120747,31095]]}},{"type":"Feature","id":"3414","properties":{"name":"巢湖市","cp":[117.7734,31.4978],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@VV@blL@ŽXlWnnšnŽ˜„@VXXl@@WšIX@VJ@LšxŎxlnšŽ@bXJVblX@VVbUVn@VbUVlb@LnJVbVLV‚XLšÒVL„ÒšV„bVIVylUXk°Wšknm°_lJ@aXL@l‚z°@„lnLô¼V‚È„VUUaVKU@WW@@UUa@knmVLlaV@„a@kšak±@UmwkKmk™lj™ÝUUkL@mlIVmnÝWkkUÝ@KƑĉ™a@»ƒmma@mX™¤¯Uƒw@ƒ@UU@bU±±L@akmƒ„™LUKmLUUUJVbbÇwƒ@kUWaUJ@Xkxm@UJUUm@™„k„ƒ‚ƒakXUšVl±ôU@kn"],"encodeOffsets":[[119847,32007]]}},{"type":"Feature","id":"3416","properties":{"name":"亳州市","cp":[116.1914,33.4698],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@lU@Un@@anUlw@KVmUwlaX_lKna@KU@@kWKUU@ankW™XK˜@@V²VVIÈU@al@VaÈamK@wU™@klaUƒV@XƒVUU»WUUbkmUkVmk@aÈw@mWU@VkIkVWKUÑķXȭºU¯lƒ@kkLWmÅa™L@l™LWlzVxƒVUK@L¯LUJ@bWƒK@b@JLU@Wbk@WVUU™V@nƒJ@XX@@`m@@L@bnJ@nWV@¦œa‚wVVkxVn@bVJ@V¦@Ž™²¯bƒl™b™@m„UšUŽƒŽ@¼ƒ¦Xb‚UV`@nnxUxWLkUkVWKkV@XV@@VVL@VX„@lVV@L@blL@`šL@xXKVL‚@„VnUš@lwnU@ml@XnV@@UVW°LnalƒUI@aUK@a‚a@U„kXW@I@mWL@UXK@UVW@U‚@@k„Wn‚@@V„@XblaVxšL@bVKXb„IlJ"],"encodeOffsets":[[119183,34594]]}},{"type":"Feature","id":"3417","properties":{"name":"池州市","cp":[117.3889,30.2014],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@„V°°ĊŤ@xƒĖ@xœXƤ„VôIÆmnLllXÔ@lƒÜŽn@@JšbšLÆaĢÞĸ„°VVUUKVanK@UV@VL„VVn„ln@‚xnklxXamk@WV@Xa˜@naVk„Klk™@mkUWwkJWw—IWK@ƒUaUwWIUyVIUmVI@UXWmkkW‚—KUUVWm@@kƒKw@U‚UUmkaULƒwm@¯Uma@akaUbW@@a@VlUXƒa@am@kJ@UVkUaƒm™L@UkKƒVUkƒJk_±@aƒ@WmXwÇkkaVaUa±ƒœwV@VkƒwnyUaW@UU¯amLk@m™@kmmU™™¯K@L@lUX¯ƒWlkXƒŽVb„bƒVUL@J@LVKnlJXnlb@`nXlalV@bnL@Vnb˜¼@lXbWlkL™K@zUJmIUxUVUVmX","@@llUL@VlxšL@a@UƒwXa¯@"],"encodeOffsets":[[119543,30781],[120061,31152]]}},{"type":"Feature","id":"3401","properties":{"name":"合肥市","cp":[117.29,32.0581],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@„L„xV‚ĊLÞkšVlVVXaWaXwW™nU„@‚anVVUX@˜bXblWkk@wWmk@VUVKnb@Išy@_kWm£nmVa@U‚KœwlVl@„zn@°l„IlmnVšIVmnV˜aXÅWmU_VK@Unƒmmk@UIVakaƒa™UƒÑUK™ÑWKUUKUamI@KkaVUUam@VUUa@UkWUaWI@a™kmōw™wUL@`mn@KƒV™IUVUUUK›Vk_ƒVkbWƒ@VkUULUJ±I¯aƒlkxU¦@L@V@V@b@b@„WJXbWVXn@LƒKVL@JkLƒŽV@Vbn@VV@XU@UlV@@VV@V@XXV@@VšJ°š°Xnb°@„JUVVXV`@bkXWŽUbU@WŽn@VLXlm„°bV„UbkK@bVJ@bVbkLV¦ƒKķV@x@„XbmVVVk¦"],"encodeOffsets":[[119678,33323]]}},{"type":"Feature","id":"3403","properties":{"name":"蚌埠市","cp":[117.4109,33.1073],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@VÒXLlUlJ@UXV@nÇx@bnlUVllnVaXVV¼UVW„U@V„²wVV@Vl@„VnwlIš@XbÆWVnUVmLUV„nm`k@VbnblKXUVIlxkb@VVLlK@bšwXxV@n¤ÆUVaÈaV_@anyVwV@„kl@°m@LnU„bl@„WVkV@Xa„a˜V„IXl‚IV‚„@XbVUÆ@XKWwUkmW@_UmnIlJXkWKXmV@‚w@_XV@Kl@kU@KlX@@UUUUKWLm@klJVUUmk@mXUWmXwƒ`m@„zUbÝakbW@m@UUƒéUIm@UbKǼ@™kKWXmWUkaWU—JWU¯L@W™Lƒwk@mm@_™ƒÅl™UVkmWUnV@VWLUb™bƑĬ¯l"],"encodeOffsets":[[119543,33722]]}},{"type":"Feature","id":"3402","properties":{"name":"芜湖市","cp":[118.3557,31.0858],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@„bVaV@XllLXU°ŽlL@V@VUnVl¯Ikš›VUVU@@b@lUXUWmb„n@¼šbƒĊ‚LÞ@lVXlmÞUnkJ@nlKVVšÞXklWVaVI@aUKn»lL@Kn@‚XXwlm@mn°@„V@Wy„wXlWVk™ƒ@aUaVU¯£kKWVXVWLUkkWlkkwmJUam@@aULVa@UƒVaUaVI@m‚@UUJUIUmmV@bm@UXVVUlVmImakKUU@UU@VmU@@kma@KVIXUVK@U™VmUkV™m±£@JkU@nlšk‚ƒLUlmb—@WbU@@XnlWb"],"encodeOffsets":[[120814,31585]]}},{"type":"Feature","id":"3406","properties":{"name":"淮北市","cp":[116.6968,33.6896],"childNum":3},"geometry":{"type":"MultiPolygon","coordinates":[["@@lnnK@¦n@@V‚V„@@VV@nIV„V@VW²a@b@bVnUVVV@V™z@lš@°UšV„IVaVV@x@ŽXX@WlwUnV@XblW„b@XlK@aš@kƒ@al@@_V@@WÅwmaUaV@„bnaVL@llInmU_@W@aƒUUĉUaVwm@XWK@wƒVkaVUUwU@@aV@@mlI@WœLWƒUUUƒVU@kV@XalKVaUƒVUUUk@WwUK@aVI@WƒUk@@UUU±xkb@lVš@xnLÇbUbk@@bÇVUJ±U@U—@WLXšml@bVVXL@lV@@LmbkLW`kbVxUn@LkxmV@bm@@VkV"],["@@VVVkV@¥@UV@U@VUUJƒkWakKUšlXVJ@bXV@blX@aXV@V"]],"encodeOffsets":[[[119183,34594]],[[119836,35061]]]}},{"type":"Feature","id":"3404","properties":{"name":"淮南市","cp":[116.7847,32.7722],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@°kƒīšaVaXK@U‚UVmnXUlšVÆkVKUUUmmU„ÑkU™UÝlĉKUƒwƒKƒbU@UxW@@lœmVUUVmUUƒmƒw—aW„kL¯K@Žm„ULWlIm`X„WL@b@¼@V@xkVƒI@b@l@lk„V°Ȯ¹ĸW"],"encodeOffsets":[[119543,33722]]}},{"type":"Feature","id":"3405","properties":{"name":"马鞍山市","cp":[118.6304,31.5363],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@šNJnllLnxV@laXLVKma„aXbVI„bVKVVVIVyn@n_ƒƒW@@ƒ„UnJlUVVXlLnaUWlV@VV„IXW@_W@XK@K@UVUUwVamÑXmmwƒw™KUnUK™çU@ƒJƒU¯@mŽ@nknWxWm@@LkKm¼VL@bUJUbkXWl"],"encodeOffsets":[[121219,32288]]}},{"type":"Feature","id":"3407","properties":{"name":"铜陵市","cp":[117.9382,30.9375],"childNum":3},"geometry":{"type":"MultiPolygon","coordinates":[["@@„ÒV¤@¼V²@aVV@Ž@„„x°Vš£nW‚@nbnaVXVW@k@aV@VUœUl™°JUkVm@U@UkK¯WVkKWkU@Ubƒakwmlwm@ƒkUmƒUUKU@@VmLUbVLUV¯U"],["@@LllUL@VlxšL@a@UƒwXamK"]],"encodeOffsets":[[[120522,31529]],[[120094,31146]]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/ao_men_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"8200","properties":{"name":"澳门","cp":[113.5715,22.1583],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@HQFMDIDGBI@E@EEKEGCEIGGEKEMGSEU@CBEDAJAP@F@LBT@JCHMPOdADCFADAB@LFLDFFP@DAB@@AF@D@B@@FBD@FADHBBHAD@FAJ@JEDCJI`gFIJW"],"encodeOffsets":[[116325,22699]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/bei_jing_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"110228","properties":{"name":"密云县","cp":[117.0923,40.5121],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@vIHZDZQtDLNMXIbHRCXXITbJ@H`LGPRDDJNCLHTOCWFGvGBUJMKGFO^IHWXITQCI’Y^AXGfRˆDXF`DJOLB~G\\DZIHHpErUVMhHb]\\M†BVF@FTP`@zTbD\\@~M\\K`H^EVODWICAakAQXoIcCOCIgGYNWFWNGGKKGaJEGMEIKYJUT_J_Go@_SyQaSFMEGTcYOQLIIi@EKAUPCV[EEXQCW|aMUMAaYCYNIDGGACIMGGSKDQGaF_C[GaB@GOIiOKAYL“mI@CN]F[SWWAcKKI@HMUimEKbeYQYISNUOcBKPIFBNgvDPGZYFSf]CMSIWGEUFgDIQ[MeDMJS@RR@LphFPCHaBAJKF@J]IBJO@HlO@@RKAMPJHCNDJTHFP@ZGNANBRFH@J_fM^ONJNF\\VTDJHDON@XRND\\XRCPVETCLBVKDFJINHRGPRV@\\CLJN@VbXbLVT"],"encodeOffsets":[[119561,41684]]}},{"type":"Feature","id":"110116","properties":{"name":"怀柔区","cp":[116.6377,40.6219],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@JHTVHXCHPfnDJGHNDJSB[JSBGVSAOH@PMPuDEHHXZN@PHF@ZLJ@LHVYJA\\OFWP]BMtMBSRGV[JeVAPQVIFENMD¡–@^NV\\JH@NNL@NM\\kTQ\\I^FNIpBHGTBFFAZQfKDIXQTLXFXNNVMVHRGpCFLlRLEVBBH`IVO\\G`RDPAXLXBXORHZEHTDLLN@VGTMrQNFPeASKG@GMOAKBYMK@GTUHUXSHMVDNMOUEOZMJML@^KRACMZEZMRQLUHE@OFENPR@DI\\ChMHIDG\\GJMDWHCKGMDCIQCHO_K@GaIJSWWQDaGWJMNCKRsCYGYuJUSaKaW@UIMDK@[QUHOGQJMEILCAUDKFSOUQD[WMC‚Q@WPMGCCIUSE[IMPMN]`e@IEGAQBMHM@YEOSGCIDMIGNOLB@QP@GkP@AI^J@ILEBIbADGEOog@KQQWSekWQQUOFKZLF@PUNmIaHIUeBCTSHENcJa@_IWSaGu`GLSBKJQFOXGDXVQVOBIHcDSJWBEFGTMH[^mLaXcHiKElTRKtFXZ`MHMPCNRDxZˆB\\ICIHK@KŽHbIVFZ@BPnGTGbDXRDJaZKRiGEFSFEJhjFNZFjn"],"encodeOffsets":[[119314,41552]]}},{"type":"Feature","id":"110111","properties":{"name":"房山区","cp":[115.8453,39.7163],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@h@bl@HRJDZ``TA\\VVD^H`\\pF\\JŒ`JGv@ZO\\GPSTEjPTR`FnEbDTDHEhLFMTK@ETSPULKEI@OVISKSJACEQNQbV˜IXGDIN@dMB[IIBcN]ZHNLP@XOWCFWŠCNRHTpATD@^NVNLED@Rh@jCEF}E[OOHUEW]W@QGGDIQSH_MmFmCUT_K]i@MHCMW—FCF‹E{BMHMPOHKS]CFNGBELDH_@BcAKOACESAOBELaXAROB@FODMEDWJAG[aE@UM@DImEWJMC@OeCA{aE[@{L@MINUCQXKfUJORCHqJBF@TCXWNQX]M[EAJO@@KMBQJIC]EWMCCUBEBFHKDOTMBGNGF]MWDBRDdMDQVyE@LPVHDCP@JVVMTG~HNSH[CmRUvHPHBbA\\PTNRC\\YNJ€PRARPJDDR"],"encodeOffsets":[[118343,40770]]}},{"type":"Feature","id":"110229","properties":{"name":"延庆县","cp":[116.1543,40.5286],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@^AXOPEB[ZIGU@KKI@YGE@OYMGWFGvCNO@OPGTBHUTA\\ITACIGMIHmCOeDGGWSUIGimYEEMgiFITEFEjHLQbYCIWQaCSHmHAOY@UEaJG@LGLDJ[J‡AwYQCDMNONGY_EWLsSQFkMO[NWAIGaIYL@HMBOKiOQDWEUDMQSF_QIUBWdg@[NaAKQ@M]OQ@WhgLUMMFYQDIRCEUZOOCIOJ[KIUMKL@HIDKVEBM`HJAJSJUdBLGNEdMBMO[BYEWJSNKNaD]PE\\SjOT_RQVEZPpƒNQXfŠNA~lNG`@PNLp¼RFLfbdKbATUh@FSNWjGFZVLFHVA~X¨PPROfFJbNJPLFbENJPrEFNPFRHDDJdENJLVEPBJTVTHGHFRFH@PXP\\ORQHW\\BjWFDERLPPBbB\\E`B\\D\\L`@F]FCnJ^AZL"],"encodeOffsets":[[119262,41751]]}},{"type":"Feature","id":"110109","properties":{"name":"门头沟区","cp":[115.8,39.9957],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@V@XMnGPY²‰JQNEhH\\AZMPDVTTDZCPiJkHSHCjIdFtEHITCNITQEKUAMCEIKCECABYESKFWAKBEIIHABGDCKCAIHMHALKEI\\CFIBILIJQZS]BBEECS@E@@C]COKI@CABAAEEDMGƒCH]A[M@CJWH—JaUMRFRBDTITLUJ@PFJKLOVST@FSLENgKGFSCaCmF_ESQiOSFOT[HYPu@IH‹_[IoE_[]GUC[USB__CYQI@Gakg@qZeHQNMNV\\FVLPgJAFJPRLCH[XcPELUT[JiV_EELFTADBXRTRLJC@fHXHHbPd`fR@NfT`@TLplHMpCEJHJBVLFŽ@JT‚VnG^KXDXHNVGRLRXFJVdDHSNWLGfEzA"],"encodeOffsets":[[118635,41113]]}},{"type":"Feature","id":"110114","properties":{"name":"昌平区","cp":[116.1777,40.2134],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VNLJI\\JPPDYPFVQDCJZRNEVNhKXgR@^P@NLRbB\\Mh@XcVARJE`RTCNFV€XRCjPPLNA@GZKbJJHXB\\MNPjLdGbWnK\\]NGHSFEXATIdCJGPARUWUHCPWRELITAHKv_E@iYCaW_BQ\\Y@QIO@QDCIGZCEMWGFMFAFgHEDOCSqKCCFGAMKEAC@ODGCGs@WH@KQA@EE@CE@GEA@EH@GGUEEJEAYD@JM@@DAA@FHD@FTJEHUC@JUBKCKG@G[CIIQReAYhO@OXGDO@@FF@IHJFCPEBACBIAAKDOABXARHPNEHGbQAAKQFGIAM[C@WHKaGiCEGOA‹HUKCIokSCUSOCYN[BgGMFIR±ŠOZmHWNU@ShbbXDHVXXGJ^lZ@PZ\\Nb@\\FHJAD"],"encodeOffsets":[[118750,41232]]}},{"type":"Feature","id":"110115","properties":{"name":"大兴区","cp":[116.4716,39.6352],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@F\\E~DFN@BDFEpHFCHBBEGCDCJBHUDSBB@ELCPbF@B\\J@BJVAFJ\\ADKTCBGECFMT@BMN@@FH@DaNBEnvB@FPBATK@FHEFIAKFBFL@@PKBFJHC@FXBRAFCDMPDTOL@JIVFDHH@DDH@BGRFCDLD@N^@@CNA@KNOAEBCECFEGCFGMGFIPMOEJOLBADBBHGG@GCHIECY@INC@DMGS\\AIOZAAEYA@GT@KKMBEETCGMVINFxA@MJADB@FlA@HJA@NND@DFA@DVAZBBOFKH_JA@K^GBC@EFE„G@gAENMXKJigC@IbSJMqGOP£RGSMGE@kbQFDPEFiBSGGSBK]I{CDWCIDOic[C_G@SuSO@EWKCO@MNY@\\uZOPENQD[LKESSKGBKEG@EJGAGHoH¥CqhifeJkX_XFFGHFNEDFPENKHM^IFIVL^S`DVEnNnG`RTCJHH@R^XFXGVPP"],"encodeOffsets":[[119042,40704]]}},{"type":"Feature","id":"110113","properties":{"name":"顺义区","cp":[116.7242,40.1619],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@EhEBENXHFNYDJHCD@RJP@R[ZARX`DbjZF@bHXT`Jb@dIFMTGDSfAJVbGnJVM@OKELYPERVXRflXTT@NIfC\\NJRhCVEHFJXNT^DTeZEHYCOhuAMJELOdAVPTMOWBWNMNEJgl]@WGUFIC[T{EEDEHGCIGMI@SECUQI[D{A{GQESPUH]CsiMCmHUeoHENcAaDGCMDGMQCACCBaCGLMAHB@DIEQLOAAEEJ@CW@CDINGAAGKQOCgV@LG@BEGDKNeREFBNCFIDOPKD[@YRW@GFWDAFE@EHDDrLDTCPGF","@@KrJEH[\\B@FF@CHFBHUN‹AJKADGECBCMAG^E@EbI@BEGP"],"encodeOffsets":[[119283,41084],[119377,41046]]}},{"type":"Feature","id":"110117","properties":{"name":"平谷区","cp":[117.1706,40.2052],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ZJZRafFLjn€VGNJ@LLBdXX\\T^EDMJ@”nZKLBjPPJ@HbA\\H`DbERHLCFK^BZaFWXQLAGMHa\\OLO@SBIpBdCLƒVQfElO@GSAKEDQTC@GEBKG@ORIJBDAPDFA@CaOq@GGQAAEJK@KMUGAAGEAa@MGMBGCGSIIW@WSUCMDOJeWOM@IUF{WMWaDIMgIoRoCOKeEOEAG_I[cg@wLIFENQFDVTFJ@HNDJGHCFFFS|D\\EJHV@Xk^IhMFMNAXPX"],"encodeOffsets":[[119748,41190]]}},{"type":"Feature","id":"110112","properties":{"name":"通州区","cp":[116.7297,39.8131],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@FDAJTGDNDCTDDEDBBE@DT@@EHCDGJ@EIZ@@FDBR@ATFBBVFFE@@HNA\\VE@CLIFNJFNJBCP]A@LJFA@HJEDD\\C@DBCHLAEPF@@DH@APHAERDF\\GIxDTM@CFLBBFJ@CNUPMHECGDBF]BMFPDLRBHHBJMDCX@@DFIBFPBRKJF@CGANBHKbDDABDRDHNNCHDbCdBFMpGHiOYMefKJMC}HWAUNW\\NNBNA„kNU|]HMTMN@MZBLFFF@RIRUT‘BMFIEGaAGGAOIIUGTSFcYKS@MSLYPKRUBU]EWDOI]CKGASgW@MTWKIMCS@uMAKKADMECGAKVUTSDy@IjWLMNBF@hƒHEF@FAD]H@LIBG`ELAPYAUB@CEB@CMC@MIB@GkB@ECAIB@NwBMEUJHNSDFFNALLS@@HZBBFYBJP[BHTCND@JMZ@FDGJHDH@GHAABCKAIPPFONEJNHEHHDEFFDADBFMP@L"],"encodeOffsets":[[119329,40782]]}},{"type":"Feature","id":"110105","properties":{"name":"朝阳区","cp":[116.4977,39.949],"childNum":2},"geometry":{"type":"MultiPolygon","coordinates":[["@@bFGHBHFBFIVFHHG@@FFB@HDFF@@FRB@LXGt@DHCH@PBDLFBNF@BEXCHEX@ZQ\\@LCPOJCDEAMFEfQLMHCAFH@@KhUNE^AAEHCFDNGVODMI@AEKADEN@CSJw[HCEFQGBBOG@@CE@FOKBDGCAD@C[FCGIB@IE@K^BDOIAEMMIJEDKF@[UMB@GF@EEAUEABSQ@CA@EY@FJI@CHGD@FS@@CAFCACFSCCDCMSHBIECMB@D]@@MKCDCQEAHG@CCG@CGUEIJK@SPOCCNEDQBDNDB@DJCDLFCBBALJB@BVGPBKVO@KHCCCD@FE@BNA@FNCTDDJA@FGB@NBDW@CL@hT@@ZHHQDDDAFSAANBC@HG@EFS@@DE@@PCB@Ue@CADNJB@FCBWA@LI^ix@FIHrH"],["@@HUN‹AJKADGECBCMAG^E@EbI@BEGPKrJEH[\\B@FF@CHFB"]],"encodeOffsets":[[[119169,40992]],[[119398,41063]]]}},{"type":"Feature","id":"110108","properties":{"name":"海淀区","cp":[116.2202,40.0239],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@plDJVLŒGPBFHjDbHGL@X\\DBNHJREBLRBHaFGŽMGOBQAWPBLCBBAJBDFADOIEJGE@@EP@HCPWP@ZgfBRQJJ\\D@HLHLDVA@IVDFGSI@EGC@EBB@CN@@IZCAGHGaEqGJG@EjwJ]@K@GSA@e_I@NE@CA@Kg@KC@ENCFƒAKQAW@WIMK@V‹@I@@F@^EDFB@HcIaDYCBRRDCHD@EFLN@FE@CJUPEJOJMTBPEDIFCMIAKNOGMRFJNDVBFLSRMJSDGJsFcEiJGDGTIlOjYD"],"encodeOffsets":[[118834,41050]]}},{"type":"Feature","id":"110106","properties":{"name":"丰台区","cp":[116.2683,39.8309],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@hMN@NFTQCFRCBJFA@HJ@@HJ@HJ\\FTACDŒ@@UNLXJX@@MA@@IECAQlDFEHBDI~D@GXCFMVDFCH@@NF@ANJC@FnAB@AMF@@EDCDDLGP@LUOAUH@AIABKAAEDCKID@CCACMWA@EGDEILA@OK@AELEJBFEEGL@BSOA@EuAFmMACbG@@EM@ANS@ENFDAHSDCL[BEIUBAII@A[E@OaKD@FAACTGVIACDHDAFGAEDoGEFACM@i€g@@QFCMKMU@]SCoBGSMQ‰DEXXDWPO@MKYGM^AdJJA\\cNB\\G^„DNHFCBFABDBJ@PL^D@DF@T@FDAF^A"],"encodeOffsets":[[118958,40846]]}},{"type":"Feature","id":"110107","properties":{"name":"石景山区","cp":[116.1887,39.9346],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@NQPHLMJBDNJEFCAONSPIFIVODIF@@EKMFEC@DGQCAQZDbCdJ@GEAFC@]@EJ@DCSB[EGII@@GI@@GEBAIQDDESRMEM@gNYTIRKJAJEJ[DFJKLGBGNBJLDCDAHGBJJAFBLEXTLZFBAFDLD"],"encodeOffsets":[[118940,40953]]}},{"type":"Feature","id":"110102","properties":{"name":"西城区","cp":[116.3631,39.9353],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XBDA@EIACM@IJAD]BC@SFABISAD]H@@OAEDQEW@BLE„MD@FLDh@@LDBF@@M`J@fTB@H"],"encodeOffsets":[[119175,40932]]}},{"type":"Feature","id":"110101","properties":{"name":"东城区","cp":[116.418,39.9367],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@DBf@@VDA@OF@@CT@FEH@@GADBMTBBECCRCGG@YS@@gDK@A‘C@PG@C^TBAJEB@TADC^IB@J"],"encodeOffsets":[[119182,40921]]}},{"type":"Feature","id":"110104","properties":{"name":"宣武区","cp":[116.3603,39.8852],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@RBX@RFFCŽBFU@aK@WA}CCJGAEFkCBRFD@JB@@N"],"encodeOffsets":[[119118,40855]]}},{"type":"Feature","id":"110103","properties":{"name":"崇文区","cp":[116.4166,39.8811],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XBL@@bEV’D@BX@AC@MHA@EIBCCDSEMmB@EIDBME@@MG@EDUCENWD@H"],"encodeOffsets":[[119175,40829]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/china_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"xin_jiang","properties":{"name":"新疆","cp":[84.9023,41.748],"childNum":18},"geometry":{"type":"Polygon","coordinates":["@@@›ρȁôƧƦóəʵסʵóƪԫʵѵͩƧͩړ›υࡓɛʵ@ȃ@óᇑѵƨɝɚôóНѺͩɜ̏ԭʵôƧɞñ@υƩ—݇ȂóƩƧ@ѵȂυœƥŌਗ—॥ɛóʵѵƧѹ˜݇̍ࢯ˜əɞυ˜ρͩ̏óਙƨƧŋôōóš̍ͩóʵן›óŋړͪƧѶ@ɜԭ—ԫƦɛȄ̍›ɝȄöςƩȂ̏œñȀ̏œƩóóŎə˜@Ő̎@ɞȀɝŎôƨóנѵȄƧ@óŏɝœóɜôŎ̍ͨςŎ@ƨóôƨɞ݈ʶóƨφó̎Ȁƨ̍ԮòѸԮמ@ѺȀ@ƪၬֆòȂñ̐òȂɜ˜óƨ̒Ŏ̑߼@φρȀ@Ő๐ς̎Ƨφ@ɝφڔ೦Ԯǿࢰ@ƦŏԮƨƨȄƧ۬ɜʶڔŐɚɚóŐôƨ߼˜ôƧƧó̐ƥóŏѺǿƦȁφƧς˜ƨƧ̒@ɜƥƦυ̐ɛƪͩƩəƪʷ̑ə@ȃƨʵנŋྸōਚԭԪ—@ɝƨŋ̒օςʵôƧ"],"encodeOffsets":[[98730,43786]]}},{"type":"Feature","id":"xi_zang","properties":{"name":"西藏","cp":[88.7695,31.6846],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ôŌנœôʶ̎ͪô™óŎƨŌਚƧ̐ôςͪφ—ɚɝࢰ—݈̎Ѻ—Ѷƨôʶ०ɜਘ˜Ʀŋφ›Ѷȁ̍—ôŏɚŋ@̑ə—@ŏò̍ɜ›óƥôʷƧ̍φѹԪ̍ע@Ѹʷɜ@ôñנ@Ѷɛɞô̐ŏѶƨѸƧƥōƦœôŏô—@ƧôƩ̒ŋƨŌƦǿô̎ɜȁ̒—óʶѶôôО̒›ςƥɜНφσɛȁ̎υƨఱƧŏ@ʵƥœ@ŌóóóͩƨƧóŋ̑õóɞóɝԩͪɝρôƧ̍ƧѹͨڑŎ̑ōóƧࢭͩ̏ѵɝóఱóóԪυô@̒ƥŌ̏Ƨ̑Ȅ݇ŎƧ›ѵӏ@ɛõŏɛȄôӒƧŌѵǿɝ˜Ƨŋԫ@̏ʴƥ@óǿ̑Ȁóǿ̍ςóóυô@ʶɛñρƦƩŐó̎óœѵó̑ͪࢯОóɜן˜Ƨ̏ƥȄ߻̎̏̐ןŎɝɜöɞƩȀôöɛȀóͪ̐ƨƪ̍̎ȂƥԪυО@φɞ˜ôƪ"],"encodeOffsets":[[80911,35146]]}},{"type":"Feature","id":"nei_meng_gu","properties":{"name":"内蒙古","cp":[117.5977,44.3408],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@ኊȁ૊ö߼ƩɜɛנñԮɛѶóԮô@ȁѸóמ̎ගѺၬ@߼ʶԮӒ߼̎@ŐѹӒ̒Ԫƨöග̑ѶȄ̒ς।œѶɚöɞɜʴڔôôȂ̎—ѺȀς—ƨ˜ƪóԪ—ɜôɛОਕڔԭ˜ѵ̍ѹȂԫ›ɛƥ̍Ȃóɜ̎ô@ʶ݊ੲࢮʵږͪנƨôȂƧ˜̐ͪ@ŐƦƨφԬѶɜôƦ@ŐƧôôƦəŐ̏›@ŐڒѶԬô̐ʳԩНςōôŏɞ@ƨȂѶəóƧ̒ػ̎ó̐Őנóƨô̒@ƨɚɚ@עԫɛɛ@ȁυͩƥʳòևρ—̑ࡗƧͪ༃ॣԮփ̎Ʀ@ôô@ôō@š@ȁѵóƨ̍υȃóʵɛƨƥóυȂóəƪ›̐ρƧͩɜԭڔȄ̎عƧȁ̐ŏó̍ɛ›ƥƧ̑óρŐ@Ƨ̏˜ɝəɛ˜߻ͩ̍ͩɝО̍ƪƧóóӓƨóƧʳ݇@ɝςƪœ@ʴƩ—ƧƦôƨɛȄə›Ƨŋυ›óͩѵ@ɝǿóŌן̍ɛ˜óО̍œ̑̏ôȁ̍ŏòȁñóƦͩ@ǿə@ɛƧ̑˜ρȁυô̍օѹœóȃə™@ȂσʵѷƪòƩ̍—ôó߻ۯôʳƧ™óšõʵѵóѹɜ̍ȂѹôɛŌφֈƩͨρóυӑóޟఱ̑݇ͪóƪƨŌóȄڔԬƩςםñ̑ȃѵŐԭŏƨȁɛǿρôõɚɛóƧОə@ѹ̐ѵöԪͨôͪɛ̒ןŏƧƥóôƥƧɛŌôóɝó@̒݇Ӓ̒Ō@Ŏԭࢰ"],"encodeOffsets":[[99540,43830]]}},{"type":"Feature","id":"qing_hai","properties":{"name":"青海","cp":[96.2402,35.4199],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@ƨ@ôƪ݈ȁƪ˜@φɝòóƨԮʶɛ̐ѹͪôОəóƧɞᇒѶ@ôږô@ǿѶ›ƪȁςœɜͩφ˜ςŋɞôѶɛƨŌɞ—@ɚςŐñԪॢͩƨȂɞóƨŐ̎ŏעӏ̎óƧƦôœ̒ȁɜ›ςͩ̒œɚɛƨôƨɝφɛóȁƨŋóóɚͩƨóóƩ@ƧəŋƦƩ̍@ƧƧôǿυ̑@ȁɞǿõŏρƥסɚƧóτԫɞœôƧƦ@ñȃòñƥóυôôѹѵ—@ŏ̏Ȅɝó@ȂəŌóəѹƦ@Ő̍Ōυ݈ԩŐƧóôƧ̑›ôʵɞƧ̑ѵôƩɞƧ̑œóНѵóôʵ̑˜ɛȂó̍ƥȀƧŋ̑Ōóƪ@ƨó˜óŐƥ›ƦŎѷƨѵƧ̏Őɝóѵɜן@óòɛ@ѷʸס@ԩ̎υѺƨ̎óʸôƦɛœñ̎@Őɚ˜@̒əŌóŐ̎˜"],"encodeOffsets":[[91890,36945]]}},{"type":"Feature","id":"si_chuan","properties":{"name":"四川","cp":[102.9199,30.1904],"childNum":21},"geometry":{"type":"Polygon","coordinates":["@@ô˜ôŋó̑Ԯ̒ɛОמͪƨōöͫ߼ƥôȃƨóóñôƧóƧôōڔŏƨŐ@Ŏô˜òƥѺŎ@ōɜóנ˜ôǿô›ƦôԮ̍ɜôɚ›Ƨ—ñɛɚȁ̍Ƨɛևυ@óóôŋρԭɝ@Ƨʸ̍ŏυɜƧƧóƧƨȁρ̍ƨȃɚ—ôʵφóô̑̏Ȃ̑ʵɜʵɞ@ƨʳסƩóŎə—óɜƧôƩƧρ˜óôôô@ŎƧƨƨƪѹ˜ó̍̍Ʃ@̏ѹНôޟ̍Ʃóƪυɝɛ—əƨôŎɛȀ@Ȃ@ñɝʶ@Ōρנ̏—õóɛͨƨȂѵОɛʵ@̏ƩŐó߼Ƨల̍φɜȂυτɛОρƦɝƨóƪ̒Ѷɝƨóʶ̒œóƨƨôԪŏφ݇̎ŋ@ŏѺƥôɚɚŋ@ȁɞô̐ȃ@ŐѶ˜óѺφóƦôñòòȄ"],"encodeOffsets":[[104220,34336]]}},{"type":"Feature","id":"hei_long_jiang","properties":{"name":"黑龙江","cp":[128.1445,48.5156],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@ᇔȂਚНƨŐѶŏöƥςŏñƧƦóƨȁ@óƨ—óȁφӑóóƨ˜óǿ̎̑ôНɞ—ó̑ɜə߼›̎ǿ̒ôڒӑφ@Ƨȁ̎̏ƥƩ̎ρశ˜ôȂςƨφ@נɞ݈˜̑ƥƧɛƨʵƧȃƥ@Ƨƥ@ŏ̑ԩôɝρρóɛƧ›ƩͩƧó߻ʸ̍ʷѹƥɞڕõ̍öɝυ—̍ȂƧ̐̑ŏóƨñŋѹóóȁ̍›̏Ԭõʸ̏ŏ@ǿ̍@ƧОυ@ñƨòȀƥŎ̑ŐѵóɛŌóȂԫōƧŎѹñ̍ʶóОן@Ƨ̎Ѷô@Ȃ@™óŎó@@ó̍ƥԭք༄।ƨͩ̒ࡘς˜ñֈƦʴφͪ@ȂɜɜסԬə@Ƨə̑@Ƨóןô̏ŏ̍ô̑ؼôƨѵɚƧȁɝ@óŐρŎԪО̏ʴ"],"encodeOffsets":[[124380,54630]]}},{"type":"Feature","id":"gan_su","properties":{"name":"甘肃","cp":[95.7129,40.166],"childNum":14},"geometry":{"type":"Polygon","coordinates":["@@ڔôԮࢯ@ō̑ŋ݈ӑ@̑ɞôóôɜŋƦƨôóƨƦנŐɜ̑óͩԩͧѶõѺ̏ɚ@ƨНɜôöəςóɜȀƧȂԮŐѶŏ̒ȄמòƪρړԫôȃƧŋôƩ݈ͩɚ@@ǿɜ@φͩóŏɜӑƧōôǿ̎›ôƥƪóõ›ö@ô—ƨ˜ôƧƦôó̒ɜ@ɞŌõʶ̏Ő@ȀóôƨȂ@ʶע@@ƥ୾ӑó̑óŋôʵóɛړ@@ƩöóƩóρ—ɛƨ̑@óʷƥƥ̎ɛƧ›ôōƧǿôͩѵôɝȃɞȁõƧρóó—@ōƧŏړŐóŎôƨóƨôòƧôóȄ߻ƦõͬƧŎםͩɜНԭ̑ô̒óŌó—ƥ@óƨɝ›σԬƨôעəςƦöŐɝȀ@Ȃφ̒óȀƨƨ̎@ƥƪɚŌ@ƨôƪƧôəͪôôƧŌôȂυɜƧɞƧóəɜ̑›ρͪɛœ̑Ȃó›ƨƥ̍ôסӐ̍ŐƧŏɝôƧȁॡͪòԩρŏ@əɝ˜ƧŋѵɜɝóρŌυ—ɛͪρ›ƩȂѵœ@Ȁڕó@ȄɜʶφࡔڔœƨͪѶͪԬʶôƩעʶɚʶƥôóƨςȂ"],"encodeOffsets":[[98730,43740]]}},{"type":"Feature","id":"yun_nan","properties":{"name":"云南","cp":[101.8652,25.1807],"childNum":16},"geometry":{"type":"Polygon","coordinates":["@@ôɞôɝ̒öôŌƧƨôͪôô@ŋƦ›@ʶƨŐô߻ƪŏ@̐ɜʶѶНƧȁɜͧöô̐˜ςן@ŋɞʵ@ò@ȁɜǿóōɚƧɜ˜φɞôƩ̎ƪóޠѺО@̐̎ƪô̎Ѻ—ƧƩƨƧ@ōóóôóς—ƪƨƨóôɛó̑ԭ—ƥŌɛǿɝƨɛͩô›@ǿƨȁѺŌɚɛ̍ןѶНɛƧôóƥȁƦͩôŎɞ—ƨ̑ɜ—òôφ@ƨʵ@ɛѹōóȃəƨυǿóʵρƧƧŌƩɛ̏ȄñƧƧȀɝ̍ԩʶƧ̑υ—óŌƥʳɚӑóНƥô̑›óӒѵʵѹœƧӐןôƪφõŌƪ̒ԫŌƧؼƨƨס›ρȁƧœƨȂóʶó@@ʴƨôôφ̎Ŏ@Ȁƨ—ƪɚƨœóƨôôôςóޤƧŌƩŋƧԪ"],"encodeOffsets":[[100530,28800]]}},{"type":"Feature","id":"guang_xi","properties":{"name":"广西","cp":[108.2813,23.6426],"childNum":14},"geometry":{"type":"Polygon","coordinates":["@@ƦŋѺ̎ڔʵƨŐ@ƦמȄƪôóȂɜŌɚͩɜ@öóɜôôȂƦôɜȁ@ɞφ›óȄ̎›ƨʶɞŋƨʴɚǿ̐̎Ԭ@ôñ@̏ƨ›ρ۫ô›ɚƨƨНƪŐ̎›ƥóƦʵƥŋ@ȃóƥƧ@@ŏɝǿôυƧȁѵɛ@əóŏ̑@@ə̍›óƧó—@ȁƩ˜ρóòНƥô@Ӓ̑@óŎ̍ƥσŎυ@̍ƨ@Ō̑ôóͪƨ̒óŌړœ̏Ŏ@ŌôȄѺŎ@ɜƧʶυ@ñóɛ˜Ƨ̒ɝ˜óōƥͪ"],"encodeOffsets":[[107011,25335]]}},{"type":"Feature","id":"hu_nan","properties":{"name":"湖南","cp":[111.5332,27.3779],"childNum":14},"geometry":{"type":"Polygon","coordinates":["@@@քɜОƨ@öŐמóƪôƩɚ̒Ő߼ȁςͩɜòƪ—ɜȀò—ñɝò—Ѻͪ@ŏƨŋóɝôǿƨ™ɚȃóəƨȃѵͩó̍@ȃƨóóƥƨƧ@ʵƦ›óͩɜ—ɛóñԭɛōυȂ̍ƧƦō@ɛƥ—ɛȀ̑œóʷóō̍œƩŏƧОəƧóœς۬Ƨœ@̐óòԫ@̏̍əȀƧʳɝŌóɞƧ˜ƨɜóŐƨò@ȄƧŌρŋóôԪОóʶ@̎óȄ"],"encodeOffsets":[[111870,29161]]}},{"type":"Feature","id":"shan_xi_1","properties":{"name":"陕西","cp":[109.5996,35.6396],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@ςôöƨɝȂɞȄѶóóͪƨȀóŎƨœ̍ɜƦƦôʸ̒@ɜƧς˜ƪôõô@ƪڔ@ôɜóʶôŌô̒୽Ӓ@Ʀ@Ѻ̎ɜѺɛѶôöʶô™ƨšóʴ߼۰óô̎˜ñƪѸƩτʶ@ȁòŋəѹóǿ̑ʵ@ȁ̒ʷυփô݉ôН̏ط@ȁƨóô̏ƪõ@ʳ̐ʵ@ɝɛŋƩŌɛóןôƧŋ̒ó@ŏ̐ƥ@ŏυ@ƧƧôן̏@ƥȂѹɜəœɛóԭ̎ƥóóœóȀן—ɛô@ŎѹōñƦ"],"encodeOffsets":[[108001,33705]]}},{"type":"Feature","id":"guang_dong","properties":{"name":"广东","cp":[113.4668,22.8076],"childNum":21},"geometry":{"type":"Polygon","coordinates":["@@@Ȃô˜ôƨ̎œ@ɚ̒@ôŐ@ɚѶɜƨȂóφɞȀ@Őƨ@ôƦ@ȄƦŌƥʶƦôôŎôʸ̒›ɜǿƦ˜@ɜƥŎ̎ƨφȁɜŎòƥԮŎƨōóŏɛƧɝəɞƧ߼ɜςȃñȄƦŎ̒ōôòƨəƨ˜ɚН@əƨ̏ƪʵυŌəɛóəԭŏəœóŏѹœρʵɝƦ̏™ƥʳѶ›öō̑óóŋρȀυƧƥɛѹōƧôן—ɛŏѵ@óŋôʵɝ›ƪԩõ@Ƨō̍@Ƨ@@ƦɝԮƪО@@","@@X¯aWĀ„@l"],"encodeOffsets":[[112411,21916],[116325,22697]]}},{"type":"Feature","id":"ji_lin","properties":{"name":"吉林","cp":[126.4746,43.5938],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@נ@ôН̎ʵѺòƨōԬŎôȁɜŋѶô̒ŏƦōñǿòƧφ@ƨН̎@@Ȁ̐Őöʷ̐ԫ̎œôȂѺôòŌôƧ̒Őƨ̏̎ȁφ˜@ŋƩͩםȃƨ—@ȁ̑ʶ@Ōóôɛœƥѹ̑—συ݇@ɜρƧȃࢯƨôœəȂɛōƩɛ̏υρóõœƪʴυφ@ʶôŌóœρք@ɜƧ@ɝǿƧͪρȀƩó̏ŐƨȂ̍غړȃɛԮƨͪ̏ςƩœôɚφȁƦôɜƧôʶφȄ"],"encodeOffsets":[[126181,47341]]}},{"type":"Feature","id":"he_bei","properties":{"name":"河北","cp":[115.4004,37.9688],"childNum":11},"geometry":{"type":"MultiPolygon","coordinates":[["@@Ʃ̒̏ŌѺ̒Ʃ˜óȄƧŌƥͪòôñȂ̎ŐóȂ̒̐̎›ôНɜ—נ̎ôŋɞȀѶ@ôͪφœƨŌɚœɜȃóƧƨƥƪ˜@ʳƩ›ɞρ݈@υНφʵɜ˜ƦρƨƧ̍ɝóɛѹ̍ρŏ̑ôóƨ@œƧƦôƨɛ@ƥƨ@ȂƦ@@ôəŐƧʶƨŌυœ̍̎ɛŋôōɝ@óƧ̍›ƦʵѵʳôʵɜŏςôƪŋƨŌɚ@ôНƥƧ@ōѸɛ̐ô̎ʵѵНԭ@̍̍Ƨò@ȁɝ@əρυͩƪ̏ƩõƧŎƧōóšॡȄɛʶɜȀ@ɞςѶƧœƥςɛŐ@ɚɜɜ@Ŏôôςœƪς"],["@@õə@Ƨɛ˜@ŐóƦφô"]],"encodeOffsets":[[[117271,40455]],[[120061,41040]]]}},{"type":"Feature","id":"hu_bei","properties":{"name":"湖北","cp":[112.2363,31.1572],"childNum":17},"geometry":{"type":"Polygon","coordinates":["@@ñȄυƦöŐƩ˜óנƨƨφ@@Ő̏Ʀ@Ő̑ôƨŌנóɜôƪŋɜŌѶօڔə݈òɞōɜŎôӏƦóƨô̒óôȃƨó̎ŐôƧƪ@ƨȁςƧə̑̎Н@̍Ƨŏρôԭͩԫ—̍ʵƧšóȀôɞƧŌ@Őѹͩñ˜òɞñ˜ɛǿƩ˜ɛñρͪ߻Ȃ̑ŏƪəƩóםôõŏƧ@ɛНƥȄó›̑ѺƧ›ôφóƨƨƦƪóɜŐôóòôƨóφ̐ƨóƦ̎"],"encodeOffsets":[[112860,31905]]}},{"type":"Feature","id":"gui_zhou","properties":{"name":"贵州","cp":[106.6113,26.9385],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@ɜȀƦŋԮ˜ô̒ɚ˜ôōעƪƧʴɝ@ɛʶ̒ʶ̐ȁƦœóȂô@ôŏ@ōô—ƨʶѸô@ʶƨ˜ɞó@ōτöòυƨ@@əƨô@ɛ̒@Ʀɜôȃ@̍ôʵԩНôóςŌƨŋ@ȃƧñôŏƧɛƨ—ôɝƧʵ̍œôȃυœ@ɝɛȂƥóóȁɛóõôɛ@əͪɛŋôȁƩóםȃ@ƥƧŏړʶѹ̍ƥŌƦȂóôɜƨѵО̎נəɜѹŋƧȂ@ȀóœɜͪɞƧ"],"encodeOffsets":[[106651,27901]]}},{"type":"Feature","id":"shan_dong","properties":{"name":"山东","cp":[118.7402,36.4307],"childNum":17},"geometry":{"type":"Polygon","coordinates":["@@Ʃ̐φͪɚςɞ@@Ȃƨñ̎̎Ԯ@ѶОƨƧڔ@φН̑ŋ@Ʃ̒ǿ̎@ƨɜԬςôʶ̐ʶöԫƨƧנƥɜŎôō̎@ôŏóρƧŏԫôóƧԩó@ƥɜƧԭóƨʵɛƨ߻ӑɜНԩ˜óô̑óƧʳə™óɛƧ@õȀƧœ̍ȃɛŐóŏυО̍—óɝƩ—ԩ@ƧɚԫȄɚʶƨ˜ɞʶԪ̐ړɛƪ̒"],"encodeOffsets":[[118261,37036]]}},{"type":"Feature","id":"jiang_xi","properties":{"name":"江西","cp":[116.0156,27.29],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@ƧȄôɚəȄ̎ʶԬ˜ԮͪςóƨŐƪ›τɞƦōƥƧ@ŏςôóŐôô̒ʷѶ—ƪƩƩǿ@ō̒ɛôυ@—Ƨȁѹɛəƨѹ̑ƨ̏óƥѵʷô̍ɛȁôŏɝǿƧԫƧ›ôʳƥōòȃρȄ߻ɛɝƨɞɚɜƨôŐƧŎԭōñƦòԮɜôɛ˜ôͪƥœ@ʶƧƨôƦƧô@Ȅô̎Ѷͪ"],"encodeOffsets":[[117000,29025]]}},{"type":"Feature","id":"he_nan","properties":{"name":"河南","cp":[113.4668,33.8818],"childNum":17},"geometry":{"type":"Polygon","coordinates":["@@φ˜̎ƪ̐˜ɞȄɚ@@Ȃעó̎ŌѺ̒ôֆॢȃô™ƨŎƨōƪöƩ̑ڔɜԩ̏ɝʵƧ—əʵԬȃƨəԪ@@Ƨ̒ŏô̍υȁƧɚ̍ôóŋ@ɝƧŋõ̑σ—@ŏɜŋôɝ̒ƧɚôôطρóóɛƩ@óƨ̍ŏƧôóȄ̑ôƧóƥôóӐɛōɝŎ݇ñړɚѵֆ@ɞ̏ʶ@ʴƩöó̐"],"encodeOffsets":[[113040,35416]]}},{"type":"Feature","id":"liao_ning","properties":{"name":"辽宁","cp":[122.3438,41.0889],"childNum":14},"geometry":{"type":"Polygon","coordinates":["@@ƨʴƧôôӔƨô̎ƩɞН̎ͪ߼ͪɜ—ɞɚ̐—@ƨςŏ̒ôƦƨɜœô̎ƪôςǿƨͩɞȀƨ@@ɛςփô›óŋ@ʵφυƩʳö›॥փρѹס@əɛ@ͩࢯ@ѹʵρ—ƩʶφȀƧ݈̒۬óʸɝŎѵ@ԭԫןɛƧƨƥςɛ—υʶφО"],"encodeOffsets":[[122131,42301]]}},{"type":"Feature","id":"shan_xi_2","properties":{"name":"山西","cp":[112.4121,37.6611],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@ɚѺñŌɚšôȄѺ›̎ֆφóςȂ̒—ɜƨɚ@@Ȁƨŋôȃƪ—ѹ̑̐ŋƪ̑Ʃρρ›óó@ōɛɛ@əɜŏƦρƨ›ρѵ@ɝɛǿɜʵóօѹ̑̍ŋסô@ȁə@ɝȃ̏—̍Ʃυ—Ƨô@Ȃ̐ظóОó݊φք̑ʸ@Ȃ̒ʶôȀ"],"encodeOffsets":[[113581,39645]]}},{"type":"Feature","id":"an_hui","properties":{"name":"安徽","cp":[117.2461,32.0361],"childNum":17},"geometry":{"type":"Polygon","coordinates":["@@ó̎̑Ő@ƨƪ˜Ѷǿɜ̑φ—Ʀʵ̐˜Ƨѵôóƪôôυς—ƨȂɞŏ@̍ԫôò̑ƥ—óȃѶͩƧƥôŏѺœôŏƦ—@›ƥͩƧ—ôȁυó@̑ƧɛѵʵƩƪѵ˜̑ʸóóôŏρó@ŐƦƨƥŎσɝƩœ@̎̍Оɚ̒ρƨƧȂôɜςôóظəó̑ƨóɞɛŌ@Őτ˜ö̒ƨŌ@ɞôŌ̎óƨəφȂ"],"encodeOffsets":[[119431,34741]]}},{"type":"Feature","id":"fu_jian","properties":{"name":"福建","cp":[118.3008,25.9277],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@̎›óȁƨӑ̒—̎ɚƨͩφŐƨɝ̎ŋóŏρ—@ōƨ›òʳəóƨō̏˜õɛƧ@ƨѵƧōəŏóŋƧô̑ɝɛʳƥ@@óɛõ@Ƨ̑ƧóȁəƧ̑—Ƨ̐@ɚəОƧ—Ƨɚóñ̑ŎóʴƨœƨԬɞȀóŐɜȂó̎ѶʸôƦƧ̐Ѻ̒ɚƧѺɜƨȂ"],"encodeOffsets":[[121321,28981]]}},{"type":"Feature","id":"zhe_jiang","properties":{"name":"浙江","cp":[120.498,29.0918],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@Ѷʶƨɜ@̒φôóȂƨ˜Ʀͪ@œ̐˜Ѹ̍τȂ̒̑נŐמôƪƧôӑ̑›@ƥρͩƨօ̏@@υɝó@ŋɛ@ôƩəóƧѵυó@ƩɜŋƧ@̍ŌƧɞυŏƧͪ̍ə̑˜ƧӒôȂ̍œ@˜óφ̑ɜ@ŎƪȀ"],"encodeOffsets":[[121051,30105]]}},{"type":"Feature","id":"jiang_su","properties":{"name":"江苏","cp":[120.0586,32.915],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@ôɞ̎˜φНôŐɜŏ̎Ȅƨ›öǿƨ@ôɜɚšƨʴ̒ôôó@Ƨ̎əԮȃԪૉöͩ̐ƧòʵφƧôʵ@óړɜóŏɜǿƧ›ɝρσȁѷ̎̏—ƥ˜óŐѹ›óŐƨƦѵͪôȄƦ˜ñ̒Ԭó@̎ɝŐƧȁρ˜óφƩóóôƨѶ̏—ƥʶυ˜ɛ̒ѵȀ"],"encodeOffsets":[[119161,35460]]}},{"type":"Feature","id":"chong_qing","properties":{"name":"重庆","cp":[107.7539,30.1904],"childNum":40},"geometry":{"type":"Polygon","coordinates":["@@əȂòɜƨ˜ѺɛƦȁ̐@ƪ—õŏφƥòȃƥ̍Ƨôυ̏ƧôñóóôɛŏƩôƧƥôƧóυƨœ̒ѹôœƦȃ@փƥɛ̑@@ɜƧó@ɚƧ@ñφσõ@ŎɝôƧ—@ʵѷóƧʵó˜@ŎóŐó@ôȁƥ›ó̒υôóʶə˜ƧȄς̎ƧȂôƨƨƨφɛ̎Őƨʷɞ@ςԮóŌôôφ@ɜֈ̎ƨ"],"encodeOffsets":[[111150,32446]]}},{"type":"Feature","id":"ning_xia","properties":{"name":"宁夏","cp":[105.9961,37.3096],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@ల̒ôޠφӒςôƪͧυևɜŋѺó̎ȁ̍ɛ@ѹס@@ʵƧȁôó@ǿ̐ŏöʵɝŋɛ@ô̑ƥóóƨƧ—ó˜ôœó@ƩôóƦ̍œóȀƨŎɛӒôŐυͪɛ@@Ȁə@"],"encodeOffsets":[[106831,38340]]}},{"type":"Feature","id":"hai_nan","properties":{"name":"海南","cp":[109.9512,19.2041],"childNum":18},"geometry":{"type":"Polygon","coordinates":["@@φɜƦʶ̐ôφô̎@ƨŎö@τʵƦ˜ԩ۫õН̏óƥȃƧ@Ʃəםƨ̑Ʀ@ޤ"],"encodeOffsets":[[111240,19846]]}},{"type":"Feature","id":"tai_wan","properties":{"name":"台湾","cp":[121.0254,23.5986],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ô—ƩɝöƧɝѵəޣ̏ρƩԭóōóͪρɞƧОôԪ݈ଦѶɜ̒ɛ"],"encodeOffsets":[[124831,25650]]}},{"type":"Feature","id":"bei_jing","properties":{"name":"北京","cp":[116.4551,40.2539],"childNum":19},"geometry":{"type":"Polygon","coordinates":["@@óóó›υóôƥ@ŏóóə@ƧŋƩŌρóɛŐóʶѶʴƥʶ̎œôƨɞ@óŎɜŌ̎̍φ›Ƨŋƨʵ"],"encodeOffsets":[[120241,41176]]}},{"type":"Feature","id":"tian_jin","properties":{"name":"天津","cp":[117.4219,39.4189],"childNum":18},"geometry":{"type":"Polygon","coordinates":["@@ôôɜ—@ƨöɚôœôôɚŏ@óƥ@@ȁƦƧɜ@óƧƨƥ@›ƧóəН̏óѷɜ@ŎƦƨóО"],"encodeOffsets":[[119610,40545]]}},{"type":"Feature","id":"shang_hai","properties":{"name":"上海","cp":[121.4648,31.2891],"childNum":19},"geometry":{"type":"Polygon","coordinates":["@@ɞςƨœɛȀôŐڔɛóυô̍ןŏ̑̒"],"encodeOffsets":[[123840,31771]]}},{"type":"Feature","id":"xiang_gang","properties":{"name":"香港","cp":[114.2578,22.3242],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@óɛƩ@ρ@óœôȀɚŎƨ@ö@@ōƨ@"],"encodeOffsets":[[117361,22950]]}},{"type":"Feature","id":"ao_men","properties":{"name":"澳门","cp":[113.5547,22.1484],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@X¯aWĀ„@l"],"encodeOffsets":[[116325,22697]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/chong_qing_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"500242","properties":{"name":"酉阳土家族苗族自治县","cp":[108.8196,28.8666],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XJ°œlJX@lbl@XbV@VLnJlxnbšƒUU@IVK@lVIVwnJlU@n@J@L@Jn@l_nWVLVln@@blLšmV@@xœÔ‚`nœ™xV‚ÈLlx„LVxVVšƒV_U»VWn_m¥XwVmnX°ƒlmUUVwÞaVƒk@a@mmIUa@™mwk@™ƒm@@U¯a@UV@@K™@ykkmwkV@kU@ƒÑƒVkKWLÅamaUm@kyU@WkU@Ua™IUašVaUUmUUa@aVLXKWa¯UUbmJXnWnX`l@@xkzWÆ@V„LU¦‚x@b@JkIkJ@LmbUamJwm@óxƒnk@V„@x„ŽVnUVmVUVŽUbVlUbkXWŽ"],"encodeOffsets":[[110914,29695]]}},{"type":"Feature","id":"500236","properties":{"name":"奉节县","cp":[109.3909,30.9265],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@WVXb‚UnK@x@b‚²kxmKkl¯_ƒVV°™VU@bnKVVV@@nkŽ@n›bn‚@š°@VLČUš@°WV@V™nU@InKVl@nU„b˜KnX„WlknLlKUwnalLša„VlUXmWk@UU@UWWIUyķ¹XaWW@X™ƒKUIVm„U@W@UVU@KV@n»VkUkÇmUmVIUmULUbm@ƒwUaƒKkkm¯ÑUL@bWVnx@VmxUI@„klmkkK@aƒK@IlJ@I¯ƒk@mak@mnkJVL@bV@Ub„„W`UUUV™I@VƒU@VVbUJVLUVVbUX„VVxk¦VJUnVxnVVUšJV@Ubl@@bXV@L"],"encodeOffsets":[[111781,31658]]}},{"type":"Feature","id":"500238","properties":{"name":"巫溪县","cp":[109.3359,31.4813],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@nLWbX‚VLVU„V@KšIVl@b„@lbšU„VnU@JÆU@V@n°KĢUl@VbÞKšVš@„_„V‚KXU‚U@KXƒ@wlkkU@mWKUU@UôJ@XV@œaVmÞIVaVLƒƒ@»kmƒ@ƒUkL™U@aU@WWƒLUUU™™KkbƒwWa@KU@kaƒXmW—LƒamVk@UmL@JmVUšU@¯X™@ċVUK¯@ÅnWK™LkKULWK@UXK@wW@™LkV@bVLƒlXn›`¯xU„°LnŽlV@n°Lnl"],"encodeOffsets":[[111488,32361]]}},{"type":"Feature","id":"500234","properties":{"name":"开县","cp":[108.4131,31.2561],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@n@na‚I„wš@@VVK„LVbVxnVÆUnanKWXamKmk¯K@mkUm¯KVƒ°w@Wm@UIUUlKUU@a¯KWanwmUXamKkUWUnU@KƒkUwWKXaWLUWkImaUUUƒƒKka±k@lƒ¯w™wmbUƒ™ƒkXm@UJkIW‚XXƒbƒmƒ„UJ™XUV@°šKlšlVXV@xmbnV@blV@VšœU`UL@V™a@bULlb°VXbܚ@V@bƒL@J„xnLVb@lVb@V@@z˜bXWšX„KVLV‚š@@bUVVL@b„„lVna@ll@„zl@@J"],"encodeOffsets":[[111150,32434]]}},{"type":"Feature","id":"500243","properties":{"name":"彭水苗族土家族自治县","cp":[108.2043,29.3994],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@„Jlb@nVV@bXb@ÆlL„Ul`nVKU¼VxkbW„nlUxlXX‚@°°WnnJ@VUn@J„k°L@VlV@nUJ„x@bVVVz@VnLla„KnalVlIUŽ„¼@nV@@anKUwVal@UlJœƒlI@akU@UWXKVI‚¯Uak@@KmkXWÜkXWykIWwXw@laXamkVUUym_XmlkkmmakwmIUKU@Wak@kaW@kI¯›WIk¦VŽƒUUƒmaUV@XkVUV±aUb¯b¯¥m@@ImJ—@mƒmL@kUKUkkJƒbV¦"],"encodeOffsets":[[110408,29729]]}},{"type":"Feature","id":"500235","properties":{"name":"云阳县","cp":[108.8306,31.0089],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@lb„LV„VVnblJVXXKWbXLVx„l@LmVXVVl‚nLWbnVmxXb°L@bVVkLVVVJn@@X‚‚œ_Wm„kUK@alUšKX@@xWL@VXLVKlLšKXLÆm@™mœa@ml@mU@UUmL@aVšUU¯„U°`lknLlw±@a@wmLVWaXU@KWU@ak@VaU@™IUVmUUwVmUIl¥UwƒUVWUaVUUKVIUa@UUUUJƒUUm™kƒ„nl@„@VWV@L¯aUb™Ulxƒ@@b@VULUx@VUxVV™U@bU@mxU„U@mUVŽklkkƒ@WxknlxK@amLƒKU„K"],"encodeOffsets":[[111016,31742]]}},{"type":"Feature","id":"500101","properties":{"name":"万州区","cp":[108.3911,30.6958],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ĸĊVI„ƒ„n„aWWXlJVIn@lWš„V„našx°xk„l@²Ž‚LVƒ„LnK@b‚LkwlmXw„@lllkUnVV@VƒnwV@@ašVUUVw@UVwVK@U@a„@kwšVVa°b@KXU@U@ƒmk„ƒÇсaml™kUVmn@VULU˜m@kUVkUaƒwUWm@Uw¯„mKUUmVUUULUKU„W@XbWVkaWwkUU™ƒ™k@maUbmbVlk¦ƒxUVUIWVU„kJVVkL@UmJ™UUVU@lLUVU„lx„@@VbƒJ™U™L¯¤@Vƒ„"],"encodeOffsets":[[110464,31551]]}},{"type":"Feature","id":"500229","properties":{"name":"城口县","cp":[108.7756,31.9098],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VK@w¯L@m@UÅV@ImVƒU™Vkaƒ@@aUk™J@LƒUUVUKmLmbÅVmUUwUaƒKUL@U™@ƒxJmbm@nVJ@X@VkV‚n™lƒLXx™@ƒb@bUVƒLU`UnƒbU@@ŽmVVX@JX@VLVVšklV—„‚`@bUL@V„LVKn@‚U@„UJkn@lmLmK@X@Jn@mb„nÞWVXnJ‚k„KČÑÆ@VK@knaÜmXlUČW°kôÇƁ@a@yÞ_VmƒUnU@K"],"encodeOffsets":[[111893,32513]]}},{"type":"Feature","id":"500116","properties":{"name":"江津区","cp":[106.2158,28.9874],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@„InWUUlU@LVašlX@°²lÒXxlK@Ul@@Un@UaVJ@I@W@UƒUUVUwVIUKUa‚UUVwn@Üx@XUlnn‚bœJ@¥VklKUUlk@ynU@kVƒUUVWnI@¥V£VWVIUKU@UVƒa@n@Vm@@nlUaVkUwƒJ@blLkLW@XWmXkmmLn™@m@U@UVm@™„UVUUlakUVa„ƒVkV@@wnaWUk@VwkƒlmVIkUUxmJ@U„™@KƒIkx±V@IUm@K@IUKkbWKUbn„m„@bmVnbmb@xkxUJ@ULW`@bX@WVXL@Vƒš¯„mk¯@UJ@VmLUaWnX@WJ@nkKkxW@UIV@@KkImmkK@UW@XaWIU@U‚ƒIkbWb„xXŽlLVbnV@bWlX@VxVLnl@nÆÞVÜ"],"encodeOffsets":[[108585,30032]]}},{"type":"Feature","id":"500240","properties":{"name":"石柱土家族自治县","cp":[108.2813,30.1025],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@„š@kl@š¼UbmVXJ@bV@nxVIVJULVVk@@LWbnJVU@bVbUJ@blLXnWV—@mbnV‚@V„„bn@VJVLnaVanbl@„šVšlVXxlbXUWaX@VƒUUVwUUVm@I@WmI@a„mlLœ™lK@alwnUV@kóVaƒÝk@UlbVK@™VU»VUUVWUƒ@U`ULkwm@@KmU@knKƒ»VkJkUmbƒLkbmK@UUyUU@aƒwm@@XXJ@VVLVVUbVnUJVX@K„„k`WXXJWXUbmW@bkL™Um`Xnƒb@JVL@LU@™°VVXKVnUxVLUbmJ"],"encodeOffsets":[[110588,30769]]}},{"type":"Feature","id":"500237","properties":{"name":"巫山县","cp":[109.8853,31.1188],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@kVƒU™bkKmbVxkLmKkllbV@@LXb„xlašLVšVV„KXXV@@bšVlK„V„@ln@¼°KXa„U@Ulw°JXalIUa„ÝWXW@kVU@ƒVUVWUUUamUw@aVamwn@VUUƒlLXWm£@wÇĉkKklmLUÒ¯ƒWn™@ğ±kwmaWm¼U@@LUV@V@XƒVUnVJ„LWš@‚XXWbĸºVzXJVXV@@VXlWn"],"encodeOffsets":[[112399,31917]]}},{"type":"Feature","id":"500102","properties":{"name":"涪陵区","cp":[107.3364,29.6796],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@nèVblĖVVnLšŽ„@šx‚V„n@nšJ@L„UVVX@lbUJV@@nn@VVVK@z„˜V@nzVJVUlmX@@_VVVbnaVal@@knW@wnaƒVK@aVI„J@£kUVW@‚wXUVJ„amƒ@Ikƒƒƒƒ_X¥ƒ@WwkKkwmŽ™šƒkUxƒnÅmm¥™WV@Um@UlVL@JU@@Xƒ@UVkKVk™KVk™Kkb@bmJVXU„VVUbU@@`W_UV¯b"],"encodeOffsets":[[109508,30207]]}},{"type":"Feature","id":"500230","properties":{"name":"丰都县","cp":[107.8418,29.9048],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@Þè@XUK@LlV@blbUJ@„„V@bnV‚@VVVXU@ƒlbXal@VXnKV@maXUރ@amk@aVKXV‚anbš£°mnIVaUKVwUmWLUUš¯V@@KUK@I„aWmn_šVlK@anXVaXWWIXWl_ƒƒ@LUWVIUmVaUUUK@UWI@Wn@VI@mkU@U¯Kƒl@ImVÅLƒwU¤óbUU@wWXkmm@LU@@VUIWVUL@JUnƒaƒx@Jn„ƒbUIWVx@ŽUXlV@¤ƒIUJ@bUL„Žmb@xmX@lk@UbmbUaUU@`W@kn"],"encodeOffsets":[[110048,30713]]}},{"type":"Feature","id":"500232","properties":{"name":"武隆县","cp":[107.655,29.35],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@l„„w„bVm@IVKXUVJ@UV@@KnnWlX@xVVôaV£„xÆKnUVm@UmIXm¯¯@WkWVwmkXƒlaUwV»ULmk_ƒVkK@ÅWa@aUU@mkaƒIƒb@‚n¼ƒnm‚_@mmK@UƒLUVVmI@aUJ@XWJ@U`UIkm±kk@@lULmUmKUnVšnlUVmI@VkVlx™bkIƒVmLUxkKUŽ‚Xš‚n¦Æn„mVw„lš™nlxlLXx„@W¦„`„„"],"encodeOffsets":[[110262,30291]]}},{"type":"Feature","id":"500119","properties":{"name":"南川区","cp":[107.1716,29.1302],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VšUbVJVUn@VLX@WVXVVI@VUVWxU@mš@ĊX@@¼V°aVUX`@_V@VaUUVƒUWnI@alašLUlšLUllLVU„@@WV@@IUKVkn@@VlLVwnK„UlJšakwlU@UnJVUmkU™VmXa@wVK@UUw™@VƒVI@akƒ@alInwlKXUmaUW@wWLk™™KVak_ÇaUƒƒV@šXbƒLVxUlWIk@UK@V™@ƒkU@VbUVUlVnƒLUV@lVXmxkV@L@V@Vk@WbUwmL@JUI@xVxkx"],"encodeOffsets":[[109463,29830]]}},{"type":"Feature","id":"500241","properties":{"name":"秀山土家族苗族自治县","cp":[109.0173,28.5205],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XlV@lzn@VŽnbÆbXKlL„U„ÒV@@llUnxll@zšŽ@LU@@V°b@Vn@š„l@VÑUƒnK@UšU@aUaƒkVm@K¯wƒklmnn„Ul`nI@almkIUwmWVkUaƒkkJmUUa@K@aU@@_m@@wUyVUUa@Umƒ@awl@Wka±„UkUykIWV™b@bUVk@›aU@UXU‚UIWakUWmUxUV@nUVWbšŽ@XXVVŽmXXŽ@VƒbVLkVWx"],"encodeOffsets":[[111330,29183]]}},{"type":"Feature","id":"500114","properties":{"name":"黔江区","cp":[108.7207,29.4708],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VX@V@LV@VJUL@lVnnxlb@VXV‚XV@@W„@UIVK@kUKna@£VWUaVUUalIVJVIUW„_lm@bXKV@mn@J„UUw@KnIVll@VanLVmUkVKXLVKUIVamw@UaU_lw„KlwUWV_Ua@aUa@KUšwm›_›Ó@wU@™nkK@am@UkUKmXk`m@@I@K@I@mkVmIUxUJ@kUL@JVV™„lnklWnn`VzUVnlWbkb@WxXxlJXzWŽÛlWXnl@Ll@Vb°UJWLX@VlV@bkJ"],"encodeOffsets":[[111106,30420]]}},{"type":"Feature","id":"500117","properties":{"name":"合川区","cp":[106.3257,30.108],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XKVXlK„ƒVL@UnV@aValXXK„U@WVwUaVU@IV@@aVW„L@U@anVV@@bVK@UVL@bnJWL@VnUnb˜@@JnIlVl‚@@bXIWbn@UKVLVKXLlaV@VVnK@bVL„m„IVƒ@KmknUUWVI@aVJ@_„WU_VmUwƒU@K™ƒVak@am¯mJU_UJUkU@WkIV`UI@JV@LmmU@@mƒbUzś™@„VK@nUKƒ„ƒb™akb@UWK@bkVVbV„Û@@`ƒXk@WŽ@n@lXL@bmb@VVJUn@JnUlnUlmX@`XLlbkJW@kzlb@`@b@b"],"encodeOffsets":[[108529,31101]]}},{"type":"Feature","id":"500222","properties":{"name":"綦江县","cp":[106.6553,28.8171],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@@¦‚@X„lVX@@UVKl„VUX@lanVlUVbXWVXVƒ„VVUnKVUlwUwU@UJ@nmVkUV™lwXam@VaUUUw@W@kk»mV@UmKkwVKVUU@@LUKVI@mV@XVWxnXVKUUUK@wWU@UUWnUlLXa‚mUI„am@wI@K@amIm‚UUkI@m‚akUkKWUUanƒ@wƒamLVxk@UVmUUL@Vm@kV@I@ak@@bWVXJlLVbVL@š@bn@@`Un„@WbUKULWVXbƒ@UVmbX„WVƒb@bVmxUKUƒV@šUn@V@V@nmšnKlnnWWXX@lKkK@a„IVxUlVb‚k@mn@@U@m„bVUV@VLUJUXU¤"],"encodeOffsets":[[109137,29779]]}},{"type":"Feature","id":"500233","properties":{"name":"忠县","cp":[107.8967,30.3223],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VLÞĊ„U@Wš@¼V‚„@lk@w²mlšVUœ„llšVnI@VlKUUlIVƒXUVJVU„wl¥UkUKUIm@ƒaUƒ@mUna˜@XUWmkK@aVIUa@aUVmIXa@Kl@UUVKUIUJmwU@@aWInUVa™»k@@lƒ™¯n™¤mabWUUL@bnl@b݄WVnbU@mLUWk@Wbka@„WVUU@UmUmVkUULV„lVUx„l@L@VƒbÈÒlb"],"encodeOffsets":[[110239,31146]]}},{"type":"Feature","id":"500228","properties":{"name":"梁平县","cp":[107.7429,30.6519],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XLV@VV@b°°nšƒnkb@bƒšnJWVXblIUVšxWnUJnVVLVU„JlUnLVK@UnUVJš²nKVbVKla@aXlJ„k„Klb„ƒ@U°£šKšV„IUa@ƒ@kwVƒVUkKV@VUkk›ƒUVk™±n@xklƒ@U@»™‚@XƒVÝĉUJnxWb@UX›KkVUbUKWUkVmkkLU`›b"],"encodeOffsets":[[109980,31247]]}},{"type":"Feature","id":"500113","properties":{"name":"巴南区","cp":[106.7322,29.4214],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@nxnVlJlUXLƒ¦@x@Vl@nKVVX@V_V@@KlVXU„@lKlxXIl@ÈĊ@Vl@n_VJlŽnVlnb„²VVVJVVmUUkĕUamçU@»W@@ĉn™V@XwVU@UUJWUXUW@UKm@UVUIVaU™UVmLUVƒUU„UWWXUakVmUkbW@UVkƒUL@VW@kUWƒ@mJUXVVU„@lmV@zklVVkLUl@¦›I"],"encodeOffsets":[[108990,30061]]}},{"type":"Feature","id":"500223","properties":{"name":"潼南县","cp":[105.7764,30.1135],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@@a@a@_kalyX@lIkaWK@_nWVkkmmV@IVmUI@Una@aWK@k@mkbWaknmJUk@mk@@kUal@Uaš@Wa@aXLlwUKlkkƒ@KmI@VUJ@Lk@@VUUmL@amJU£kKUaWakLmU@bVVUbnbWV@xkL@bUb‚xUxVbXJVbUVWIUVU@kLWxkKWV@n¯VUbU@@VVX@VmaUL@VUK@VVbn@lVnI‚@@lnLULm@Ub@Žl@na„@lK@XVVkJ@b@zl@@VnV@bVb@J@bnXV`lXXmVI@W@InbV@@aVKUblKVLUanLlmnLlK"],"encodeOffsets":[[108529,31101]]}},{"type":"Feature","id":"500118","properties":{"name":"永川区","cp":[105.8643,29.2566],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@@b܄nWVLX„lxV„VxXxlVn@@bVblK@a@UnLVJV@@UnLVU@VXaVKVXš@n`WUÿ@IUKlaUUUkWyUÛÅÝ@mmkUKUwW@Xk@amUUakKWƒwXaƒK@VVLklƒXVlkxV„UL@bm@Vxn`ƒIVxUVkLVšUšl@@lkXmmƒVUn@VV@Xb"],"encodeOffsets":[[108192,30038]]}},{"type":"Feature","id":"500231","properties":{"name":"垫江县","cp":[107.4573,30.2454],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@šĊ°¤nҘ¼œaV_lKnllUXVVLValUœLVW‚@XamwVIUKkaÇфa@U@KƒkVwkUUƒVKlVnU@aƒU@ƒVIka@akU@KVL@WÝçUV@Vmbů@L™KƒnnJW„ƒVkxlL@VX@VxmnXVWxUb@bkn"],"encodeOffsets":[[109812,30961]]}},{"type":"Feature","id":"500112","properties":{"name":"渝北区","cp":[106.7212,29.8499],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@@bVVXL‚a@lnbWn@L„@XVlK@VVLUVlbkLUKVVVL@VšnX‚VL@VV@UbVb@x@¦UxVb@bUJƒL@L„VVxlK@™nk@U@W„UVLlKXV„@VblU@UUKVU@wn@VJVanLlkX@VaVK™¯@a@U@U@ƒVaUK„kUUƒ±maUkm@UUkbm@@Vk@@JƒwU@Ub@I@JmwUL@aƒ@@KkVÇLkƒWkƒ@kUU@@xUVmKUnllUb"],"encodeOffsets":[[109013,30381]]}},{"type":"Feature","id":"500115","properties":{"name":"长寿区","cp":[107.1606,29.9762],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VVšU„bX‚lX„¥l@XnVmlxUx„@@blVnnôĀlm@aVaXwWUnmUwW@@UkKlw„UXƒmI„mšL@KÆ°na@UUImyU@ƒ—@yULUUm@@mU@VIkaW@UUƒV@K™I@mƒmU™wƒ@™mKUnU‚UIƒlVLUb@„@V@V@bš°ULUbW@klmKUbUIm@@xUVVL"],"encodeOffsets":[[109429,30747]]}},{"type":"Feature","id":"500225","properties":{"name":"大足县","cp":[105.7544,29.6136],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XUmaVaUU@anVlKXbValU@aV@@IXKš@@bV@VxVK@UXLlUšJXa@_‚@@aVK—ÅWVkwWaƒƒwUa@am@kUWLU@kWmX@ykI@W@UV@na@LlLV@UƒkwWƒUKmXX`mIVl@bXLWVkbkkƒx@`VXm@@J@U@UUKUxk@WbUIVl@VXLW„ƒJUkUlUImxXlmb@X@VUJUnVbšW@UV@@VVX@bnW@LVxUnlJUV@n„@VxVIn@l`„UVVVL"],"encodeOffsets":[[108270,30578]]}},{"type":"Feature","id":"500224","properties":{"name":"铜梁县","cp":[106.0291,29.8059],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VblLV¤nI@bnKVV@Ul@@KVI@UnJ@Ll„klVLkxWK@bXb™@Vbk@Vb@ll@@nVlnIlmXblaXl@„W@_Ü@UƒUalU@aXL@Vlašb„a„ƒVL@mUL@ƒUUƒƒÇXUW›X_WaƒƒUƒ»m_™@UWULWb@UUVmK@VU@UImK@V@bkL„x‚„XblxXU˜ÆUL@b@@`Wb™IkVWK@VULUwU@@a™@WL@JU@@bkVUb"],"encodeOffsets":[[108316,30527]]}},{"type":"Feature","id":"500226","properties":{"name":"荣昌县","cp":[105.5127,29.4708],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VI@U@WnaWknwVJVkVl„IXƒWK@UUkVJXal@VwVL@V@V@In@UW@_„wlllaXUWK@aUknJW_ۃ@aWaU@@UVm„UUaUImJVnÅUmVUm`kUUVWLnVU@VVmXƒK@„nxmŽULkx™ImJ@nU`@X@Vkn@`@nlV@nVJVaX„VLnK@bVV@nV@lbXWš@"],"encodeOffsets":[[108012,30392]]}},{"type":"Feature","id":"500227","properties":{"name":"璧山县","cp":[106.2048,29.5807],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XzVlVVkbVL@JVĀXŽ‚¼V„„„XbW`XœWVȎ„„VVšŽVkV@@UXa@alK@IƒƒU@UKWUyUI@wVUUWVak@VUkƒW¹@WXI@yVIUK@kWwkѯ±W@™kUb@KkVVVmXƒJ"],"encodeOffsets":[[108585,30032]]}},{"type":"Feature","id":"500109","properties":{"name":"北碚区","cp":[106.5674,29.8883],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@X‚VLV@„„@JkL@bWb@VU@UlƜVy„a@nV@nn@KU@IVJU_lJXV@VlVIV`nIn°@b‚lUbš„„KVI@aUaVw@¥@wUaVaU@@UUKW™m@UUKUUVLlKkaVUUK@UkLWUƒ@@KXmma@kbWKUU@aUamLnÞ@VWLk@@Wm@ULU@@U™KUVWI"],"encodeOffsets":[[108855,30449]]}},{"type":"Feature","id":"500110","properties":{"name":"万盛区","cp":[106.908,28.9325],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VIV@@wVJ@InKVxXal@@U@U@KlUnwUW@kVU„KUmVkUa@I@KW@@bk@@mƒU@m@k@a@aƒIUxmJk@ƒwULƒwkKmVVX@VXV@xVLVVULmWXwWUU@@nUJVL@KV@UVULlxnL@VnUl¼@l@XVxVVUbn@WbkxUšlVnU@m"],"encodeOffsets":[[109452,29779]]}},{"type":"Feature","id":"500107","properties":{"name":"九龙坡区","cp":[106.3586,29.4049],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XK‚L@Vš@XbV@lW@UV@@VXIV@U™VKlL@KnnJ@VV@VU@I„@@mVUVWUUmL@V¯LUK@UV@UU@a@U@yU@WLUK@X@KUVmL@ƒ@aXI@w@ammVk@WÛwm@UxVVVbVLUJVxVU„V@V@X@JUIVbm@@Vk@@VkL@lVLUJ@zWJ@X"],"encodeOffsets":[[108799,30241]]}},{"type":"Feature","id":"500106","properties":{"name":"沙坪坝区","cp":[106.3696,29.6191],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@Xºl„UVl@UbVXUV@xVJVzXJVUšL@VV@VKn@@Xl@XK@UmÝnKVbVakkVm@k„ƒUK@UmIm@LkKULVšU@WJ@UU@@VkXU@Wa™@@UKWL"],"encodeOffsets":[[108799,30241]]}},{"type":"Feature","id":"500108","properties":{"name":"南岸区","cp":[106.6663,29.5367],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VV„JVL@bUVVnl`XIlwXJlw°nnl‚IXW@UÇĉk@WJkwkLƒ@WVkU@LU@U`W@UXUV@n"],"encodeOffsets":[[109092,30241]]}},{"type":"Feature","id":"500105","properties":{"name":"江北区","cp":[106.8311,29.6191],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@nLVU@wV@lV„@Xll„ÈKlU@L„@@bVKnx@I@JVaV@„x@Il@@Un@laVVn@mkUIm`k@WXJmk¯mkxWIkxWJk_UmVUUKƒ@UU™@ƒ„@l"],"encodeOffsets":[[109013,30319]]}},{"type":"Feature","id":"500104","properties":{"name":"大渡口区","cp":[106.4905,29.4214],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@k@@U@w„¥WKkVkImUmwa@b@xWJ@b@„nKVU@L@WVLXKV@@z@V@bVVU@@VVL°K@U"],"encodeOffsets":[[109080,30190]]}},{"type":"Feature","id":"500111","properties":{"name":"双桥区","cp":[105.7874,29.4928],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@WwUwU@kK@KmbU@@V@XlJ@znWlXV@XK"],"encodeOffsets":[[108372,30235]]}},{"type":"Feature","id":"500103","properties":{"name":"渝中区","cp":[106.5344,29.5477],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VLš@VV„@VL@aUKƒIUUƒ@@JUVU@"],"encodeOffsets":[[109036,30257]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/fu_jian_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"3507","properties":{"name":"南平市","cp":[118.136,27.2845],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@@knyƒk@ƒKU¥šwV@nkƒWƒzUmk@@lKUa@aVI@UƒKUamKUUVaUI‚@Xƒ@UV@K±IUVVlUbUbUL@KWUXmWk@KkXmmkŃKUƒ™a@amUƒbkUkKWUnwUƒÇwV™UUƒÝUKV£U™@ƒnKWwXLVKm¥@wUXkmWk@ƒ@wX@lU„@šyVImaXwVƒƒ@kŽƒnU@mbk@mlUXƒmU@mV@n@bnW@bUIWJ—ImVUKWbUK@nkKƒaU@W_VUUmWmL@UU@™bUWUL@V@bmVUz@`mUUVVbXL@V™L@lmLUxmVamXkW@xWbU„VbUxkU±@ÅUmmkLUbW@@`kLknVlV@lbXxlVUXVV™ŽU„U@UbWŽkIWVUUUJkI@llbUxVL@V™VƒUU°ULUmWXUV@VULWb@™xm@UaVLVKUa@ƒw@V›bkmVambUUm@@VkK@„@b„xlxX@‚„n¤@Xƒ@@lkLWV@Žn„V„kb@bWJXLWx@nkxmm™bXn@VWVUn@VnJ@bVXl@„™VJXnWbX`lL„UlJVI@Žœ@VXV@Vl@bn@@Æmn@VšxXU@mVIlxšVššnI„l@nVJ‚aXI@mlU@aXkVm°klmnVV_naš°@V@xܦXK„V‚nnUlVXbVK‚LXKV@naV@@VVl@@lXblXšWnLlbVK²nš@@‚VLUnlV@lƒXxô°‚V@UnaUUlKXLVUVVUbVVlUnJVX„@VW@an@lb„@nl@VU@anƒšUVW@kƒaUm@InVVKVU@kUW@Uam@km@kVa@a@™nwšU@WlI@mVI@WXaW_nƒ@™nƒlkkW@U‚¥@kV@Uw@wUƒ@@IXK‚¥VIn@nU@`@Xl@VV„LnašW‚bVaUwnU„@VIšKlV"],"encodeOffsets":[[122119,28086]]}},{"type":"Feature","id":"3504","properties":{"name":"三明市","cp":[117.5317,26.3013],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@lL@Un@VVna‚bnUlœa@U‚x@„VbULUKVbn@šw‚@XaVK@UVUXWVnVKV¯„VšU@UUKVwka@klJVIVVXUlJXVaV@VƒšUUVWkUWwkaU@UklmlK@_X@ValKnnÆV²@lVVwUaVƒXa@wlXnW‚bnUVwnK@kšK@UWKUaVUnV@_VynU@a@UVKVXšaV@@VnKnXVV‚UX`V@„blL@mVLXaVLnU˜JXIVJ@amX@a@mnUV@„nVWnkl@naV@„ml„@@KmKUam@UU@ƒ@UlKU™Vk™U™K@aVaUwV™U¥UIkJ@wmI@‚mbkwkVW@UXƒKULU`™IVKUa@LƒkkVmUU@WlULUWÅU@I@ƒWW™nU@@w@a@ƒUam_XyVIVWkkƒ@mwVKXUV@nw˜VXkWƒÅ™U@ƒaƒU¯KUnƒK@ƒ¯šmUƒLXŽVLnWVbVbUVm@Ub¯¼W@amƒ`kb™amLUUUƒ™aUXV`@x@XmJ@n@L@xkJUU@kU@mWm@kUUwUUVWl@VUkIƒy@kkaVUUm™IWVXbWxU@k„mVkK@nWVX¦WxU@@bkx@VU@WŽk@™kUbmJUUmkUW@_kKWKƒ@knV¤kIUKWLUbV‚@Wbk@@VWL@VkI@lUXVxUVU@@mWIƒV@a¯nUaƒaUV@„ƒJ™b@bÞ°VbUš@X™aUVmL@‚VXblŽnV„°˜n@Vnx„@VUUUlK@InJVb@„Vlnn@V™L@VWJU„x@XlJUVVVl@LUUUJ@Lƒ„@lUL°¦k˜V„VnV@„xV„„l@blLnlšLVaXll@šnVUn@‚xn@nml°‚X@lb"],"encodeOffsets":[[119858,27754]]}},{"type":"Feature","id":"3508","properties":{"name":"龙岩市","cp":[116.8066,25.2026],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ša„I@ƒVU„bVb°m@b„UXJ@nV@VUUwVW@klJ@UXK@Ul@Xa‚@UVaXKVLlJU£lm„@XLlL@`VXnlVVnIVašll@XV@@Ulw@aV@XwW¥XU@mlLnUlƒV@XwWaXUšJVnUVlb@l„zlJUVk@UXVVVxlVn@nXV@@lVVlI@w@K@mnI@W@wU_VWšbV„VVnKšbla„_n‚bX@°»Van@VUUaUamXUKW„K@a@Ukƒ@wWkXƒWW@wUU™Kw@_lyƒwUkU@@Uƒ@kamVmƒXašUVUka@Wk@»UUUVƒKkbWU™VUbk@mkƒxkƒƒKnIVUmW@kUKmXUmVaU@kU@m@KUWVkIWJ@ŽU@UI@wUUUa@KW»nU@mVkUmm@XwWU@ƒUUmL@ƒw@mnƒVUU@aWak@@amxU@UxULWVXbVLU`mbUImVU„ƒbn‚V@@bVn@bnVWxLmyUbƒIUKƒ@aƒVm™akbV‚UXW„UlKWbkV@„WLUlk@@nšbƒb@lkKmU@ƒUIWJkw¯UUVVxm@@XkbWx—›XKƒlUzWJkUUL@bmKkVƒ@@VUIUlWV@X„K@VkbWx°xUb@LUbk@@VWb@LXJ@VWXU@@bUVV„VVn@VVlLn„@l„@‚xk¦Vx@bVJXbƒn@JlnXxV@@„nJ@X@V@lmx„bUn@xVL@VVKlL@l„„nLVaVL@xkl@LƒxVl°š„X„WVX„Vl„œJWnxlJ"],"encodeOffsets":[[119194,26657]]}},{"type":"Feature","id":"3509","properties":{"name":"宁德市","cp":[119.6521,26.9824],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@@LVKVaVaUkVU²J@LVU„@@W‚VJUbVVnLVb„L@VUJ@bVbkL@Žl@Vn„y„XmlU@™xV¦„L@Ž„lmz@lnL@bVVšbVb@l„nšKVk„Vl¤@zXV@šl@XJVLVKnXVK‚VnU@wUm@šKUƒ@UlVlw@U@U@ƒUaUKlU@kXKlmXIWKXaVIVUVK@KU@@k„JVUnLVJUL@V‚IVa@VnLšKUnl`Vb„V„V@š‚Vbn@Vzn@lKnVlI„VVKUalkXJl@XXVWVLVUUmVU@Unm„£lK@Uk@WUXK@U@WVwVkšƒĠkĢÇ°aUÅUwmaţƒɱUÇa™w„±V¹XalKôx„@„UVaÜʓͿVóbÅLƒJm„¯Vk¦ƒŽk@mamXkKUƒUL›akbk@mV@LkJWb@Vk„mXk@UVmaUV@amLUKUamI@KUaU@WbU@UUUƒUIWJUkm@šƒw™Kk„VJm@kxǁVƒUK@mUVUkmlkkVm@amwƒLVWU@UbVLkšUbƒ@VƒmK@XaVWU_VJnwV@@kUmWakxƒ@kwWakIWxnbUJ™zƒ@kVW@@x@„XllnVW@xn¦ULWKXxmL@„VšU¤VL„ÞVVUšÈxV„mxXVlLlV„anV@bšbV„„LlÆnnlW@LXlWnXV"],"encodeOffsets":[[121816,27816]]}},{"type":"Feature","id":"3501","properties":{"name":"福州市","cp":[119.4543,25.9222],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@lxna@nJ@xlIVJV¦UšVxUb@bšLšVUlVškL@V@„VVn@Vb‚Ln‚@LU„lJXblx„@lwXbVn@lU@mxUIV`UXWb@‚nLU„„@Val™UKVaV@UX„Knx‚bn@lUkllnUVnV‚@VLU„È‚lwn@UIlƒšL„x‚™n@VlXIVJV„VVV@XaV@Vb@LnJVbVLnK@bVUnbVUl@nWlƒ@UXalI@KnUl@laœbVKV„lLnWnbl@„l¥°Unƒ„IÆKôa΀U„a@UUwÇWǓIUWUÅVkƨm@ƒ@£@KmLU¤ULˣJ™kUƒVǟUUķ@ĉVƒKUk@Ñ°wôǚç@īšé@Åţ¥mīÛkm¼Å@ƒVķVó°ō¦U°ƒn@bVJXVVL@bUŽƒakLmx@xmxXzW`XbWnXV@bWLÛ@™aƒ@ƒaXbWVkaÝwU@mlWKkLWWkLUKULW@kVmVUU݁UamV—¤›n@xUVUzkJV¦lJU„"],"encodeOffsets":[[121253,26511]]}},{"type":"Feature","id":"3506","properties":{"name":"漳州市","cp":[117.5757,24.3732],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@@bl@Xb@bVVUŽm„@n„x‚@nKVV@„XVWxn@VnUl@nmVX¼@LVbVV@xVJV@@XIlJXU‚V@Ln‚@lVV@UbVnnWVL@lnXUVmJ„Ll„„wnll@VašUXVla„LVUVV@¼Xl@lbUV™VWbn„nUlb„@@VV@„aVUšmlUašUny@kU@Wkk@WaUVk@@ammk@@U@UlU@aUa@wl@šmXLllnL‚U@anVnU@L@VVV@KlXnWVnVanUšw@w@wm›nÅ@wƒaUam@Uk„mUl@@a„a@U@¥škôK‚wȯ°w@ŻkwǕaK›ÑÛk@ĕōřċ£ĵƒUKW»kÅŻLU@Ulġw@¤Vz™VUbkKUbmLmlULU¼UxmbXl@bWVƒb@bUnV‚UšVbULU@@VkbVL@`U@WX@ŽXV@b°„@b¯š@¤@Xm@@b@`U„VVUL"],"encodeOffsets":[[119712,24953]]}},{"type":"Feature","id":"3505","properties":{"name":"泉州市","cp":[118.3228,25.1147],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@Vl„xkz@`‚xšLVV@xXXW„Xl@xl„@V@bnV°™@„„LVm°L„V„bV@ƚX„Wl—UmxU@WVULnx„@llUXUJWzn`Vb@„@b@xV@šmXX@„@JÆVVXVKXkV@nVlU„l@KVbULšJV_VK„LVWX@lUVƒkIU¥lIVyVU@wœm˜£nUVWU@aƒm@UmWw@UX@@am™VUn@@aUUlUVanaWUXWmUnkšK@VšUlVVUUwš@XLWWX™ma@knm‚bVb„VXbVL‚@XJlInlšL„w˜mXóšw@çV»ÇçŋaķƧóƅóKġ°nÅUķƑUÇW@—¯xÇ°öÆlV„n@llšaš@„Lšbƒ`™@™„VšXVƒVx@V@bULVJUk‚Ç@ƒ¼ƒXUKk@mmULkaWbk@ƒx@UkL@a@K@U@UmKmbU@kV@UmVUbUmmXkW@LUU@U@KmVmU@bVmKkkWK™nk@@xVb@bkV@V@Vl@nn@bl@VUXbl@XlV@@lmz™VVbkŽ™nUVƒb"],"encodeOffsets":[[120398,25797]]}},{"type":"Feature","id":"3503","properties":{"name":"莆田市","cp":[119.0918,25.3455],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@VbނVVnUlUX@VKVLlKXXlKXL‚‚nkV@ÞxlbXUWa„b„@šbÜ@XK@aWUXmWaX_Wynw@wnwlK„bV@aUKWUUI@a„mV¯Ŏ¥ô¯ĸU„UÆ@n»¯aƿé@ţ¯nĉĬÝK™óó@™ÑU¼@è™xWô—nƒx™KmkkJWI@UKWaƒUUaamn@lnbWšXXWK™@VxUVkU™V@U™LmlnVWXXVmbUbkVVV@bm@UVnš@bW@@VXx‚n@V„n@bV‚UX"],"encodeOffsets":[[121388,26264]]}},{"type":"Feature","id":"3502","properties":{"name":"厦门市","cp":[118.1689,24.6478],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@@VlUV@nanL@V@V@L@blK@V„wl@XalbVKnnl@VL„W„»È@lVUIVK@a@UUw„WUU™šƒš@„_™aƒK™@™bkkm@UƒkõŁxóL™l@¦@Vƒb@bk@VŽƒnVln@Vb„b@xmÆnœ@x@x™x"],"encodeOffsets":[[120747,25465]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/gan_su_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"6209","properties":{"name":"酒泉市","cp":[96.2622,40.4517],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@ÇnÅaĉ@ƒU¯¥›UŹ‚ƒ£™WUýUU±JkkUw‚yÞIČxĊĕĊ¯š¥ÆUkţ™UÅÓ±¼™IUx¯UƒÒƑ‚ݐŰƒKÝnğ°ÅU@Žƒ@Vn@þš¼¯šWnŎ°XLWlnVnbWnƒVXxmbƒa—bóUƒlǕUUa™IUmlU™ƒš¥™kƒ¥ĉwkkƒÝɛa@¯™™U¯°mVƒkVnKlƒōÑÇÑU@kl™UġŽkUŻnUW™@š¯ƒk»šmWV£UKnUƒmUw‚w@ƒUIVaX™šwm»Èmmwn¯ċ™¯LĉŽUƒJUalka±Va@U‚k@ƒÛф¯WmnUaɝ¤Ûmƒn¯m±x@wóxÛLġÒUx¯VƒÈ™JUbóz݃ÇKĉ¯ōlÝUŎWl¯nťbÝ@¯ǩLġmV@ƯĢkÆm™ĊkVťLɃmÝXó°@„ĢbVŽóVݦɱ@Ƨaġ„UV„ĠÇÈV¼UVţwmbJÇwˋa™XmǯKkkmŽƒbXšm¼V¼ǬŚ²¤ôŰÆƴô̐ŤǪnɆӨ¼ɆLÆłUĊšxŎƞȘǔˎǬǪnƨŮǬö°»šġ„„ÞÜÆĸÒĊ„ǀbƾèôÈ@¼¯þŤĸƧ°VĀ¯b@lÈĊ‚šʠń̐„ȘKǀŽֲॗţÿǕý@ʊǓƨóÆÑǖŃôw@΋ʈƆÅÈVVĊV„óĊÅ@ÞƒĬV@Þīš@°Ž„V@ĸĢƒ°XτƜĠ@ÈaÜ¥Őƅ‚™nğóĕVġUůƿŋ—ĕƒa±V—UťÇğÑ"],"encodeOffsets":[[101892,40821]]}},{"type":"Feature","id":"6207","properties":{"name":"张掖市","cp":[99.7998,38.7433],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@ÈÒŎÒk„mLUŽlŽU„¯nV°šš@°ɜb„ÞĠaÈ»ĸl‚š„LVUÈ@Ċ@ýUm„@@ÆVĠ¯Þm„LƯޏƒ„Ñ°VVwšJ²»ÆԚVlŤÅV™¦ĉ°ĉĖċwÝJzVxll²IVVVþšX„¤źœV°¦„VĊ@ÆbÈmǔLĸĠ¯Ģaô¯ĸmÆÛUƒlÇĸk°XyĊUǔV„ǩnmV»ƒa@ýnK°n@l¥@»ż„Ċ¤m皃@£ČU@mƒmVkÞUƐ±²¹°‚ĠwÅƑŃU¯™›V¯aÈŁšƒÇ»™ġn_°xŎKlxœklx„@Þw‚„„@Æm²b‚DzLlkšWXať¯ĊaœÑšK±w@wƒUÅçV±Uk™@@„¯š¯xƒU™±±UU°ōxVxÅÔō°ó¯UÝ¦óbÝþƒ@ĉÈóUV‚Ux„„@VŽUVÝwÅÈǎóVkk¯JǐkmmL@„™KÇx@bkš™@U°ķ²ó`ƒš™šmn¯°ƒUwlÅkUƒ`™¦ɛô™Žķz@ŽÅnÇ°U¼¯KmVk²ƒJƒ¼ƏÞķôš¤ULƒ@mnğ`™šÇnUxÇ@Ûÿ™U@ƒƒkŻŽ@x@móJkŃ¥VŹĉóÒĉlċ°ķ„Uƽ܃@›x"],"encodeOffsets":[[99720,40090]]}},{"type":"Feature","id":"6230","properties":{"name":"甘南藏族自治州","cp":[102.9199,34.6893],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@ލš™nKlnšwX¥WÝXk˜xÞUnƒ°aĊVnUUKlÞĶWXnĠ¥ô»„™@nmVL@¤°™Vz„JšanU@aÆwna@k›ƒU¯šyX_›aĉb™ƒ„wƒéXkWwÅaš¯V¥mƒ¯UƒƒI@ƒš@„mšb°aÈçšUš¥@»‚knwɜƇ°I°ÑÈmVU™¯Xa@w‚W@wšV¯Č¥l¯Uwnm@k˜aUaóKkk@™Ça™b@ŽÒWa¯IÇxÛam¼™VUƒxÒl‚@zÝÒ¯bÝaĉVĉwDŽW›zJ™mJn²mܯUƒ¯ĉ@ġ¤Åb@²nšmlƒ@@Ž„„U„ƒLVxšV™„U¼Ålma™b@ƒ°™l@WIUƒ¯@mƒ™@™™ó„™„@U›zţyƒXÇU™ÇVUUVLkbWakVWmUbkkƒKUÆ»nƒ°Knk@aƒUVmšnk»l¯Ģ›lw@_kKVU@ƒnaƒ@lUk@¯¥mV@kmbW™b¯Åõa@mkU@kƒÇŽkU@›`@™óó—bl¼Uxƒn„¼šlVȄx@blVkVVnƒ`XÈġÈ@ǃK£ÝJmUUnUĖmlU„mKUn™VÅaUw›Uĉ`¯n¯wW¼nxVŽ™š@bĉnƒ‚kIċŘkXUŽ±Ò™xšÈ@ŽX°`l„œV˜IȯĊV„ƒšVVan@VašUVażVmšblkÈW„ƒWIXa„alL@wVb„„V„¦lL@lĠ™n҄U‚nk‚šL@ÆÞkšÞšK‚bñþW¦Û„ċVƒ„ULUºkÈlŎUxÆxÞUUxšÒ‚x„@XbšL@lÆ@„ÒlXVln@„bm¼ƒJ@„Ån„šƒx@bnšĠm„xVXmbÈè@ŽĊ£ČW˜w"],"encodeOffsets":[[105210,36349]]}},{"type":"Feature","id":"6206","properties":{"name":"武威市","cp":[103.0188,38.1061],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@±¯¥@klwU»ƒƒÞÝmwKm¯™™ç@™kVÇUL¯lVUKġ„ġm@a@U„@X£°l°LŎÇ@aōVÝw™ÔƒKUŽÅš„WJ¯lm@ÛVWa™@klĉUmaƒLUanaƒ™ƒk¯J„™™±KkXóÜÅxƒ²Ç‚@„„nUÒĊb°@™ÆkL™Ž™XÇÆ@xÝn—xWxţ„¯¤ƒI@Æn„ƒVV„VlU²Æè„V@x²x™L›ÒĉbŦ°Wb™Xklބš@l¤šXĊ`„wl@ĢÈŎm@bšnV‚Ubƒ„@șÆÛLƒèǚUÒŦlĸ™`°ĮʟÆǓbĉôϚĊƚĢnŤé΀ÑĸĀĊ¦„@@l°lœ¦Ȯ¦ɆÞĊKŤ™ĵĸů„»mŁyġ™ķŭ@Çɱȭ¯mƧUĊķnŁŻ»UaU™˜ƛɞÝƨů"],"encodeOffsets":[[106336,38543]]}},{"type":"Feature","id":"6212","properties":{"name":"陇南市","cp":[105.304,33.5632],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@šÈÞ@l`UmVƒ¼œŽ‚@nnÆwVlnVVa„LVƒÈ_‚ÿރ@n„a„xÆ@„lš_š@VxnK@llLnxmÈŎJnbUxšI°Žl@n¦‚lÈIlmX¥„k°@šk‚J„k²é˜@klaUaVaU@@ÝnIWnmnx‚k„ºÞ„„aV™°„V@nw‚KšxôbÞ£šVšU„bšþšLn»mƒVw„IšJ°Ž@„nb@°°I„ġUkÇKVƒ™™@ů»lƒ„Lnmƒ£@anK@Ñ܍n@»mL@£™yk„UUmbUÞÝ@kyÇbó»™XUxƒWVzb±mÝbXaƒwUamL¯»@wUKVwm¯ĵJ°ÅUWVk„KVk°wÈVšVуlUšƒ¥škmVamknƒUw¯¯ƒbċ¥ÅKƒk™Kk„™VċVk£kKVw‚Ñ„a@kóyÛ¯ÇVk™ów›š—Xō¥Ç¼ów™Ž¯U±‚k„ƒ@x›IĉÒÅVmÈnšÜ@n°„bUbÝV‚ŽUnnJ¯Į@‚m¦nV܃@„„L°JXb‚Ñ@šaÈb@šllôLVb—b@lmnVxk°ċ¦U°™Ž@xX@xWbš°UVÇn¯Ò¯Jɛƈmxl@¼"],"encodeOffsets":[[106527,34943]]}},{"type":"Feature","id":"6210","properties":{"name":"庆阳市","cp":[107.5342,36.2],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@kw‚ĉ—»VamƒƒV¯wƒIóVkl¯™Km™Vō¯ÝWkL@bÝKō¦@Ž™„@š™Lx›@b@l™a@km@@l¯nm@UaÅ@ƒ„óWUXm¥™nƒw`@UUxķôÇ°ğ¦@„VJš_n‚‚IVŽnalxkX„JWn¯šnVƒLšxl¤nnVbklVX@xnxmV@bUK@nm@@xƒV—°±aÅnƒŽkUWnUaƒx@m™n@ƒ¯LƒššmUĀlU@lV@blLUblxklkIÇx¯°‚UXbšaVŽUnšV@°‚LUlnbšX@`°nVmbnÆmV‚kLmK™¦UŽ@X„y@kl@U„°K@¼XbW„ƒš@b„WnLVa„VšƒVz@xlVČ¥lbUxލlV„U@nÆWôn²™VJlU„Ƨ„LnmÜLXa˜n@mœw@wlUlV²mšblwšVȃlLލ„±@lVnUlxnkma@mškšJ@kXV‚U@mn@š¼VXUƒVƒlLnmVbôaVnWV»ÈUl°È¯ÆIn›ÆU@kk»mKkÆġk¯@»mƒk—¯@óÇlÇ@—Vykkl™Uml¯Þ™@w"],"encodeOffsets":[[111229,36383]]}},{"type":"Feature","id":"6204","properties":{"name":"白银市","cp":[104.8645,36.5076],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@VKUȚl@šè°šnŽ‚LnxÝބ„V¼kx@l‚¦²°ĊóĠ„™Ċ»š@ÈxšaĊxlwÈVŤa@¯²aÇ£ƒJk£lƒnUÞ@°šô™@y„wl»lIX¥Ǫnw@ÑÞWla„ÅlL@ƒUwĉakƒl@ƒš¯mwna°J„V¯nUVÓÞÑm£²óWaUƒÇ@óÝUçV»ÈkkW@¯‚xV@XlK@wX@Vmm_@wÈݙKU¯ÇwVwÅK¯VƒkƒJ™™™XkWVaƒImŽ¯Uk„ÇlVšœĀV°mxóšk„@¼ó„WxĉÜU@Ub‚zÛJÇk@‚ÆnVlԙ@kŽ„x™ô@ĬWL¯ƒƒK@aÛImm™@ƒIUaƒ@™™UŽÇêU¤VÒÇx¯ÒV„šš™lk@Wbĉ¦UbkWV_‚y¯Lƒaó„kŽ@b@nmbkx„°"],"encodeOffsets":[[106077,37885]]}},{"type":"Feature","id":"6211","properties":{"name":"定西市","cp":[104.5569,35.0848],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@„a‚V²wVJV_@„LlanÅllŦçÜӚ_šlnƒWaôk„xUš„bmV@È°lèšnk°l¦„`@nnL‚@ÈlÜIyVaV@ĊÛXwôƒ@»lƒô™nwU¯›ÿU™Èklƒ°Vn„JUblXšWšš„I„l°U„ƒVƒš—@aVVVmnL@„lƒ„UUw‚mkƒš£„bV¥VUVwۂƒlaÇÝރmk£ƒLUy¯L@WlkKW_XaWƒ—mƒ„ġU@a™k™‚ƒakXkmVwmŹVƒU™b™WƒónmwnWW£„KÈnV¥ƒ¥„ƒÆ_k™lW„bU¯„V°aôbnaVwmaōInÇmwkK@kmLUw™@™`ƒkÅ@ƒwƒb@m݄ĀÇ`U„ƒKUbmUUkÅxmm@›„»nUVk_Ý@™Ç™¦™VÇè¯b™aƒn™@@„„JV„°Žn„U¦™°ÆbXxWl„êƒxš„ĊaœbW`™zV°œ„@lmbÅx@bmV™bƒI™`™¦@ÒUVUI@ƃL@bš¼@ššŽ@„šlmxnL„°ULƒŽƒÞğޛ°kLUŽƒL™°™xVŽ„n„KVƒl@šzX@"],"encodeOffsets":[[106122,36794]]}},{"type":"Feature","id":"6205","properties":{"name":"天水市","cp":[105.6445,34.6289],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@UyȍVƒVUnn@ƒVU„`UblzšJnk‚@Vb„KU„°l„wš„„W°„nkVŽ‚UÈlš£°V@n¥šV„kl™kU˜±U„ƒn™ƒlw¯UkwmKUlmkUmnkym@ō@U„mWÈU°l°anlJškUKlU„¯Èm@kmWV»kkÝLUWUx±b™@¯ma@ƒ¯™IƒJUxn„m¼™K™ýƒa™V™Uݤóa™wLmxU@¯ƒUšƒb݃ƒ¹lmwmnXŽmJ@ÞV@UbVbkblŽ—@±êƒlI™l¯@ƒlW¦knÇJkm¥k@¯™Jmbóa¯bƒUV°ƒakXlšÅ`ƒ„„¦U¦ÇmƒLX¤mXnxm‚„ôšXša„VźUnŽUxlnlW„bššl@bĢV„ƒ˜nX„WbX`lLXk@Ž°KVz„Kl¤„nÞ݂Èkb„‚܁"],"encodeOffsets":[[108180,35984]]}},{"type":"Feature","id":"6201","properties":{"name":"兰州市","cp":[103.5901,36.3043],"childNum":5},"geometry":{"type":"MultiPolygon","coordinates":[["@@lW²LššƒŽ°I„l„šmbVb„KnbĊVlkš@XbÜU@Žkn°‚XIƒÆ™V„LšÓÞxŎUlôƒ„b°KzU`lXVaĊ¥Xal@šk™™Uƒ°ÑÈwUтV£ÈéVšš„@Vb„Jš@nnÜJ@b„L°„XK@īšóƒwlš@kÓmUÅmK@mƒ_k¥l¯™mkçǯ@nUƒaV™ƒwólXbm„™k™`ÛÔťèkkmÆkbƒK@U`UI±xUƒbWlX„mbVbÅÒólkƒƒIWJkšƒ@ƒz—KŻ¼™@™xUx󎃄¯LWb@ŽÅ҄„±¦U`nbťĀUšVb„LšŽ„U"],["@@ƒ¯lwna@mōȯK¯kW¤ƒ@@V@bĢnĢƒVLU‚°k"]],"encodeOffsets":[[[105188,37649]],[[106077,37885]]]}},{"type":"Feature","id":"6208","properties":{"name":"平凉市","cp":[107.0728,35.321],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ÆLUxÈxV°šLÇÞ@xn`Ü@X@nĊŽÆwnJmwUx‚aUkšw@V@w„aVmlLXÝl@X‚VĢmV°@nl@UUUWK@w„ÿVI²Òlmš@nÝĊýVV@nšJ°„„šUłm@kV¼nK›ĢȤôK„blnKllVk²aĠ¥È¯ĸóVw@V‚_„xšmn¦VWôX„ƒÆ@Vbn@°m@kn@@lšb@k‚aœ@‚wšK@™šƒ@UlKVaƒWX™W²¹lӄw@_°›n@@_lKōķW™@ŽmLUWƒn™»Û@›l_Ç`ƒÛmm°ÅbWb@š—VWbƒUUKDŽÅaġlmkUġlƒ»—Lƒl™Um¦@Ž¯U™¤ÇkVUml¯ƒƒX™ƒƒx¯kVƒƒLUa@ml™IkyVaƒ_UV@„mmUVU„ÇŽVzUxUVU¦ƒa™¤l„nVxƒVk„@ƒmKUnUU@b™˜U„ƒ„","@@@Žż@™mlkƒġk"],"encodeOffsets":[[107877,36338],[108439,36265]]}},{"type":"Feature","id":"6229","properties":{"name":"临夏回族自治州","cp":[103.2715,35.5737],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@š@ż»˜L„y„@l™XI„Jl„ôkÆÑUanaWƒXkW@™yk@U„ƒLƒmUšwš¯„KVlKœ¯Ġ݄݄VKƒ¯mKnw™k@ƒ™@™™»@a„K@ÅVJVU@њ¥š_Uy¯š@£UKmn@‚ƒšó¼ğ¦WmĵXݎkŽVLmVĉU¯bm„ÝV—wWlXÞW¦™xkmmL™šÝŽœ„±U@Vގ™š@„ÅÈW°X„ܼƨyUĮnŽWŽnXÝxUx°lVXJlôV"],"encodeOffsets":[[105548,37075]]}},{"type":"Feature","id":"6203","properties":{"name":"金昌市","cp":[102.074,38.5126],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@šĢȼ™„Çł°bœU°šV‚ƒń‚ÆǖŰnšÆ„ōĬǔaʠůĭš_kķÆ¥VÑș„çÜKšÅ@DŽƒVaU™m@aōnġÇk@ƒxĉ_™Wk£™@݃±KÈ±aÅnƒ@ƒÝxƒ@kw›lkwōL¯wm`"],"encodeOffsets":[[103849,38970]]}},{"type":"Feature","id":"6202","properties":{"name":"嘉峪关市","cp":[98.1738,39.8035],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@llĊx„¦šl™¦š„kVVnšJVbǖV„kôV˜a„bnaWw„UXmmamUXkWKō¯Xm°™™»ĉÇ@UVƒK™ķkǼğb"],"encodeOffsets":[[100182,40664]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/guang_dong_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"4418","properties":{"name":"清远市","cp":[112.9175,24.3292],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@lǯkÿƒaV¯™VaÈU„¥ÆDŽIlxšmnb‚Uœxl™„Uôl°kš„„Wl„š@ô™VwUanUl@„xVkšaX¥‚kU»„aš¯±@kka@ƒUwmUkwƒJk™˜„±k@ƒ™™L@ÝWUwV݃—xÇU¯ŽÇX@m™Åƒ@@yĉ£VmUwȗ»ÇšUn„lUnWU¯`Ukƒ@@„™x„Ž@bÇxX¼ƒVVš¯LšĀk‚ÝLƒ„¯@VŽƒĀ¯lnĊW¦kVÇôkUDŽUK@ţ™U@a™™ó܃UU»ƒ@™¦k@Vx„KVb„n‚š@„Æ™„l„@xšƒbWšnlU„lxÈlV„È°Æ„@¼™„@x„šWxœŎ‚V„šK°„š¥ššnƒÆkŎ@ÈÑm™„K@¥šk@™ô@„nôV"],"encodeOffsets":[[115707,25527]]}},{"type":"Feature","id":"4402","properties":{"name":"韶关市","cp":[113.7964,24.7028],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@W™Xk±Ñ@ƒUw™mUwĉwlmn@Æwn£mkIš¥ÇÅ@¥šaƒón£nWWwš£V`Þ@šnVml@xô¼„IV¥ƒkUmkamUkVWwÛ»móƒ£UVÅKmn@x™@kbmm¯a™Xka›VĉaUb݃ƒ²—‚lš„IlxnVVx@„lb@l²™°ƒbV¼lW¦™bUlƒwk@mVVbUxóš™@kƒƒX™ƒ¯lókƒVkš›wVma™nkwƒJÅȃ¦ÇVUbšŽU°„blĀ°ŽkÈ@x™¦Æܙ°@„°„¦óa™VUôlUlbXl@nÜV„„nKlŽnIVÞ°Wš„°U@bnm@¥šIVƒ²Ulƒ°VnalzXyl_Vyƒ¦lƒœLlxš„@ŽÞbšKm„knVWanwƒÑVwČº˜@n_ÞV„aVŽÜIœl@„˜KȚ„VJ@aš£È@˜™@km™„aV¯W@_ƒa¯KmbkÇkLmwƒ@Å¥"],"encodeOffsets":[[117147,25549]]}},{"type":"Feature","id":"4408","properties":{"name":"湛江市","cp":[110.3577,20.9894],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@@ƒkXƒ™@a„UUċlk„Jƒk„™@wVJXUWk°W@nKnwlUlš²ƒ„blU@‚lI„l@„XbW„šxnm@lW@w„wU‚JX¯VU°`ŎóˋkÝÝkÅ@ÇmğÈřmw™aĵV›xUہ»°™ĠǷnýmóX¥ɅĵҏÇ@°²ĊUĖ±ĮU¤Ç°™Ā¯ɐnżUĊĊĬV@脎@ԃÒU¼l¤nƒĠb„êVĠ°Èy„zVaV‚nUÆL„ašbVl„wÆ@"],"encodeOffsets":[[113040,22416]]}},{"type":"Feature","id":"4414","properties":{"name":"梅州市","cp":[116.1255,24.1534],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@„‚nԚlW¼x‚¦@lœVl™lLkè„a@zš¤ƒĖ„¼UxlnUKUbÝlU¼lb@„Vx„V„klJÈwV¯š@ĠlÛĖšnƒbkšÆźÞƒUÈôklmšL„¥‚LœW˜„„™nKUkVa°V„x@IVV@x°bUk„a™a@mV@„@y„w‚L„ÑUwVUšV„‚„U‚bÞVVann‚@XwÇÿš¯²aVamkXaÆ»@»nw@¥›UXaƒkbWa¯KUw@¥m@kwmLU»UU™J@kmU@UUWUƒ@ƒyƒanwmçÛl¯ƒŽ¯UƒmKUmƒwVkmÝXbW@XWÝbƒk¯@±‚w@»U@W¯Å@ƒÇ¥UƒU@ƒƒ™IU™ƒakJƒĀ„ꃰšþƒXkamŽ@Žƒ_J°m‚@X"],"encodeOffsets":[[118125,24419]]}},{"type":"Feature","id":"4416","properties":{"name":"河源市","cp":[114.917,23.9722],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@°VlmX¹laĢÒlm„@„„šVš£‚‚@¦Ģklynn¼lW°z„W„„°VbÈV@lÆbnn‚JškX„šVÆašÅ„W@™ƒUUw@ƒkaV»ÞkVaVLkmVwƒ»„ĕ™£@yƒblçkKkš›U@k¥‚wX»™kmӃ@Wn¯‚I„`@nlb„W™ý„¯ƒé„ÿlI@™XUmWUwƒ@@UJU„Ç„mKUV@x™„ţk¯¯LWƒƒnUxK@ű»Vwa¯š@¤WX@ŽÛ¦@¤ÇIȼWxXŽƒ@Wx—w›ŽUnVbÅèmVa±²UWl@Žk„lȄ¤nôܼXxlUnVlbVn„lU¦ƒJó»@wnkmU™‚Ý@U_™¤XxmXm¤„ô™b@¦Èƙ¦lJn"],"encodeOffsets":[[117057,25167]]}},{"type":"Feature","id":"4412","properties":{"name":"肇庆市","cp":[112.1265,23.5822],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@l@š¥„@V¼„Vôۚš@bšV@ŤVLȃlVÈólUX¥mĉ°k„ÿU°@„ƒÞKl™ÿ°KU™„UW»Èw@aƒšw@ƒ„@nm@w›£kÓVUVn„Kš™k¥™£Vamƒ@nkKkbÆǫma—kmLU¥™UmƒÛwmVU™mUƒJ—ÇaUxÇIn`mb@Þ¯b@„nJ@nl„U‚V„lVU„L›W¯—Û`Ç_¯`mš¯I™bĉWċzx±J™xš¯ÆUƒƒ_k@™šƒJ@Umb„šXôlLš˜n¦@¼ĊxlUXŽ˜xUbL‚Ġ„UnVĊwlšUš„b@lW„X„‚m²˜@ÞWxXš‚Unb"],"encodeOffsets":[[114627,24818]]}},{"type":"Feature","id":"4413","properties":{"name":"惠州市","cp":[114.6204,23.1647],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@lbšW°bnnlaš@@wnmÆLVUkÇlƒ@Xk‚V²±‚bnUÆçUaVmœ˜xXw„@WXwÇ»ÈJ@£Ü¥@XW@£°™‚bUx²¼@ƂLVw„mX„°K°Ťlšƒ@wVUnLȃVƒVIky±wkƒKU¯ƒÅkƒ™XġÑۃlwUwlm@m„nKWašÅm›¯óÇmğb¯alĉUwķbmb@lÞÒVn—šmĀŹ@VŽƒbVŽUnmakLm`@xĉkklVÔVJVn—lV„UnmJmaLUbl‚™zmŽkL™a™‚ō@@zš‚V¦UŽV²kJ„nÜU@˜VXUŽL@„lJƒL@bݤUnVŽ—b@xVnlK²„Vx°V„xlI„lkVl²k¤@n"],"encodeOffsets":[[116776,24492]]}},{"type":"Feature","id":"4409","properties":{"name":"茂名市","cp":[111.0059,22.0221],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@‚LnÇlk„KnkÆL„ƒUm™ÈxlUœJló°n@ššanŽš„„a@ƒ˜@X_@mÝóóU@a™aU¯mL¯ƒƒkV¯™ÇVwkw@V±Ŏ£@™™@šalw±Vk@m„Åm¯™ÿŃƧIÇ`ōô¯_UVW°IV‚ƒx@xkX@Žmn™wXƒWa@ƒƒkkJ@kVƒa±„k™kVmxmL@‚¯XXlWVUI@xƒš„lƒIklVȃV@b„šlW@„@nUxVblVxkôlx™n„‚y„šnIƻư„aXwlK„bVnƒŽXb‚L„¤„k‚L—èƒVV¼ƒŽ²IlĠVX„ynz°KVx°@VlœLlblKœš"],"encodeOffsets":[[113761,23237]]}},{"type":"Feature","id":"4407","properties":{"name":"江门市","cp":[112.6318,22.1484],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@lUXx°JWnnƚXVš„W„X@„šºVLV¯nU‚Vnb™ô„x‚aXmW™XIšŽUb°xlK„l¯œK˜xXÞ°ŽšXÈ¥Ü@„ĉޏU™‚çš»nóƒVma—x‚¯UÅU¥Ý¯@ƒƒç@ș@çĉÅUmU籃ĉKÝxÝ_ÅJƒk¯»ó¯nmèkǀšŽWxœ¼mnUÜġ°@¦@ƒxƒLkŽÇaVnUxV„™šVlnIlbnÆÆKX¦"],"encodeOffsets":[[114852,22928]]}},{"type":"Feature","id":"4417","properties":{"name":"阳江市","cp":[111.8298,22.0715],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@°„nKV°šb@bôVÞô@n„VlÒôÆUnlnn@lmkmVkƒaÈkÆƄ™k¥‚ÅÞ»ÆKXkW¥ÅLmÅkamJUkš™UƒVwUmÈbl„K„w‚@@¥Ģ¯VÛnm›»Xw™lƿ™@kbW™—aʵ@óL›l¯ƽ@™ƒƒLn°ƒÆ@nUl‚²kx™b@‚š@šō¤U²@ŽlxUxšÈU°lŽ„"],"encodeOffsets":[[114053,22782]]}},{"type":"Feature","id":"4453","properties":{"name":"云浮市","cp":[111.7859,22.8516],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@@V„Iš™l@„`V„°Å™šw²I‚wČyĊXša°Jn™°_È`Ü_°˜œX‚KVƒkUUƒVkƒ@mmI@ƒ°a@Ýnam_ÈJVwlĉX@„šlUšómaUmVU°UK™¹@ƒƒWƒXU™™WmÅXm¯IWwkVWlÅLݼÆl¦ƒšÅÅÇl„bUllnknm@kmVmóÅkуUW`—@@„ƒb™ƒm™b@™¯mkô›IkVÇwnš„VƒÅKmlƒLklmȁKƒšVĊK°²„`n˜¤n„U„bWl„xVx™LUx@°nXm`VklVxmnnx"],"encodeOffsets":[[114053,23873]]}},{"type":"Feature","id":"4401","properties":{"name":"广州市","cp":[113.5107,23.2196],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@Ș¼VxUnĊ¤@z„@šÆ@nÈW°ÈV˜w„ŽUÞVxÞX@ŽšK„šl@ބVaĊbœU@ml£k±lUƒkkJƒw¯UUw±ƒkLUm@w˜aUVmÞ£@a„KkI@ƒ‚KVUW@—ÛVƒmlIU±VU¥™@yğzƧǃƒšƽĠřšÅnī±m@ƒ²¯lƒ°@nÝÆóUll@XnÝVU¦mVV°—„V¼™Jƒn„b@°mbn„ƒ‚@²¯‚¯wVwƒ@@nmxX¤¯L@ŽVLU„m@@l"],"encodeOffsets":[[115673,24019]]}},{"type":"Feature","id":"4415","properties":{"name":"汕尾市","cp":[115.5762,23.0438],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@@‚„@VxnXWV@š„bVššJ„„V@ÞÅU¥Ċxš£UWU‚wÅUU¥WVUkĊÇnkV`°LV™„wƒƒnU@™„ƒlbĊ¯„Vnalšš@@çkUÝ¥ġaó¯ÅaÅLŻÆUýmy¯ó@ĉÆó„ȯw™ÆXbmLƒ‚@nknVxkx܄ĢҚW„Æl„V°„Ll‚²xlz"],"encodeOffsets":[[118193,23806]]}},{"type":"Feature","id":"4452","properties":{"name":"揭阳市","cp":[116.1255,23.313],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@V„Ȧ„Æ@X°V@@¼‚x²°@„lÞaWXX@‚aÞWlnUŽ„xVnnL„‚°V„@k‚mĢl@„ak™@mlk°aXƒ±„nwm±™²¯JV²@ƒwW˜—_mƒa„V»ƒU@m¯ĉUф™šJl™„ašbVn„lĸLlƅÛDZwÝ@ĉxó@è™@k™mbƒUĉ°kaƒ„@šmV„„ƒxUš¯KU_mlĉÈVlXUV¦ÆVxVŽVX™¤ĉwV¦ÝÆ"],"encodeOffsets":[[118384,24036]]}},{"type":"Feature","id":"4404","properties":{"name":"珠海市","cp":[113.7305,22.1155],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@„è@„Þ°V¦VƁ°˜wnb„UÆ»nçƏ@nxܤ²llU°VnÈJސ°UôéšķUklƒô£VVˌKÞV°£n¥ƒ£ȗ™Ýy¯¯mÅkw¯bÇĔğ@Ýn¯ĊƒVğōŁŻƒķJ@Ț","@@X¯kmèVbnJ‚™"],"encodeOffsets":[[115774,22602],[116325,22697]]}},{"type":"Feature","id":"4406","properties":{"name":"佛山市","cp":[112.8955,23.1097],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@Èb˜Ž„InVVšnUÜxn„šVV¦nK˜lnbÅǬlalL@mn„Ubš¤l¦™šƒLUmUVlԜ¤@xmnVl°_XVVmƒkVmș@kn@VƒUK@°KW£nw@m„@Ux°x°@±„mƒna@¯ƒa„mšIU»˜ƒU¯nUV¥ÞUWmk@Vk¯™Ukn›ÑWݐƒĊÛ@Ǧ™W¯Wݗw›Lk°ƒkL¯wVa™WJXšWnbƒwkVƒ™W@kĊ"],"encodeOffsets":[[115088,23316]]}},{"type":"Feature","id":"4451","properties":{"name":"潮州市","cp":[116.7847,23.8293],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@°ŽÜknèmx„b„z„@V‚VX@VnV@lšIVVV¼nKlxn@@¦Vx°LXbla„ŽWbœV°£¯™W@nW@™‚aUñVœwWš»@¥ŤÅUÝǓÝóV@ńǎkUVmƒIUwÅVWÇX¹›—@W„¯bkl@nlšƒb@‚kġŽn@l"],"encodeOffsets":[[119161,24306]]}},{"type":"Feature","id":"4405","properties":{"name":"汕头市","cp":[117.1692,23.3405],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@‚@U±°Iš±n²mx²ƒ˜@œWºXÈÆUVx„JUnlVȍ@ŃôUǔÞVçn»VyĢÛVm@»kaÝUǼóšÛÈķKċ¥X„¥Wwğk™ƒ¯@ƒwķKƒkUm™aƒbkš™IƒšVÒ°Ċ@n„VU¼ƒ‚„bn˜`X—„x"],"encodeOffsets":[[119251,24059]]}},{"type":"Feature","id":"4403","properties":{"name":"深圳市","cp":[114.5435,22.5439],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ÞLš„@xšbV„šVšK°™X°Kô¥Vw@anU„胐š‚lkĊl@wn_lKnbVmU„aUź@nÿ˜™UmÝѯUƒbk„@ÆkxŻ@™aÇX—wƒJƒƒ¯LķÝUĕ™ó™ĸóêWº@b²nmĬ™Æ"],"encodeOffsets":[[116404,23265]]}},{"type":"Feature","id":"4419","properties":{"name":"东莞市","cp":[113.8953,22.901],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@Ŏ@ššblKnšykVa‚KnbnIVmUƒ˜kUmUIUә„ƒçmV@bUxó¦¯LW‚¯š™L™UUƒ™a@w™ƒÝKğŚ™ƾ„„ƨÈĠy"],"encodeOffsets":[[116573,23670]]}},{"type":"Feature","id":"4420","properties":{"name":"中山市","cp":[113.4229,22.478],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@‚XœÒlmšV°ôÞÅ@m„¯°k„±‚@@aX¹¯VݏÇIUmV¯kk‚±Û£mw@‚Őmèżmô™¼èVš"],"encodeOffsets":[[115887,23209]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/guang_xi_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"4510","properties":{"name":"百色市","cp":[106.6003,23.9227],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@lklWXL@VšI‚l@XnJn@VUUalk@mK@kny@UlU@a°™„ƒUU@VmaU@Ua@UWw@ƒn@KmLm@alkšmnI‚m@an@VIUamWÅImwU@@a@K„X@JVL„UVmUaVkUa@m„@@Ulmkk°ƒUaVUlKXbVwVIkaVmUk@KVk@a„aW¯m@w„¥laœX@KmaškVmnUl@nxVKšInU@yVaVIV@na°KlxX@@_lmXšUV`VIV™V@„n@lšbn@@WUkValK@²yl@„„VUV@@K°L@KU@@UVaXIVVV@naVkVa@K@UUK@UUa™LWa—w@m@K@UVVƒ@mVUUVKnL„mVL„K‚bVK@UUIk›mI@mUIVK@IUK@VkLƒ@WU@mU@WmUk@ƒI@VƒJk@WwX_@amK@UUWkIƒ„ƒK@LVb@mVmakL@J@bU@Ux@xƒbmI@`ƒIwm@UbmKUaUWa¯UkJWV@XƒJUU¯LUmV@ma@kkamKwƒLUUmWVkkm@aVUUkVKnVVUmXK@UW@km@Ukkm@@W@U™kUy@I@aUUmbƒ¤U@kUmL@bmJU@Ua@wkLWWkL@Uƒ@VaU@ƒLUakKWbkUWVkKkLVLUV@JVbƒz@Vƒ„@ƒVmUU@kVmK¯@VƒU_™VWakVmIUKUaU@@bml@XU@@V@LmKUV„mVUKƒƒKƒbkaUXƒKUL@x@V@l@„mxU¦„V@ŽlL@V@Ln@@VV@„nlKUaV@nLUbmJnL@VWLkbmV„@@L„W‚„XLlx„VVIVV@x@V²blUVm„LVUœK@kWWXUlV@Xl`„LX„l@@VšŽƒn@VnbVš@lVUVUÈVbš@@`UXU`l@@XUVm@kš@xmVknUJVXUbmKULmbx@VlJ@LVbkKUbVLÇUUVƒUVmU@VaUkUKƒVUwmLkUUVVlƒbka™XmwƒKUšVVU@@V±Uk@VWUUm»XamU™bƒKk™`ƒ„™U@UnWW_kKmbUVUVmnUV@„nJVUlšUbU@UV@n@JmI@VmbnVUXlx¯ŽkKmnVV@L@V™bkV™Umm™@Ub¯LmlUƒL@VWLkmkLmmn£WmnKU_mW™š™bnbmxƒ@U¦UJU„@Xmlk¦@‚mnUUm@@Jn@lV„ÔVJnIVW„I@a„ƒÆK@I@aVK„IlŽÞnnl@nl`nbÆX²l@xV„@llbVn²ŽVVl@nn„V@IlW@Un@@kVa°KšnÈmVaVXUlaVƒÈU„VlwôUlynIVašan@lVXb‚Iš@n¥la@Kš_n‚@bÆx@XnJV„nKVz@`VXVšU`@bƒ¦UV@VšIlx„UnV‚K„XÈbšVllšbVbnVn@"],"encodeOffsets":[[109126,25684]]}},{"type":"Feature","id":"4512","properties":{"name":"河池市","cp":[107.8638,24.5819],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@lLVl„bVV@nXVlI@JVX„mšn„W°b„IVV@‚ln„@nalVUb„nW‚@kVkÒlbVKn²°bUŽlV²@˜X@`nb„aUI@ƒ°wlU@aXJVI@aVK@wUamIXm‚@XUV@@bV@Vm„ImnUUwVaVKXU‚nVK@akƒVwV@nL@UV`n@@X‚lnIUJl@X¦˜V@aUIVm@anƒV@UwnL@VlbVL@KVVXUWƒ„wUUVUka@UVJnUlbnalbVVn@°„„LV`Þ@šXVxV@@bVlUVVbXnWlXnmlš@XXWVXJmbUI@V„llUVkn@@VWV@Vnb„@VXUJVnn`lLVk„a„»lVšLnw@WV@lInw@WnU@U@m‚knUVó„K‚wUmUXUƒU@@wVJVIl@XKVVVbVI„J@Un@lŽVLnm„b@U@Ul@nUš°VUVJnnVJV@„@mVU@ƒ@wkUVwkKWk™yUUkU@alkÈ@lJ@x„Ilƒ@UUWVkUw@Kn@@kmaƒVUl™UUL™ÇƒUUKl@UUmL@aXU@mlUUwmKkUUVKVUƒaƒKUnK@U@Vl@XUWU„KlwX@šb@K‚@XkV@UwWJka@aUwmV@U™@@U@wUm@»kLWVkIWŽXnmV@VkbmKƒLUbk™Va@aƒa@@aVU@aVak£@ƒ±UkVU¯V™UUƒJVƒUIƒ@kxmUmWUbL›w@K@aU@@aVU@Kma@aka@_VWkk@UWVUKULWKULUš@KUnƒwVaUKƒxU@UmaƒL—m@kVmVa@UkƒmI@ƒ@KmIkxU@@K™U@mmakI@VƒLkmWkkJ™_U‚@V@L@n˜xXbšKVb@VVL@V@LUbUlmbU@UUWJUb@VV@@L¯K@LU@UVƒƒk@±z@‚kLUbVl@Xm@™akm@ƒU@UšUJU_™VWŽkn@`W@kw¯LmbU@UJUb@zmV™JULmwk@mVUn™lnb@L›Wkbƒ¦@x°nXŽƒb@bUl@LVlUnlbUJUxWakLUVVb¯„llkn@Vƒ@@nVbUlVbUnƒVUK@IƒW@L@bV@nxÆJnXVbUJm@@bnmJ™nkl@b‚nnK@L„m‚@Xx@VVbV@nb@UVVƒ„¯š@bkV@Vmz@lnLl@kŽVbUVm@mI@Wk™J@UWKkXkl"],"encodeOffsets":[[109126,25684]]}},{"type":"Feature","id":"4503","properties":{"name":"桂林市","cp":[110.5554,25.318],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@nU@J‚X@`XLm¦Vb`lšVXXWš@VblČnVšŽlanLnmVLšK@_Vaƒ¥@kUa„@VmVb„aV@XVVzlVVK@knKVmX£VKšLlbnš@b@llL@xĊôXaV@°È@¤„bn„V@@Wl_„V„U@W„nVamw„wVbn@„K‚VšLX@VmVUxlV@šnVV_nK@m‚I@Wn@@IšUĊ@@wVWX@@I°VVm@wmU@m@IUƒV™kƒlkUmmkÅV@@aV@@Wn_UKla@kšaV„šlVanb@k„@@KlVn@@aV@nIWW™UUaVU@™kKmwU@UImKk@UU@w@W@‚™k@™UkWƒ@mk_W@Ua@a™ƒƒ@—¯ƒmV£@mƒUUam@—kWakƒVama@UUm@nw@alaUmnUlVlIœV‚™šLVyk£Vm@k@UUJkƒK@kmKUw™KkWK@UXImyVwnI@m‚ƒkUlkUKkUVmƒw@kkJWUÈm@_k@@aƒaW@U„UJUwU@@IWKkƒmUUV@nVl@bVb@bU‚UXƒakw@ƒWUkbkKƒbm@™xUlkLm@@wmKUX@‚™UaVW™XVmU@@UUUƒxkmWXkKkUWaUaUb™L@`UL@LV`UXmK@VmakLVbkL‚xUJUIVbUVVb¯KƒV@Xnl@lVXbmÒnV@L@VWKkVUIWJkIƒŽUamUUbm@U„kU@JUbW@X„WxUam@kbVVUnUJmUUV@bƒU@UUV™@ƒVk@ƒbƒmULV¦U@V„U`VLUL@xVbn@UJ@nWJXXVŽVV@bkxVbUx‚Lšš@x„¦@šU‚lXUVVlULV@@šnŽU„ƒb@xl„nJVnlVknUlVUbmŽU@ƒbVš„x"],"encodeOffsets":[[112399,26500]]}},{"type":"Feature","id":"4501","properties":{"name":"南宁市","cp":[108.479,23.1152],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@lKnbnU‚@Ua@K„L„ƒlJVX@VnL@bW`Xxl@„I@U„Jl@nV@X‚V@nXV„@lK@UVL@JULVJ@nnJlœVJ@VULaƒLUKƒnmKULVVUŽ@nU„š`lIXlln„K@UlJnb@nšV@LV@lwnJ@L@„nJl„@VUbUn@l˜n„KnbVŽV@„wVLUb„xVm@LV™VKXLVKVLXU@VllUX@`lb@bnb‚L@ŽUV@bV@@b@Lœx‚KVanXVƒUUmVUUUaVUky‚UUa„ImK@mUUVUkKU_@W@UVVVIUW„UVaVU@UUKnƒ@k@al@ll@bnL@b„VUV˜X@Vœ@@b‚Knblmn@V_@aUalL@a@akK@kVKUKlwUUnV¥VmU_VWVIVaX@Va„alńK@LVJnalL@LnK„wlVUw‚mX@VXšƒlLUVnblaUmVUVwXU@Wm¯Va@ÞKnw@w™mšk„»‚UVW²a@_mW@U@I„y„LVUUKW@@™„LX@VUV@@yVU@UV@nwUUmJka@IU@ƒmƒVkaW@UwUX@`ƒ@kLWUk@mƒkUUm@k‚UUWkUƒkWxk@@VƒK@nV@UVaƒUUJmIkVƒ@UamLUbkVmamLka™@ƒ‚kmL¯WI@wJmwƒx@akU@aUKmbkaW_nW@_U@Wm@a@wkwUKmƒk@ƒbkb›w@mKUkkU@J@bW@kVWz@bVUa›VUx@„ULkJWbXVVXƒ`@œmJUVU@@Lk@WbU@UJlnXlm„Vx@Ln@‚b@K„LX„WJUUW@kƒaUVUbmV@nnV@n@lVLƒVmLX‚mXkV±@kxÅL›šUbJWIÅJ@I‚mXalkUamKkškL±aVwKƒUU@mÞnbWJX„m„@lbmKULWUUVkaƒbnn@Vl@VVV@VƒbVbnLWLXJWxXLV@@VV"],"encodeOffsets":[[109958,23806]]}},{"type":"Feature","id":"4502","properties":{"name":"柳州市","cp":[109.3799,24.9774],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ƒwU™„aV@nVaUVklmkUUmmIkƒ@w„aVƒm@™U@VKUkVUkWV@™ƒ¥@w™™KVwUalw@aUUUWWXI@mVIm@Ua@wVKUKV_UƒV@U¥VK„n„al@„Uš@VU@V„V@aVUnVVIVmUUlan@VbXwWƒX@Va@IlVVƒn@VanVVb„lJXIVJlUXL@U@KmUnÑWakU@mkƒJUI@mk™@wUmmUV@JXaWIXWmaUIƒJƒkk@W„nJ@„ƒaUak@›kkJ@kUKU_ƒ@myUóWUkm¥kUmL@KUKm@k_UmVa@ƒk@@UmU@mm_—JWIUVUŽWLUlbVUJÇVUIVwƒKUVk@mU@n@lUL@Km@@l@L™VƒzJmUU¤m@UbV²U`U@@¼Vn@x@Vš@@VnUVx@blbXIVxU@Wl@@L™aW@kxƒLXVWVk@@U@VmLVŽ„L„bUVULVV‚lnLVxkV@nWV@bnKVVk@VL„VšÈVKšVVk„Unb@lm@@LVxUlVX@Vk„ƒJ@wkIÇ@kl@blVVVšzXllLUxlV@x@„UV@nƒ‚U@UImmUIUV™¯mVk@@V@VƒamnUKkm@@VƒIUJUaUUWLk@UJUI@xV@V„VWVnxƒLUômVV„@VkVVVUnV@UVkL@VVV@bVxla@bkXVJVn„`nU@bƒb@bVL@VnJ@„l@šV„aU@@_lW@UUU@Unƒlll@XLl@@UX@°bVWVanLlknVV@VVX@VVƒnUŽVLmbXJ@nllXX@`VXƒlmaXVWk@Wkƒw—J@„VL@J‚bnU@bn@@bVKUnVJVIVVVL²a@bV@@Vl@nUVakalmš„UL@VUL@V‚a@mXl@nK@UlK„L@Vl@@nkllb@š„Vnn@‚šnV„™V°l„šVInwlKXxlU°Žn@@ƒ‚I@UnVlakUJWkUK@anUWK@_ÞJ@U"],"encodeOffsets":[[112399,26500]]}},{"type":"Feature","id":"4514","properties":{"name":"崇左市","cp":[107.3364,22.4725],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@@JVzšl@V@Xn@ll@VlnX@@VWLnŽUVmUULVlUV@blnUlnXVV„K‚xnLlb@lnbU@Vn°KVV„I@WXUlI°VXb‚VVbnLVan@‚x„J@_nJ„a@wVwV@@a@IU@UU@WKXwWIXKmKUa„a@U‚UUUk@@Umm„albVUXVVKnL‚a@knƒWƒXImanÝV@„V‚LUx²blKl™nLVbklWbn@JÆIXJ‚IVaœ™ÆKlw²@lUnWWnK„UUK@k@mmU@mnUVaVU„b@lVXVXIWƒƒK@Lam@@KUwnƒWkkmVIV@Xal@@KV@VUnI@›„_UWWUkam@kkm@ka@mƒk@wkJWIUU@WXkW™XkWWLUUƒ@UakLƒW™XV±VIVWUU@anUWaUK@IU@Vak@@UUKWaƒ@m@ak@@wUkla@mUaUklakwVƒ¯¯@WWUkLkKmaƒ™kLUnV`UxWX@Jkn@bmlƒakkk@ƒb@l¯bm„ƒbJ›b@VXn„bVV@„ƒbƒJUkkKWVU@mœÛVUUW@UVUJWXkVkKmUL@WW@U„Vl@XXKW„XJ@XVlmbUxnnm@UlVnV@XVm¦VJb@šmLkKÇbXblVkn@l@bWnX`V@@IVV@ŽV„V°n@@_naÆVVbUVVbUJnzlVUl‚XkV@Vlx@X„VnxƒbƒKUK@b¯VVUV™L"],"encodeOffsets":[[109227,23440]]}},{"type":"Feature","id":"4513","properties":{"name":"来宾市","cp":[109.7095,23.8403],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@nVlw„@VJU„„IVVUšV°lU²V@„l¤Ub@bUV@b‚@„b@bUblšVa„KnLla@UnUWmXlJXUlKV@V_U±Van@V£nV‚I„yšU@K@kn@@LVK@k@mnVl@VU„LUxVJÈUVIU‚aVkXKVVUXJ˜In`@nnV@Vl@@„UbVnl`n@VL@LnKlVn¦VlôXV‚nz„@V`VL@llIœll@Vb„b@ƒmIXƒl@„l„IVJnbWXXJWb@IU‚nVVn@xlš@nVJ„I@W„U°LUaVUUaVJVIwlKUalKnb@UnLVWU_@KVK@_šKVa„@VKU¯VLVKn@la„aUkU@maVU„J@k™@Um@XmbkyVaUIUU@KV@laVn@KXKWUkUk@ƒaW™UUVw@aXKmƒVaUUkšmIƒlUU@wUa™xUmmU™¯™U@WƒLUmVIUym@UVmUa@wmw@çm@aWLU„™JUIUamKmL@™aƒx¯¥ƒkU¥U@±„k„UVmKU_mJUbkKm„ƒLÅǙ_@WWUXUmaVUkK™„UWW@nVxkUƒxmL@KkKmbUI@KƒLkƃbUbW@UbUJUXV`UnU¦mŽVVkxVLUL@llL@b@bkKVb@bU`m@knmaL@a›@@U—WVUƒU@amK@akkk@@b@lm„VL@VUVUbƒVVXUJUU@V@XV`lLUVVV@nnLƒJVbVlzUVVbVVnUVVU„"],"encodeOffsets":[[111083,24599]]}},{"type":"Feature","id":"4509","properties":{"name":"玉林市","cp":[110.2148,22.3792],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@VJUXVVXlWX@V™xVnX@@`ššULWŽUXÅbWK@mULUUmJ@n¯b@l@VULVx„x‚XU`VXXJVI„V@nm`@nUŽVXn@lWVn@b@Jn@nU@Lm`@Xn@WJƒ¦U@@VnL„lV@@Xl`nIlJnkVL„w@KVK@UšaVL@bVKX™lUUKVK@I„VšL„a@U@WšLUlVL@bU@@blb@VlbUxVbXUVJ@xVL„U„lV@VU„bVLnKl„XJ@L‚b@an@VanL@`VLšKV_UWl@U_„a@WVInlVUUUVm@I@W@wVakIWm@U@ƒXwlaVbnI@ƒm»Va@aXaVLšU„»@aVa@k™KkL@KmU@WƒzUK@wU@VWUUVUUKUa@mKmbUK@_nWVaUkVaUaVUVLXKVƒVUVmVI@UkKkLm`UkW@UwWW_„UaU@WakXmK@xUXƒJkƒUUWUk@Wl—mJ@km@@aUKzmyVk„a@kkWVUU¯lmU@@w‚kkmV@Vk@mÅIƒ‚Ukƒaƒ@Ub@m@UUU`mUbWaWmb™X™XKWIXUWm@љ@y@UkIUJUUWLUWƒL@UkVUxW@kaWbKWnXxW¦n„m`XLVlUbVbUx™I@JmLUKUb@VW@@bkL@b@VlU@xkš@L@lƒxXxWXX°V@VVVbUVV@UVVbULVnVJUb²b‚aUb@VVVVInlV@VnXaVUšlI„VUb"],"encodeOffsets":[[112478,22872]]}},{"type":"Feature","id":"4504","properties":{"name":"梧州市","cp":[110.9949,23.5052],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@VbXblVlLXWln„wVV@VV@UnšWUXVbš‚@VWXa@kVK„UaVaVkšUlyX@Vaƒ—VmUwUaVU@UÈymI@aU°@š™nWV@VaVaw@IV@VmnLVK@kmmna@™„™VbVI@aV@XbW`U„„LUVVx„@VbUV@bl@VLXblJn¦lL„°°@n™@K@UlLnK„a°LWbnJ„¦UÒV„UllLlVnKnbWnn„V`„w‚@@Xa±™n™l@XKV_„WVkVa@kVyUa@wU£UW@UIVW‚@@a—wWaX_WKkVmUULmak@UJUI@±m»™—k@m»VyUIm™nmmwnkUmVaVIUn_mW@»Vk„@VwkmmUXa@IƒaVm—mƒ@Wm_U@mIUWóLmUk@laXmmkUK@UmKULUUmWULƒ@VakU™@Ub@bƒ¼™VUKWb@bUbn¼@„mJUakbWx@„@VXnlJUb@x@X@JUnVVUVmkUJ@XƒbV`k@VXU`™LUK@_mKUbm@@b@„U`@nlV@b„UnbVbn@@`VbUbVV¯bm@@mJXb@bVnUllVXUlbUl@LU¦VVmŽkLVb@b™l@V@XlK@V@nUJUz„°mŽwmLmlXbWVU@UUUlƒIU@VVmV@@¦‚bXbWxX„WlXVWL@LUmkbU@@LVVVJUblzna@WVnš@@lƒIUVnbV@Vlƒbkbm@ULUKV°ULƒ@"],"encodeOffsets":[[112973,24863]]}},{"type":"Feature","id":"4511","properties":{"name":"贺州市","cp":[111.3135,24.4006],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@nL@xn@lKVkšwn@„alLlaXV@„lx„bVWV@aUa@aUk@mVUnVl„XL@JV@VxVIVƒX@„b@bl@@`ÇnXVlI@l„xUnlVVLkllV„@nmJUxnzWJ@VXLlŽšLVxnL@l„LlŽVI@V@lUnl¤Uz™Kš@„Vl@š„L‚l„Lnš‚b@VnVVU@k„a‚Knxn@VkVJ@ńUlakmWIUaVanm@_UK@UVWUa@klXam™U@Vmƒ™VIXW„@lUVknVlKVLXŽVXšW@b@VlšnnVL@KXL‚Kn@lb@UnW°@Va„X„WVb°aVa@I¯aUkUaVKVwƒaXk@a„a‚™@wkm@alanUVw@alK@Umkw@UƒaUmU@WXUaUK@UW@UaVWI@¥Xa@w@WWšVƒXwƒU@mKUXUWVU@a¯kl@akU@UULmK¯VUVW@U_m`U@@xVbUz@lUbUlƒXU`WLk@mš²šWb@Ž@ƒxU_mƒXmmamLkUkKVkUƒVу¥mIXa¯KƒbmLkK@V@Lmš¯@ƒ¯kKm¥kIWaUKk@@aVUUaƒ@UwVUƒKVƒX_WaU@@bUJUaƒš@šmbnn@lULmKUnU@@J‚xUbUbU@mX™š¯@VŽ@bnJÇz@VUVVbVxUn„˜UbW@kz™VUlUbVbƒŽUL@lWb"],"encodeOffsets":[[113220,24947]]}},{"type":"Feature","id":"4507","properties":{"name":"钦州市","cp":[109.0283,22.0935],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@@IlVVlnL‚@œxla„al@n„VLlx@x@bXnV@@`mXX`lbnaVL@blV@b„wnx‚I@xXJ°nK‚l„š@lbnKnblUVanKVb„@lUnJVI„VUb@V‚U@m„L@Ul@Xw„llVVXV@lVnlVn„l@XVlK„@@_VWVxX@lb„U„nV@@JlbnIlmnVV@UwVK@U@k°a@mnIVVVK@nXLÆaVWXVK™™@_W@Umšw@UXWWkUUVWUIVaƒUkJ™UVWbUmU@mkUJUU@UVab±aVaUIUmVKUaVUU@VUUaUUU@W¯XWWw„w@k@Kl™@wkV@U@alK@aX@@UmIUWUIƒ@mmkXU`U_WJUnUJmUk@@amLU@UVW@UkU@@VƒbUWVUk@@wmKkUWLUWX@JmIƒlUkkKWKkLWU@UKWa@bU@@a@_UKWƒUUUmJmw@nV_@ġğKóLmbU¼VÆ@xUXƒ@Um@wklVnUn›lkaUV@„lV²WVklWXXbWlkVkIm`UUƒLƒUU@UWƒx@XU@@lWLU@kbUbV`UXllUV@bmb@LnKVbULm‚šnVVIV`X@"],"encodeOffsets":[[110881,22742]]}},{"type":"Feature","id":"4508","properties":{"name":"贵港市","cp":[109.9402,23.3459],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@n@VzUJ‚nVŽ„K@XšVš°nVVnšwVb@xVV„knJl™VVUbn„WL@bUxVVXš„bl@lVXkWƒXwWaa@¥‚@nUUUV@„JVkVVV@XUWanknK‚xnƒ¯VyVI@m@UkL@W@Ušk@aUalKnUUV¥@KVkkaWVkUVkUm@aWanI@n@°aUUVaUa@_m@UamaƒV@akU@mV_@ƒa@KWIkƒmLUKƒaUVU@ƒkƒVUK@wUIWVUaVwka@Uka@aV@@aUKVk™K@X@Vƒb™KƒU@JULVLkVWšUL@aUK™b@VUL@LƒxUKmlkImJk_@WU@ƒkmK@UV@„¥XIm@@Wn_@KmVm@@I@aUmkXm@UWV@mn_@mƒUUJWIUWV_WƒwU@mUknVVmxU@@VUV@zU@UVW@ƒK@šX@VLUVƒKƒz@J@VnX@`±bUXVƒ¼™lšn@xmxÝL@‚Ubn°@XWVUxUVVnkbWVXV@Xš`ÆȄKnƒlLVanIV`nLVUlƒ²ƒV@V¦„l°¦„w‚b@šnKnLVbVJšIVƒXK@b‚n@ènx@xVbUnV‚"],"encodeOffsets":[[112568,24255]]}},{"type":"Feature","id":"4506","properties":{"name":"防城港市","cp":[108.0505,21.9287],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@XV@X°°U„lxkbVlVb@nkbVl@xl@@b@n„‚XbVL@Vl@UbV@@JVLXbmV@bVVUXUJU²šW„XlKVb„@VVXKlXšWlXXWV@VXJlI@x„l@nlbn@lln@lbXalIVK@ƒVwœUVb‚U@aXylUX@@aW@U_UJmU™nVKUamL@Kna@aVUkkVWU_ValaV@XK@kV@@W„wVXV@„V„KVVn_lJlUXkWaXWlkXU‚±kU@ƒVUlbœkVmUmlk™¯Ý™™W@mb@¦VxULm™kJUU@ma¯wƒmkX@VóJ±bUVUXÝWk™lWXXlƒxUaƒbƒIğ™Ç@U@mVUKkkm@UJm@XnWV@x"],"encodeOffsets":[[110070,22174]]}},{"type":"Feature","id":"4505","properties":{"name":"北海市","cp":[109.314,21.6211],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@VaVLnK@IšJVwUaVaUkWKn_mƒX¥WwXm‚LXalbU£UyV„Å@ݙwm@™°l›LÅUƒmk™mwÛaƑLÝUUm@ȣƃV_„Ó@£UƒƒUVƒ„™¼U°W̄™ÞVbXbôx@b@bmV@ǃ™UÝ@@ĢU`m@ŽnxnIVV‚VX„VL@`@bV@@aXbVL‚@XVlKXLlLVl„knJ@I‚WVXXKlVnL@xl@UVVX„a@UV@VlX@VUV@nK@bl@nVVIVmXIV`V_lWnn„@VJVXnJ"],"encodeOffsets":[[112242,22444]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/gui_zhou_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"5203","properties":{"name":"遵义市","cp":[106.908,28.1744],"childNum":14},"geometry":{"type":"MultiPolygon","coordinates":[["@@@UnUlJn„w‚JU°VL@bnVšU„wlJ@XƒŽXVlU@klVUJknl„UllL@bUJ@xULUlƒ„UblVkblbnw‚UXmla@„wV@VK@L@UXaVKVLXWƒUVa@U@Im@@W@£UKUakKWIXU@al@@llUnL@W@Un@@VlUV@VIUanKl@Xb@lmxVb@b°bb@nlJVVnnJ@b@L‚V@ln„@LmV@Vx@blnVK„nlJXIlw„J@҄b@nlK@Un@UL@VVVVUUUVK„l„@VUVL„J@UVUUw„@Wm@™„UV„ÈVlbUb@JšLlŽX@@x„„ƒLmŽk@@nlx@bUJUzVJ„@@LVxUV@bWxnLnVVK@_‚K²xVbV@n¥@aVI@b„@l@Va„Knb@n‚`n„mmý„W@ƒU_šwV@VlVV@Vn@n„˜@nI@Jn@°¦VaUU@™„mVVWVaUńU@aVKnƒVbVUmmU@a@kUw™m@aUUmUUJ¯lakU‚aXaWUUaVƒkk„amkmUnVlULƒVlJ@XU@UJWUUw„k@aU@WbkWƒL@U@WU@@XUKmV@aUVwUĕUJUamUUVUÑm™nIVJ@kl@XalJVn@KVLœ¥@UWIXWmU@mVUKnUWLUKUaWUUKVU@U@anUny@UlUkK@w@a@aVUƒ»UkVw@Wmk—JƒÅmUUVmwXalLXWWUnam@XkƒJ@UVU@U@W„@@U@I@Wl@Ènlw@KXLWb„lVUkalKUU„VVaV@@wnIlaUmkUƒKWU@KkUkLWaƒKUUWUn@VƒK@LnnWJUIƒVkUWVnV@V™@@XƒK@VUIUJ@IWJkX@VVJ™IƒVkK@I@UVaUWk@m„@wnUWKk@mxk@@„lV@b„xmb@x@VUmLkUƒJ@nVV@b@VkLVbU`¯I›l@™U_UW@UU@™™ƒK¯wm@™xƒL¯¥kIƒ™ƒ‚@bkbƒ@Ua@ƒm@kkW@XVbmV@ŽkV@bWbUbV@„¦ƒxXlmVk@ƒ¦™bkaWL@KUImK@wUK@VUI™b@bmK@LÅy@akXW@kbWlXblL@ŽULUbƒ`@U™kUymX¯@mšUJUUJƒL@Lm@@WX@lU„VlšXll„@l@Èk°V°Ž„X@VU@UVll@XUJVXUVm@@VXLWlnV@Xƒšk@mVULnxV@@bm‚kL@VWLUbU@UVm@ƒb@ķ¥UnmJ@UUVƒkkJUšlÔU`UIW@ƒ°kLUlUI@WVI™U@mWKkXk@ƒ‚WU@bXšW„@J@xX@l@LVl@xšLVxXX@x‚KnxVknb‚KVV@U„L„WlXU`@nUlšX@llVXšVU„KlkUKlI@anKVLXKVaUIVWV_VK@VnLlU„»VKVL„m"],["@@@KlKkUUVVX"]],"encodeOffsets":[[[108799,29239]],[[110532,27822]]]}},{"type":"Feature","id":"5226","properties":{"name":"黔东南苗族侗族自治州","cp":[108.4241,26.4166],"childNum":17},"geometry":{"type":"MultiPolygon","coordinates":[["@@VV@XkV@bUbWJU¼Vb@Vnb@bš„@J@bƒL@LV@UVƒlUI@a™KULVb@bkJmx„šlLVxknVJk„‚xnKmnnL@bn`WIXlWLU@UxVbUVmKV„XI@JVIVJ@U„L@Wš@@UmUXUlV„UVJXImm@K„L@UVmVXV‚„LXblKlV@LXV„LlVVnkbmJ@xnXl@šbXa‚@Vana„ÒšL„m‚VnIl‚Þ¦°k@b„@@lV„nJlUnš‚VX_„@lVlK„šV„UUxVLVWVIXJšUlnnWlI@KUaUUVKn@VaVXV@na@ƒmw¯@mUkJUamI@lk@@am@@I„ƒUmVImUUw˜™@anUVaUU@LU@WaWUXWW„wV@VwnU@L@ynbl@@X@a„J@nW@@Vn@„lVLlxnI„lš@@UWKUƒnIlJXIVllIVVš¼XK@aVI„V‚@@bn@VKXLVKVVVInw„J@UWI@mX@WKnI@KmU„UVJUL@V„KW@@k„@aU@@W@InJWUXwWI@Wƒ@¯wkaVaUIl@nŽValIXWWI@UUm@anwWkXWWIUbk@UJmIUamKVUUUVVama¯VkIVVUlKnXVwX@@WVaUUVa@IlƒaVmƒkna›wk™UU@ƒU@mUVƒšUVwœl°LVbnJVU™¯la@mX@@UWKXU@aV_V@@JlkUƒ¯@V™nK@km¯k„U@ƒWUW@mmƒU@™kmlU@wkL@WƒUkL@VmLƒJ@b@V@bknUUVK@UVKUK@Uk@Wa@LUVVnUbmVk@@UU@@aƒV¯K@U@UU@WmUL@aU@WV—w@ƒ˜I„xXll@UX‚K@KXXVJna@wWaƒ£naUKV„m@UU@mUmalm@@XkVm@U@VƒLmWU@kkWxU@@bVV@VkXVlƒVƒ@UUk@@ƒmI@KUw„m@UmVƒUUwU@lwkV@IUa@mUaVIVKVa@w@U@™UJkb@n@bmJ@XmlVUxWXkJmUkUUVW™xUlU@ƒaULUšmbU@@‚WXkmƒL@xUV@nUxÇm@„XLWbnlƒnV‚nnUV˜U‚nVVz„@lbUVVlULVb@V@nUJkwm@Ux@bWbUK@UULka›JbƒU™U@U@lUK@XUJmn™J@bU@UwWa™x@zkJWnUJUUVšVV@bXn@xVb@J™L™m@X™w@`@bkb@VmXUV¯L@mW@@n@V@‚ƒL@K—IW@@aƒaUx¯@U„m@XbW@@L„V@bnVWVkKUzlV@bÆa@lnI@VV@@LnVVKUaV_VJVbnU@bn@‚‚nX@yVIVxXKVLlUVaXU°J","@@@KlKkUUVVX"],["@@UUVUkUmV@ln@VXVK@K"]],"encodeOffsets":[[[110318,27214],[110532,27822]],[[112219,27394]]]}},{"type":"Feature","id":"5224","properties":{"name":"毕节地区","cp":[105.1611,27.0648],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@UkVƒ@k‚W@Xn@@K„KVIVVIn™°@nWVzšl@V„_VaVK@kKWaXklaX@lW@bÆz@KnL@ašaVJ@UVL@xnLVJ@LXKlbša„¥l@nUWk„wƒ¥U@VaXa@amLkUƒKmƒ¯kƒmkIUaƒKUIWƒkKm@anw@mlwXIƒmƒUk¯@a@amUƒ`kkKWVkxmUUak_mJmw@w„mXUW¯X›_@WnI@aVwkWWýŃU@WLkU™aUbVV@lUVVnm@kUmV¯™kK™LƒwmVUUaWV™aaWw¯wƒÈ@VULUVUUƒK@nWJkI™l@Umxnbm@kbUJƒa¯bUbVxmLUV™aU@VUUWxkVVV@bUV@XWbnlUbƒbUJlbUV¯b@z„`WbXnmbƒaƒwUwVWUƒbUxmbU@Uam™@Vƒk™VaƒwVaUƒWI@mUKóz@lUlÅ@WIƒb@xXxml@XklULWKUmwUa¯KUXWJkaULmKkLWbkKUVƒImƒƒWa@kUaULƒW¯LƒK¯@kbƒL@b™x@J@bmnnlUšlzU`U@@Uƒb@„m‚n¦°bU„Vx@bkVm¼mx@mk™mVV@bkxVn„aVV@bU@mL@b²`lIVV@lXLlš„bVxn@@bl@XllIVšnbVšn°°wlbXw@mVa°lVnU@mš™VLVbn@@b„@@WVnUV@Xlxn`VznJVb@L@bV`V@šUnwšU„@WUXKV@UUlmUUlaXalLšm„bšIVbnJVIlVVaUUnWVXn‚VL‚k@ƒnWnblnlb²x„xVKVXlVXLVW„LlUVJna@wVL„¼@JVX@`@nnx@nWJU@Vx@XXKšŽUblxUš°„LVKVVlL@KnbVUnJ„IlUšƒnKl£VW„x„IlJ@nšVÞUVVnb‚VX@V_°lnK","@@@UmWUwkU@Um@@VkL@V@„„‚V„VkV@nbVa@ƒ"],"encodeOffsets":[[108552,28412],[107213,27445]]}},{"type":"Feature","id":"5227","properties":{"name":"黔南布依族苗族自治州","cp":[107.2485,25.8398],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@‚V@IöalK@UV@@KUaVIVVœLlaVbVWnX@‚@LnUlxl@naVLXVVaVU„J@lUUanWWI„@VlV@Xbƒb@V„n@VmVVbk@kU@V›V@X„J@zn`ULW@kK@_WVUK@LUb@Jlxn@nnWlU@@b„x@XVVU@UbVb‚@n`VI@VVLUlUIUV@KmL@VV@XIV@@lVLVmXV„@WLXLW@U`šnkb@Vl@UL@VVV„L„llX@`lIXb„J˜IXW„L‚aVL@ŽXXW‚Ģ™b@bmK@L@°@Vnxmxšn„K@xVn@VkL@V™Lƒakbl`VnnxVnUlššV@@VVXV`@šœk°JV_UalK@U@aUU@m„IlVnK‚V@U@wnaƒw@akU@ƒl@nwl@XLmV@xnƒl@VXUb@V@JlL„UšJUI@UlWUƒnLVUUaVwV@XKWkXJm_@amKnmmLwlƒUIlmUwkKƒ™nwlI@aUaVKšL@bVJ„kVUU@@K„K@a@I™ƒ@ama@UUaV»XIVa@alU@WUU¯IWVUbkVUKWLUwUJ@zmWm@@amVUaUIU`VbULmU@KU@@UmJ@kÅb@akUVylLXUmU@aƒU@KX@Wan@Vƒ°@Vw„b@bX@˜J@L„K@@U@mX@@n°KVUnW@Ula@a@_šx@WšnšK@IUa@wWm@aUUU™VVVIXmlI@yšwXbVxV@@ašInmVI@WVL@k@VšV„V‚aœIlbVK@VVLXa@aVwn@lxVI@m@UUaVKUkVUkaƒ@UymUV—VUmmU„mmkXaWK@ƒÈnVw@mVU@w„KlnXW@V@naV™VKUk@KVIUWƒ@mk@KXU@Um@@lVƒk@UVJna@UWaƒL@a@ƒXa@kmmVUUk@mkkƒamJ—ImJUUmIm±aUUkambkamVUU@VlbUbVVƒxX„WVUU@VUakU@UmUV‚U@mnUVVnUbVJ@b—UW¥kLVamVkUaWJU_UVWKk@@nl„UVVJUXm@Vm@UnVlmbnmJUbULU@@UUKWVIWxnJVb@xUL@bUJWIkxƒbkb@xVJƒbmU@kW±LkKUkVa@a¯am¥ULkalÑlKXUWƒXƒaVakImVƒ@ka@UUƒJ¯aƒX™mmb—KWU@wUUƒaUa™KmU@UXlWb—¼WLUKUb°„UlVbkbVL@VƒšƒJ@nVlUbUXmJ@VX@lbUbU@@bWb@VnLVJ@bVVUz„ŽVL@lnL@b™VVVULmKUk™Jkbm@ƒxVb@V—kƒKVnnV@b@ŽWXU‚„nV„l‚VVXVJUXlVXbWV@VU@Ubk@@KWbUUmL@JnXV°XJ@_‚`UbkXVVlÆkbƒ@VLXVV@‚V@k„KXX@`V@@n"],"encodeOffsets":[[108912,26905]]}},{"type":"Feature","id":"5222","properties":{"name":"铜仁地区","cp":[108.6218,28.0096],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@°a@aÈbVUlU@aVKnVV„VUlyX¹lWVa@U™VƒnUVU@m™@mUl@„mÞw„@‚xnIVbna@KVI‚J@kwV¥ƒUXÇVkVW@kkKWU@aXUWmnIVa°VXbmL@VVbnVVVUb™VbšJVbVKXkVKVanU@aWnWUWa@U™nk@mVIVK@wXxlLXbVJVlKœbl@VI@mšaXalVV„VbX@@ašalnkx@b@V‚b@Vnx@bVVUXn¤WXn@Vl@Vlzn@š`@I@KUU@ƒV£namVkXa@aVK‚nnU@anVlKƒa@UUU@amk@»kƒU¯@aš„VWnkWmkImU@akaVm@»VUV@UKnkW¯XWlkUKnIWaš@nmlIXmWUnwUwWm@wULmaUJkIUaƒaWa—klwkwmJmU@bkJ@XUJ¯W@XbWbUKUkWJUUVKnn@UmmXUWa@mU@@UI@WmXVykwm@kaULWwU@¯ƒlKUUVU@mU@UkmaUbmV@b—š‚xVnVUJVnƒ„@Jn@@bl@@knJVblInV°@nx@„mbU@UWUbm@ULVVVb@LkJmXkm™VWIUJUXUKVwƒV™UƒŽkLkUƒ@W`Um™kVmIUƒ@kƒ@@a¯lÝ¥kmJUƒn™KƒÑmbUb@Wb™ak@mWU@UbƒUVVkLlbUVƒkXaWK@LkxÇmk@@X@J@Vƒ@@X@VUV@V„IWln@mbXVWXkKWbnxVUnV„ƘInl@XUxVl„¼UV@b@b@xlLkV@VmzmV@b@VUVVLXVVbVLXKmVVLU‚@nnVWXXJ@V›¦UK@LUmkIWbk@@lUImJnšVÒVUnVVbVIVĖUxV‚@bnUVL@WV@@X@V„KlXXaV@@bƒlVxXVVIV@@WkI„UVKUkVmlnnŽƒbllU„VbXVWbblVkb°ŽVInVVV@bšnVx@l@bnVVnUŽUam„UL@bƒVVÆUbUXU‚ƒn@šVVUb"],"encodeOffsets":[[110667,29785]]}},{"type":"Feature","id":"5223","properties":{"name":"黔西南布依族苗族自治州","cp":[105.5347,25.3949],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@VL@Vl@@IXW@kVUVbnW@XlKVVnU„VlL@b„aVbƒb@xX‚°ÔUxV@kbm@VxkxWJœ„V¦ƒŽ@ÈnšVKšxWXJmV@n„Ò@xVbn@@blLk`VX@bššla²JVUlnn@U±lw@wnw@mlwVIX@@m@klKnk‚a„KnwmmXkƍVm„Uš¥l@nb°n@„aVwVmVIVnI@a„¯@mšU°ƒl@@VnI@JV@UV@b@IUbVJmXöºƒzllUbVa@aXUl@„U@llLnKVaUa@UmK@UšwV„bnKV@VwVK@UXƒV@Vbn@‚w@U„WnX‚@„a@m„I„™@UUKlaUaVk¯ƒVaVLXK˜»XaWk¯mƒkğwmW@mIƒVkwƒJUIšÇVwU™UkVKkƒm@UkmU@WÅwm£Vƒ„m¤¯IkJWa™_™lUbmJzÝJk„ƒUÇVU„ƒ‚@bU„Ýn™m¯LUb@`mL@VkL@VƒUmmk@UU±Umka@kUƒ@ķymUkk@mmkÝmUaUakImV@V@VÅLƒ¦ƒJUXmJXšWb@n°Æœx‚¼nV@LlbUŽUbmL¯@ÞbV¤nbVx@bUVlblIœ™@KVVUnVJUn@VlLUlmLUUUxmK@I@@VW@@bU@UJmUkLVVUl@b@V"],"encodeOffsets":[[107157,25965]]}},{"type":"Feature","id":"5202","properties":{"name":"六盘水市","cp":[104.7546,26.0925],"childNum":5},"geometry":{"type":"MultiPolygon","coordinates":[["@@ôyVL@nXJV„Ub„x‚bUŽlšU„@ŽšnŽVbV@naVw„a‚VUXVx„x„bnaWmXaƒ_@y°aVUkaVI„aVamkXa@WVU@aUUlUXwVV@UVšbVUnKUwVa°a„bVIlan@manw@VšklJXI@m„LVVVUVK@U„ǃk@KUa@UkaVU@UVWV_XWVXVWlLXKlLXaÆKšwVL@akKm@Uwƒ@@XUVk@VUI@wWK@aUV™I@UkK@ƒmL™Wƒ@kImJƒUÅVmkXUW@UJkx@nmx@xkxV²m@kmUV±Ikb™™@aUWl_kK@am@Ua@wƒÑ@mnUWIX™wULm™@DŽU¥›ƒXIlwUwn@laU@Vw¯ÓW@w„aUaƒb@akKƒUmVUUkL@WmXUaUV@lWX@Jk@@UUKULmLUJmzkKmVX°VšUnWKUL™ƒƒL@mU@UnVJ@b@„UV@Xƒ`m_@l@@bmbXJmnnš@°˜wnn@ŽVLX@V‚@nVl@nk@@b‚l@nn°WlXzW`XXVKnUlxVbUb@‚V„Xb@Ž‚VxÈbVlnbmn@ŽkVUL@„ƒŽmLUVVL"],["@@@ƒ@UmWUwkU@Um@@VkL@V@„„‚@„V@VkV@nbVa"]],"encodeOffsets":[[[107089,27181]],[[107213,27479]]]}},{"type":"Feature","id":"5204","properties":{"name":"安顺市","cp":[105.9082,25.9882],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@lL@bUK™xÅLWbkKWLkKUXUWWXU`UX@VUVlb@VVb@L„l°xXx‚bšbXUVb‚VnU„xšKlL°šnUlVn@UmVU@kUUVašblVXKV@ƄXþlXUxnU@mVK@_@ml@UU„@šblU@KnLVyUw„@@UmkšWVw@UVK@VXzVK@n„VVUUW@kVJnlaš@nKW™kaWL@U—™õb@JU@mU@@_WWƒL@lUU@WUUK„@lakÅUUlWVa_@`WIU¯mW@InKVVXa@Ll@VaV@@UXUWakUVWUIUW‚UkUƒƒmVXW@@amUUm„L˜l@UUa„wn@lašIVlnLVKUUšU@amK@kUKƒVyUU@aUImK@UXa@aV@VakaW@@UnIVWVaUkƒb@mWƒX@Vxm@UaU@W„@VULUxU@mLƒaUŽ™x@VnL@VVbUbmLkK@kƒVk@WV@bUbVakk„yõ¹nWUIVa@J@aVUU@@ImJ@Uk@¯„™V@nƒ°@bmJUUJUnUxƒbm@¯Žmak@™¦ƒVUnŎWlnnmxƒLbmlkL@l@nWVnlÆU„VnIlJ„@šXnK@„lL@VšJVU@bXL@xVJUl@VU@W„@Vxn@"],"encodeOffsets":[[108237,26792]]}},{"type":"Feature","id":"5201","properties":{"name":"贵阳市","cp":[106.6992,26.7682],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@nŽlLX„VJ„LVblJ„n°ln„„LlVnKlU@nUUa@WlX@l„n@‚Vb„@la@a„„šlJ°¦„Kšwn@°x„LVkUmmwUmk_la„bšK@UlK@UUm@wƒL™mnwmw@U@¯@KnL@aša‚ġXWW@UKbƒKWX—JƒIWakJ@_kWƒkƒKUU@UVKk@@Ula™mV_X@WKXKƒ@WUUnUK@kU@WJU@@UnK@LVUVJVkUK@UUJm_@UaVaV@UU@Wƒw@aV@Xkmmm@kw@IVa@KVLXU@`lLX@VKm_@yƒI@WœU@UlVl@UanU@Uƒm@U„aWaU@Ukƒ@XJmXVbkV@ŽƒIUVUbWUUKmbk@kwmV@K@mWUXUakb›KUUUJVb@LU@@VkL˜š@VXKlbXšmL™@kbm‚UI@lVXUVƒU@mULWy@UUL@VUx™Xnl@Vƒ@VxUzmK@LkV™aƒ@VVk@@n@`UL@nmV@bmJ@Xœ`WX°WVƒn@xnxnIl`VbnVlwXUlLl‚„_nV@b@bl°„V„nWJkx@nmx@b"],"encodeOffsets":[[108945,27760]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/hai_nan_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"469003","properties":{"name":"儋州市","cp":[109.3291,19.5653],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@஼jpnr’``ŽpRVHʘ̤žZt^JÖA˜[†CâlTébQhRPOhMBcRSQiROE[FYdGNOEIH]MgEAMLLIAG_WMCSL@ED]PCLYC[ZIHgjSxJTMbHNEFCMEE_HSDFHSLECRNSFDRICHNADGPI\\RZGIJTIAHLDQOHG`GTNCOIC@eIGDWHIS[kiE[FMbECZS@KKS[FDWsCeRuU_DUQNOE[LKGUBM¨EDQP@HWHGDImXƒCog_~‹I_fGDG|QDUWKBC\\ore|}[KLsISBHVXHCN`lNdQLOnFJSXcUEJMCKSHOUMDIm_‹DI`kNDIGEYFM\\YPEEIPMSGLIKOVAU_EBGQ@CIk`WGGDUM_XcIOLCJphHT_NCISG_R@V]\\OjSGAQSAKF]@q^mGFKSW^cQUC[]T}SGD@^_ˆaRUTO@OHATŸ”"],"encodeOffsets":[[111506,20018]]}},{"type":"Feature","id":"469005","properties":{"name":"文昌市","cp":[110.8905,19.7823],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@€hIJ¤Ī¯LQDaFßL[VQìw€G‚F~Z^Ab[€¹ZYöpFº lN®D´INQQk]U‘[GSU©S_­c‹}aoSiA£cŁ¡©EiQeU­qWoESKSSOmwŸćõWkàmJMAAMMCWHGoM]gA[FGZLZCTURFNBncVOXCdGB@TSbk\\gDOKMNKWQHIvXDJ\\VDTXPERHJMFNj@OwX@LOTGzL^GHN^@RPHPE^KTDhhtBjZL[Pg@MNGLEdHV[HbRb@JHEV_NKLBRTPZhERHJcH^HDRlZJOPGdDJPOpXTETaV[GOZXTARQTRLBLWDa^QAF`ENUPBP…\\Eji`yºEvåà"],"encodeOffsets":[[113115,20665]]}},{"type":"Feature","id":"469033","properties":{"name":"乐东黎族自治县","cp":[109.0283,18.6301],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ªVLP`@PEdNRAHOPEAKHEVL`GZBJfvdTAXNNTZJFPrHHNpKTD\\ILHbEVd^J‚OHLh@NNBnHP`\\xH@NBRLJTlŽNv_^CTLd@bNDVFbxdFV€UPBTKOGEOUO@OEBXQP[H_EI\\EbeYa@UO_J‹MEJ_IEDKJUGMDcNUd_FMTEJSGoZ]EIYGO[YW‘gEQ]a@WHEDQKUSDUGAbYBUpSCYNiWqOSQEoF[UcQISWWNMSDe_cLQ_UBiKQOOASQAWgS­ā]ZaŽSPÝZ]XMXSŒ[^oVËNgNKlE RôEø"],"encodeOffsets":[[111263,19164]]}},{"type":"Feature","id":"4602","properties":{"name":"三亚市","cp":[109.3716,18.3698],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@®ĂhTBXTRPBRPjLVAR`dKf`TC‚NXMTXRJVdE\\FpTRrPjXZMTDVoZABaVHTCLVCRGF@X^bFR’hZXP\\ZHHMA[^wBWXJlW¤EJ[bCTOF‹WWMm@ILMGWQ@DQ^QNWFSHEbF`OXNbO„VNKTEPDTLTCCVTREfvfEHNbRAENH^RJXCFHNFRpVGHWISDOTMVCZeGamaLoLÛD¹¹ėgsia{OųE—Tt‰lɂwr}jŸR±E{L}j]HąKÃT[P"],"encodeOffsets":[[111547,18737]]}},{"type":"Feature","id":"469036","properties":{"name":"琼中黎族苗族自治县","cp":[109.8413,19.0736],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@bRFnHNbHŒgN@NPEnbXP@bND`NT\\@\\QZb@`@J]V@XhžDpW„nCJGHGXO@CR§FANHVKLF\\MPVR`CvVfQtDPKpGHG@S`WJP~^dSTHWX\\RHTFACQTIAUPOU@MG__IaYSFQK‘NSbORHXCZeTFJg„B`YBMNMFi~IVDV[tGJWXGDQRGF]ˆJrALgESLSAYDGIaFeXQLS\\MKSLSQYJY}eKO[EHiGSaK[Yw[bmdURgEK^_kcSGEOHKIAS]aFSU@Y]IWFUTYlkP_CUOUEkmYbSQK@EMWUuAU\\M@EpK^_ZMDQ^OXwC_ZODBrERURGVVZ\\DTXcFWNIAWJWAYUUFYEWLQQaCIZeDM`cLKRGpanJZQd"],"encodeOffsets":[[112153,19488]]}},{"type":"Feature","id":"469007","properties":{"name":"东方市","cp":[108.8498,19.0414],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ºŸx‹JYZQ”IŠYXLl@dR\\WZEn]bA\\S~F`KXaDeTiNO^EEKWEDQXITBXaWaDQMUJOIaTWf@NJV@dSxGZ‰Fu_@WMKAUˆ}AQ@MwG_[GOAmMMg@GKP]IUcaFKG[JSCoLGMqGEOYIMSWMSBucIeYA_HUKGFBLOFGPQBcMOF_@KO©UAtERadwZQ\\@ÊJÒgòUĪRlR°KĮVŽLJ"],"encodeOffsets":[[111208,19833]]}},{"type":"Feature","id":"4601","properties":{"name":"海口市","cp":[110.3893,19.8516],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ńZƂtĢ¬æßFuz¹j_Fi†[AOVOFME_RBb]XCAKQKRSBQWSPY\\HbUFSWSPoIOcCOHIPkYCQ]GdGGIFQYgSOAQLK`MFUIGa@aQ\\GGUFcHKNMh@\\OYKAigsCgLSF]GOQO]@GM]HyKSHKPW@Pxi@EMINYREXWRQ@MQcFGWIAwXGRH\\yDI`KJIdOCGRNPNtd\\UTMbQYi@]JeYOWaL[EcICMUJqWGDNZEXGJWFEXNbZRELFV]XQbAZFrYVUBCLNFCHmJaMIDDHXHEhQNXZ_TARFHVB@DTQIRR@YHAJVnAbKFUEMLd\\c^ÍÞ"],"encodeOffsets":[[112711,20572]]}},{"type":"Feature","id":"469006","properties":{"name":"万宁市","cp":[110.3137,18.8388],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@^J@ZTVbET^JBGLFPTHld]`FLQhcVanx\\\\ZbLHTGj\\FLP~fIZRZPVTQFSVAFJE^NDLEE[~LjsxVTG\\NZZNGlLRRGLJTV@hPZANN^@T\\NEPPbDZXO`d^HSvcJDIV\\XZAJUFCLNP@PQ¤@[ïKLÑIÏ]ÇE±I{uƒ­YśUćFcYUmsVeBSVgB[RO@aYYPO^]@UVaNeDShMLG\\EfFVE\\F`"],"encodeOffsets":[[112657,19182]]}},{"type":"Feature","id":"469027","properties":{"name":"澄迈县","cp":[109.9937,19.7314],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@T\\GJCXJH@fJDDPNCNJENN^NLHBNSx@DDYbBLLDRbjZTj@`XXTlG^Xr@PJLW\\WLTlWR@HDJTD@X_PO@STMDNTMVV@NLDM`M\\XM\\JNBH[PYZ‡úYzŸ`Ċ\\ÎÝd]c[NKVFLEBaUmBIZGQ@JQSR@CUAEGBQ`SWYRMFgWGCGJCbNnIDGMEDKVAZUEqBYRa^WEUFKYQMaFWXEHIFWMYHCrXVIIiaK@aMCUYNSIISTwXALKH@XWXIEIJQCG[IEQDE_XSBaa[AIPW@]RS[FWS[CD]PEBYNGFSaSyJG]@ugEUDQlGHiBKHUIoNSKqHFaPMICK]UUHIPDJMuCA[SCPIDIOILGAEmU[POPBVSJDREBGS[QXWSGcT}]IO_X@TGHoHOLCX\\ELT@LYTD‚aFENF\\lj"],"encodeOffsets":[[112385,19987]]}},{"type":"Feature","id":"469030","properties":{"name":"白沙黎族自治县","cp":[109.3703,19.211],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@D\\RV]dTXELnHr]^@LETBBRTHPi^[@U`QTHDJ`MGSogDIPKdJ`WVNHCXHl_DJR@AH`FBVPUJLHKNTJOFFZON[ZEHFCJlMJ_ŒCn`CJVNGPLTNDFIdVTWEIPmRKMc_kDMWGGUTAtJLK~\\f{pqD[LAVXRCH{HC`eŒJ`}@W^U@I@_Ya[R[@MSC_aMO@aWFmMOM@‹haGGMEmaQ[@MESHaIQJQ……MckBIw[AOSKKAMPSDSLOAV_@@`KJRbKRDfMdHZERgAWVsDMTUHqOUr@VQXTT@Tƒfg‚L^NH\\@heTCZaESNObHPƒHeZF\\X^ElM^F^"],"encodeOffsets":[[111665,19890]]}},{"type":"Feature","id":"469002","properties":{"name":"琼海市","cp":[110.4208,19.224],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@TP\\pATHTGlZDJGAQjE\\Rb@jVBDCN`JZ[NCNHNXbULPrP\\KNbMTLjJJRFP`“pNLZz^FLRHjVPZ@hxVKbHBHMNNJFRlLzGPnNHhIrHHADcPWdUAmEMVQDSKYHY\\EhBN^HpXGNDBNNBnIß‹Å_g{³So]ã@ORO@KMEDIVYB[WJUICudGTc]P_YWaCOOMFS[]@MMYBgOU@ISHKQQkKMHYY[MSHwUit}KF\\KFMCF]EIUBETSROUKTLT[NKTWREfJbCHBZKTFTKh"],"encodeOffsets":[[112763,19595]]}},{"type":"Feature","id":"469031","properties":{"name":"昌江黎族自治县","cp":[109.0407,19.2137],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@`ZĤd–`òüˆ˜ “BSPGP@VSbQ`‡@]HC~T^SE]N]FkW]E[fY„GGOPaTMbFDYfS@g[MGK]h„e@SSSRW@UVqrPVGNStCXUhBFQGYNcCeLQQaLI@_`@EUwcEaCUaMc@SK]Du`MSkKI‡~BVNL@X`‚EvYŠwHcTU@MIe@SXJbIPNVCRXbWbSAWJCRXFFL]FMPSjCfWb_L}E[TaBm^YF[XcQk@WK‰Z“JYRIZwŒ¹ "],"encodeOffsets":[[111208,19833]]}},{"type":"Feature","id":"469028","properties":{"name":"临高县","cp":[109.6957,19.8063],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@jD`hNd\\^dZädĒH´Op@ˆùZY\\OAGIMN[[W_NCNMKU@NUMSNCTSP@`O@WSCCI@GXQSkXKX[IK@OWqH]SkWW@_SiiYQaKCAKZaCCw@MTGAMKM]FMMIMDSM_HGHRPKCBGSJJIYH[QOJCHMBDGQJECMTDQKFGTCEGTF`NFEDMFaGSNwIiTGhYJD\\KZODC^@FTKND`XBHKJNKFBNhG^FJMPcHEZF\\QPRjQTAdgNOPgQaRSê"],"encodeOffsets":[[112122,20431]]}},{"type":"Feature","id":"469034","properties":{"name":"陵水黎族自治县","cp":[109.9924,18.5415],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@R]NC`YL]FoN@V[vBXVFNL@TRZalnVFVP`DlOZkVSXEE_F[EUFeH[NKTgfCbMVU^@P]ZObZP@\\QhATUfAtUasñiāEoI]eYǯ@aKmaeƒWuCºKÜKpnbHbYfUDSNCPJTRAHJTDJSfDNLHXC``VBNGTYCQDIXMDSP@xLNEFRNXBIpVNLXah@RgF@`qOML@LJNSPLbaHAh@Jdj"],"encodeOffsets":[[112409,19261]]}},{"type":"Feature","id":"469026","properties":{"name":"屯昌县","cp":[110.0377,19.362],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@\\OnVBFKHPJCJOJTDB\\vDINOCGJVVL^JDONEbrGTLpMVJLGjAHGRkVChF@vH^zIbTETMHAZOFC^\\DXT\\EffAP\\PdAV@UIYfS|S@YPICMeM@sC[_A]VQEwyHSMuNcAUlQJMVGMS@mVBZPFO\\CSFQK[LqDMACiUa@[QiFBRIHYCHkGSBS[oSOqB‡IE^QHCRWHIXsHU\\UC}JEjMNAN_ZƒAIhSEYfWDQGaPMTL’ERZTJb``NHV@"],"encodeOffsets":[[112513,19852]]}},{"type":"Feature","id":"469025","properties":{"name":"定安县","cp":[110.3384,19.4698],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@JjDNdJ\\FbKPXfZ^Ij@RZNaVSc[MsMOHQPDJcLIJ_zCG[HQxWJBHXdENRR@XQFWZQQGOFSWUCI[WCJuRGLXNMPLhCl[Ta@SqGgJMGOmyHkKEQMINMAGaGULgwY@UOGiKQ]EYyMK”oO_QEIIKiNSMa[LqOKOaVMWMGMDY\\_IKrL\\ERT[DEPYOUA@nNTUHINkRBVMdNvGTxzRF^U`BD\\@tfNDNOJ@Z{TeTJZ@VU€cB[OBOeeQT@^OXBJb\\AbWTF`RCJFH\\RDJIJFXW@WLGBKxWTSJJMTVZND@bbL"],"encodeOffsets":[[112903,20139]]}},{"type":"Feature","id":"469035","properties":{"name":"保亭黎族苗族自治县","cp":[109.6284,18.6108],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@FJp@fxpQ\\ApN\\GNPNBM`HLMrXLXj\\PEHnI@WUCEM\\GTc\\GZYHTPBHRCPTd€H\\K\\@HXi–BJILJJAVNTOZJNtFPC`YxDPWci@IBgbGKaTOIM@KNKrP@_hE@QbgKWUMJoWAQMFEKM@wTONCJWRCZDHSAM_UD_GWMKeCITSCGIQBGXUHQoMEEGWDQIG]FMQBMaFGueFeSQDUSDSKOCSFMLƒUaPWM_PaEGFETMX]RCRR@HXKN@JNnXXEŒSPaDI\\£FkXWIAX]xB\\GN"],"encodeOffsets":[[112031,19071]]}},{"type":"Feature","id":"469001","properties":{"name":"五指山市","cp":[109.5282,18.8299],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@TCNOLBTLBPx\\AJdl†NR†RIbJTGNF\\@RcIYbmHoLQdKN_fCJYbDRRXKZFVEZVXBXIJBXMdESW[CUYHUVQFQAqsEIMPYMSBUIIJKAIj•GW[@[LGScDOGQOAGSYZ[HSd[HFNVD@XmJFG[OWiWKNqGKN_MAMO[HoM[BoRewo@Y^HpITSFENc`MVCdHNIVCLJFI`NFIŒP`@VZbaf[FFJG`O\\WRFA@PVPFPPH"],"encodeOffsets":[[111973,19401]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/hei_long_jiang_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"2311","properties":{"name":"黑河市","cp":[127.1448,49.2957],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@VÈÞ@Žkx˜nXŽ°VÈa°V@kôw„b‚š„JVškXlVUx„„@ŽlL@xkVV°ƒ„VbxlVUnVxk@ƒ„ƒKkŽVb„Il„@°kVl„@„™lÆnkll@@V„VXƒŽš@V„²bUlƒVlV„U„VÇn@nkJšŽlkVbœ@›x²V@n°VUnlKU„n`@n°bWLnVUblVUVVbknV`°kkŽl@@V°@nz„J@XšxlWXb°n@bƒĠlbXb™bVbƒJ@Všb„a@„„@lbUbšVmnœ@lšVmnIW‚œ@WbÞ@„n@x°@š„ĢaƐéϚnœ„‚lČ¯ĠŻÈwm@ôçU™mm£Xy°UV™›@wÈ£Ǫ¯kõÝçUњ™Uķ‚ƒĢkVфÆšÞU°nŎ¥ČUĊx°m°¦żVƐœx°ƒÇ£@y„UônރÆ@Èĉ°Kô¦šW„kWU—bÇ»@™ÈĕWÇÈ£ŤU@›n£ÆUUKVamanwŃmÝJ¯k@JƒIkaVaUUÇbkaÆÑkWmÝUۙ™Ý@™ƒwnU±ƒ@kkV¯KUkƒJƒ¼U¦ƒšÅ@ówķaķůV¥Uaó@Åwmƒƒ_kVƒwĉ‚ĉmmn_V»™a@U™ƒVwķóƒ‚U¦LǫéóXÇmōLǓÇķxÝkƒƒĉ™kmakbUĶ°@W¼„@bƒšÈÆ@Ė™L„l@„°J¯„mkl¯L݃±L—amJ@¼ƒ„™VƧUó„™UX˜ċb¯ńVbkÆÝI@llx„k°V²šV@Uxގ˜L@b„@b™`ƒšÇzkókݤ@ğ¯Wƒ™LĉǙLmmnċVkbUaƒL@Ž¯„‚bU°ğL݂Ý@"],"encodeOffsets":[[127744,50102]]}},{"type":"Feature","id":"2327","properties":{"name":"大兴安岭地区","cp":[124.1016,52.2345],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@k›ƒϙmƏêġb™ƒ¯@@wƒmÝ@XV@IlŽl@bUxl¯VlV™bV@ULVlUV™_kx™VVV™ÈÝJ@„¯šU„™lm¯x@xóÒĉ¼m„¯Wƒxţ@Uz¯ƒWwnUwťƒ@knƒWƒ£óVƒUUwğyó¦WI—Vmm™I@±kwÇ@@bƒ@ĉ¼ó@¯wó@¯aó¼›KՃaUwmWUwÅI@aƒKó@Ua™LƒaƒVÅwō¼UUÝl±I—¤VxÇx@zkJmnn‚mbnz™xlŽƒl¯ČkJl™°@„kb„Žmx@x™@kêmVnŽWxôXšxU°„bWLóJnÇWĵ„V¦™ŽƒUUb™b™ÆġK™šk¯™VU±aXmċÑUwĉKġ„k„™ŽVxk„ÇKkbƒIƒ‚ÛXWl¯bƒŽ™X¯K™bĊš„„ÞVƚnŽĸ²lxUŽ°n°òÈb‚¦—xVbƒŽƒ@¯„Vx@¯VķÞČlĊ°KĸŽȘI°¤ČIôŽò»ƨnȰKǬ¦ôWŎÈƨwlƒnKVXmbX`lbšwkVW‚XXŽ„L°a„ƾaĊ£nƒ°@°¥ŎzÞ¥‚»œalwôkƒJ„a@ĶK„£„bU°ĊxźVÈUĠ¥ƨ™VI@XU°x°Ln¥šw°UmwXm݁V¥ĢŽ°@nU@mÆ£š¯lKœšÜw@aÅU‚¥UaÝIkmV²‚nn@Ķ»@Uk¥VKÞ@ÞÛ@ƒkVmĢa@_ƒJómƒǖ¯Æw—óÇa@alƒUwšwĢřšk@wÆWXUWXƒWa™m@_ƒ»ÇéXaĸwVa@ÝKkUWkX‚kšKXxƒn@lĊV@¯m¯nřÆwš¥"],"encodeOffsets":[[130084,52206]]}},{"type":"Feature","id":"2301","properties":{"name":"哈尔滨市","cp":[127.9688,45.368],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@°`„_šJlUšŽ@„„@V¦°JUšŽnLôlnŤ@@šÈaUÒVbkbl¤ƒzk°ÇVÛô°IlVUVôU„xÆU„Ž@bźĀ„º@¦šb@l²‚UVlœ@°ÒĠxšnXxÆVô¼Þ@Üx²KލlƒVÑ°UȰôlwô@²ƒĸ°„lanV@„šVŎUll@bÈnÜm„wĢ@la@ÝÞb°UXb˜lŎ²ÆškšV‚I@ŽnJnĠŽ°knƒÜbĢwna@a˜kÞKƒĀ„a‚™œ‚‚IVbU¥wĠwkô˜xnLƒċVçkaUƒ±IUmnġW„°WôĉšalƒÞÅĵ¯@W¹XÝaƒb¯a±X¯ºLƒaVƒmkLóƒƒbkaƒVUKVkkKV_@aÝykk±L@ƒÅU@yV_™aU¥ówÇx™@UkVƒn@lƒkÅlwšWVwUkĉmkklW@šašbVwnWWƒ—wWL™™@Ušƒ™UƒÇLšÇmƒ„@wƒJĉƒL¥@ƒÝ_@a¯y„UWw¯ƒ¯Uġx¯aÝXVmaU£ó±›¯nwƒa¯óÅVƒXman™„Uƒ›lUXkWa@mkI„›ğaƒm™IklÇU™„kĊƒƒzkKƒš„lU„ōĬlš™„@ŽnX°@llUxŹ²mKĉVWwk@UbUK@bmVmI—ƒVmwaWxXlWȁšmºšÞÆbUxV@ĵńWÆĉLkWUbƒaWzkbĉ`U„±LklōwUVÝ£™UW`Uwk@mk¯VkaõVX@WbL™K@XƧºWzxƒK@lmX@bkVVÆk¼Vbk@Vn"],"encodeOffsets":[[128712,46604]]}},{"type":"Feature","id":"2302","properties":{"name":"齐齐哈尔市","cp":[124.541,47.5818],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@Þ@ށĠKV¯a°ƒ@„KVblaČU‚mnnšKĊȚKX„°ŽĠ@Þ£ôllÈy„™š_@a‚ƒ@a—KݍVwU@±™¯Uƒlkw@kÞJlÅUa°ŃČaW—šVôƒƨVšU„ƒ@»nI˜b²Kބ°Klkn°ƒ¯I@ƒƒkšK@ĕÇń™@aƒX»¯@VĵlaÿVamI@aÅÝउýƒĊȗJƒôȁÅkmƑۃ@kxġ@@l™aVk¯»ƒīŹaƒkƒ¥Å¯™JUaWU@@w™aƒ»„KUkÆkUm„UmwÛ±±UUbUŽUXƒwWwÆÝk™lkUanaWwnKl™kal¯ka™ƽa›kÅx™a¯@™amb¯V™lÇwÛĀ™V@x™šmêVƜVV‚aôV„wÈx@šˌx„¦VÞ¯VšlmX@‚ƒL@¯Ua¯LmV@„„°X„ċK™V™ƒ@UƒÈ@‚¥@w—ƒġIU™km¥Źwƒ¦¯lmn@°kxVV@¦óam„n¦l@nx™lĉVóšmx™n™ÒĉĀĊ¼„þ„šǔêÞ°ˌĠÞÒ°ĀɲĀƨźˤȤƨĊ°w@£nymwnkUUV¥ôÑVmkÆmUUVa™mVIkmô„lxkXÞþƒbl„ƒl@kV„ƆƒV„xV@š¼VÒ@šŽUŽšnnނJ"],"encodeOffsets":[[127744,50102]]}},{"type":"Feature","id":"2310","properties":{"name":"牡丹江市","cp":[129.7815,44.7089],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@U`lLUlVL„Ulb„aô„lKnŽU„„b‚K°¹²W°b„aÞb˜knyUlUkamř²L@m°@lšmš²n`ôÅlK„x„ÜKnxV@„l@œƒ›ÅXyW_k@™wm™ŹĕmƒX™»‚ƒÛ™l°ƒôšÈ„»š—ô˜ô_WW@Uœal»šwU@@wšUVƒš@VƒXI@w‚Ģ͑ÞȻ›aU_@mUkly@¯óV»XmWUXUWmnm¥nUUaWLk»Æ²IÇa™wÅaÝ°¯nUa±a™ƒ™@¦õÆğ„@„™@Åb›xU܁nÇłlb¯¦„ôó»mƒ—@±ƒUk@Wwƒa¯xU„V°ƒxXbǎŁUV™™ƒK@¹ƒKUaȯ@ōݙXƒal™ƒlÛkalÇUǫÇńÇakbÝƆ¯nlš¯Ž@¼™VUx@x¯W¼™Æ¯šmĖ„Ĭ¯ČƒVk‚ķÅmxœ°ô²V¤‚bUnÞW°bĢw°V°„XxƒV°z@bÞ`@„‚¦„KĊŽ„I@xƒŽn„™ÈÈK‚„šV™„@VššXK˜xX„mXUx™a™b@‚kXllĊnVlUx™XkxlÆk„m@U„Vlš@ÈwôxV¦šbU`@zÆV@„²KllÞz@b"],"encodeOffsets":[[132672,46936]]}},{"type":"Feature","id":"2312","properties":{"name":"绥化市","cp":[126.7163,46.8018],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@ऊþÆÞ@bnJUb‚ĀnblŽĊš„„ÞlĸwǔÈŎKÈnôWǬê‚KV¥„ĸôUxš„@VšbU¼m`nnĊŽĊ„xlUšmkaVÿšLšwš@°»UmbKmݙUšwUmVknKUUl¯ƒKU™ƒUȃ‚™nK@ĠkX±lX„°„L@¯¥@wV_m›ĵ¯Ww™L¯ƒUkōƒÇVU™l›w—V󁱃¯aƒVka°wVk°mÞ¯Ŧřƙl™²™Ŏk™U@ƒmUkb¯ƒķŽ±„ó@kxȯó¯VUÒk„ÝŽ±LÛwÝ@ó»ÅUWw™mğw¯Ñ›@UkV±@k™a@¥ƒ¹Źÿ@aƒÅVƒwóVVUkU¯JÜóÈUl¯„yk£laUaVÑÇb@™ţ@kmómK™V¯IU¥ƒ@@ƒ™kV™Iƒ`@ô™¼„blU„lƒ™bÈb@xÇKkĢɳaÅɆō@ƒŽVƒK@z™@@¥ÆKnÜ@@aۏUw›wnU‚ķ@ƒ_ƒV°Ž@„klVššnULVVÞbVl@°™@nx™n°LŚÆlV„ȃmU²@VmĠLƒx„n¯xkWƒzšJ‚wnLmbXbW°šÆ‚™²™@™Žšx@JVx„L‚Ā²Æ°I¯º‚È@ÒnÈ"],"encodeOffsets":[[128352,48421]]}},{"type":"Feature","id":"2307","properties":{"name":"伊春市","cp":[129.1992,47.9608],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@ƒKƒ¯kWW²ğl@ŽmLšÇ„„VVš„Lk°VVmLUlVn™xšVnނLnaVŽ¯¼™@™x™KUĀlb™n„`n„Æxô@VbU¦ĸŰĸbôxÆ@„™V¥„»„IVl°LUŽll@²„mV„x@ššÞܚÞVnŽlXÅÒlbÈaVVUblb„J@I°lÞIn‚Æ„mxnbUbVLÅVm¤@œţVǤXÈÇĖ@šÈ¼˜aXVÜaXbWŽnzŎašř„KôbšUlw@¯naÆKnUU¯Üa@mkkVUĊm„™żÝ‚ǖŽ‚K„™°L²lÆI@ƒ¯¥ĉƛVaÞk@ÝVaĠlnUVwƒœómaƒ@™wĉ@™a™VƒxamX@aƒ@UaÅLƒaVWƒ_nWm£nWm_ÅV¯ƒm@m„󤁚ݦƒ¯ÅalmX£ƒ™VWUŚw™mÇ@@IV™„WUw@ašI@„k@wŎ»Wƒ„ƒ™ÅVaœK›Ika@¥lUkUlwÅwVyÈwWU@a¯U°m—Ç@UçƒaVa¯mV»ÅwÝUlƒUk™V@k„mUk‚X£šw°@@ǃaÝIƒƒam™Ûam„¯lğmmI@J™U™l±ÅōŽ—kWa¯VÝa@Þkbġ@ƒxÛnÇm@akkōVōl±škšÅšťŚÝ°¯nUl¯xlb„U°b²„ô‚˜Uœxšk‚VÈUŎ„Vl°„šKXxĶ°nœU`@x°¦@"],"encodeOffsets":[[131637,48556]]}},{"type":"Feature","id":"2308","properties":{"name":"佳木斯市","cp":[133.0005,47.5763],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@nš„b‚„ÞJ„b@ȯ@™xW¤Vlƒn@lšUVlk„ÞVÆxU¼°nUb„bVèÈ@˜ŽnIn‚@šĢmlUw°™żƒ‚VUn@lnL@VôbšwĊ‚lœ„JķĸĢl„wôwƨxVVUƒŦšxšLź™Èš°`nnĠwŎJސĶwôJ„@¤Xn܄ĸlšn°¼È°lŽ„„Uš‚b„xš@„l@ÞÞÈm°„lôwšL°¼ĸ‚°Þ²nĠ@ôwÞ`ŤI„V„ÒĠU„„@„VJĸbƄ²@°ŽĊKšœ„JĶaĢȰ@ô¥°nš¤‚bČUš@Vx„mUw@a݁ţƒÇ™ķƒ@ĕķīU¯²@ÆmVÑô¯X¥ċç@™ĉ»U¥ÝţKWVÅkUVÝŎUmǍÝx¯aķxÛUóL¯a±óōb¯™ƒÑŃVÿƒ_Åķ„a@UƒK@wm@Van@UmmLVa—@VImmXUWƒÝUřƒKUwÝUUƒkVƒk@l¯X›‚Å_ƒJ¯k™Jm„ÅLƒa@¥U@¯Vƒz¯@ƒ`@¼šmxƥšŏKÛk@±laÛ@@Xm@™ƒ@xƽ@WŎnšˣĕÅ@@aÅ@@nÝbǏ¯@ƒ_U›kUWƒkb™wÝU@ç„Wlw@anIƒ¯lyœX°m°VšašÛšm@„mVwÞK°ƒšXlaXmm_ƒ@UƒkwÝK@ƒVI™ƒXmV»ƒI@aƒ¯ğW™bġaU_¯JU¯ġŽƒ„ĉ„k„ō`±nÝÆk„™bóĊ¯Xƒ‚ĢX‚mVn²JV„lbUè„ČmK—wlóğx‚xV¦UaJ›šƒbƑÿÝL—l@bmbġx"],"encodeOffsets":[[132615,47740]]}},{"type":"Feature","id":"2303","properties":{"name":"鸡西市","cp":[132.7917,45.7361],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@‚LšKVVnkšbVšÈb‚²U°VnklVlaÈL@anU°ÜmXV`œnôLƒèšxlŽšLX„˜L²ašVVmÈX@ķ˜lnU„Èl`ȹš@ŤŽ°U@x„KnnV„mlnnUl‚lVnnaŎwlVÞ҄@n¦šLVŽ°lšwVk„Lšaގl„n҄š@xmLÞ¤Wnœ¼‚WÈLVVUxlÈô„„WVaU_VKšKXUÆbn™‚nôK„bÞw°bÆWXamVwœK˜™Uw¯WUk„UlJUwVUa™@@kmyzm›ĉw@kVwškƒW¯ÅKU_Vmƒƒ™xU@aW@@kK@w„a@Kƒ@@kVUƒaky°_Vm™kna¯K@™ƒL™wġk@@IÇóX™ƒwVakmV@mwXUWanƒlĉ@ǙUw™KƒƒóšܛNJۄm°@›w—Å@ƒ±b¯Wƒ¹„WVwŹĕ¯kVmōb¯w@aƒwmV™UUb™V™IkaVwķ™xk¼›b@VXXó`󗙘ƒ¼Çó™¯„kŽÜš„š¼WŽn„źĖnššxl@X`WzœÆ"],"encodeOffsets":[[133921,46716]]}},{"type":"Feature","id":"2305","properties":{"name":"双鸭山市","cp":[133.5938,46.7523],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@™UƒƒUwó™mÑÞÑUÝÝUkmmŃyV¯ī„¥ƒUÿĉ¯mÇkaWbÅX¯aÝxƒaóLmmšÅaWV™LULV`UbƒXóƒkÇVwUUÇKX›»XmÝ£nK@wƒ™mÑkƒÝ™bƒKUl™x¯kU™Km¥ƒ@ÝÑkUōxmbUmkVkmmnkUƒmmƒL@w¯Vţ™@Ǻk_ƒÇmV—k@ĸVx‚VÈ°lLkllšUbōwƒnVW¼nlUx¯XmWUnÝ@™xÝUó¼¯J@LVbkJWnkb™W¯„ÝLUxƒn@‚™n™Ü™b¯U¯n›Wkz„°mJ@bkxƒX@èÞVšxlaX„lVVœ„`°@ȐÞa@mÆ@@bÆ@ˤĖm™Xōƾ@@wš„n@@WÜ@kb@²ÜlŐLƦ™nw™@»„_°@„y°UV@@¦„bÆKnƒšI°l„IÆ`œ°W@k„llUV„ÞVVx„LƚÞVX„WVnnUJ˜@UbnKVnm@Ubn@@x„L@VƒbÆĸ„`UĀƄ„Ò°šŎa²ô°bôKÜVĸw°bÞwȎVnÞōVUÆlXU"],"encodeOffsets":[[137577,48578]]}},{"type":"Feature","id":"2306","properties":{"name":"大庆市","cp":[124.7717,46.4282],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@mÇ@сǰ¹¯J±ÅÿƒKUw‚I@™wšš@š±Å‚™X¯WanamKx™I„ylX°wƒm„wğKUn±@nVDŽUƒÅkƙ¯Kšmmwš@@¯UkÝaUUVK™mU™lk@ƒ¯„U„`ĸ@V‚mœxVxܐ@bÛ@m‚ÅL@¦š@@y„L‚U„Ŏ@ÆɅɴblġÈL@wÇaša„ƒkkVƒaš»@ó¯_ÝJ™wÇaÅXny›U¯¥Å„@w™bÝa™Lmm@@ƒVUŽlbğVmš™¯Xƒm_ƒ`¯_Ux™m™L™a¯b@mƒaó¦Çk™¤V„@bóJknVx™VXx±aƒLUbVxkLVlLWlƒ@nX@VÅbWlÈnƒx„bWšÅbmŽ@xœbml°b™„XbW„XVmnn`ƒLmšnbmb@šk@mwU@@š¯Jlbk°lbkšmLXxmbVbkllšÅނxX„xVWVVa²VܲnxƒVVnÅlVlƒL„¼šb@xV@XŽVbšIÆ°„¦„lźb„Ĭ°¼Ulšb@kĢ@lw„@ƒÜlnȂƄóȘI„ĉ"],"encodeOffsets":[[128352,48421]]}},{"type":"Feature","id":"2304","properties":{"name":"鹤岗市","cp":[130.4407,47.7081],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@Þ¥‚™ô£nƒn@°„ÆUn`mXn¤mX„`UX„bÆKVb„@@bnW‚b„wšUšbĊ@šx„@nbšWVmƒ_mm@ó»Um„ŘWXkĠ»²¯‚¯nķšwŎ@ĊšŎK°bĸUnјKȦĠÈbÆknJššÆUĢV°IšŽšVƾƒwaV™ƒƒkÇ¯¯»™mķkۃWm@£ƒóIĵxݏōIğxmm¯_ǙŹš™K™wťŽ„UVUŽƧwóxƒxġkĸķƒIk›ĉ™xóa@UmK@kVmUŻ„¯šVxkŽġn™‚@mmJ¯n°V@bXVÇxUzÆxkxlVkV@¦lbœJ›LUbšÆƒ„X„ō¼@xƒl@™J@bVxƒXUš@JÈ@šn™xVÆUXš‚„W¤knÆb„°"],"encodeOffsets":[[132998,49478]]}},{"type":"Feature","id":"2309","properties":{"name":"七台河市","cp":[131.2756,45.9558],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@²mŎ_lƒĊƒ„ƒĢV°°IV`ĢbšaĠX„°@b„JU¼Wnš„UJ@„ÞLlxV„„@n`lIUa@K°Iô»ÞVšwÞ@VmnX°WVwmkX»‚U„mŎxVak™lkkKǯUUwÇWUn™U±b—KWƒ™Kk™w„çóK›mU_nW¯ÛmV@bÇKkbkUml¯U±VÇaU™™amlUU™LK›„k@ƒU@mwÛLƒŽƒwkLóÆm_™±™nkŽ¯@@n±KnŚlbkVV‚mz—lWXº@Ķ°"],"encodeOffsets":[[133369,47228]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/he_bei_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"1308","properties":{"name":"承德市","cp":[117.5757,41.4075],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@lLnlmxn„„IVVlUnb@VVxXJWL@LގVnnV„J˜_@wkmšK„b‚x„wXk˜WXXšKlb²K@nVVVb„L@WlU²„lKVnUJVz@VVb@lżmVUVnbôaVX@°Ub@lWbXš@b@bVb°x„@VxÈLVlšaÆ@Þb²k°@lVUŽ@Xn@VW‚LXb@¤VXšKVVVLnm°_ƨ¤@aUIVa„alkX›°k„™V@„alwUVy„U@k󙰃na°UVUUmUÆw@mkLVUƒWVI„WšLnn@xlVnK„myU@ƒU°UXaV@U¥ƒU@Uƙ@aVUkWU¯ƒaU@WLUV@bkbmKULmKkUVUkmVIUwlWV²™Uml°U@W„LUwVm@UUK@_ƒKUUÜaXw@ƒVKUU@mVIUUlmnIVVVbÈVlKnbVKš@nI˜@nVnwVLVK„K„„˜Vnb@aUIVW@In™°@lVnIš@lWĢ@°UVL@b„@VyUUƒa@w@WUnU@Wǯ™K@UkkJWaÛbmk@mVaÞU@amkWƒ@mXUKkÿƒ£@a„kl@Um°UXwla„al@nmlXnW°znW@aƒwV™@ƒakbĉ¥VmU@ƒIƒVƒUƒJkUmWU™KbmkUaƒKkUVU@KV@@klw—™WaU@kmƒXVènbmlUUƒKƒX¯JkbƒI@JmIUWU@ƒLml@XkJ@U™kƒK@aVKwWa—IWwƒmUƒ@mU@J@UaċU™aUUƒVkI±ƒk@UUƒ@UbVVm@UVKƒLƒlkIWaULUWƒXUJU„ƒ@WbUb@lkXUxm@@JVn@J@b„nƒb@Vkx@bšLU‚Æn„JšaVXnKVVmzX‚°V@_lJXxWXƒK¯bÅamUƒ@lUI›bñJ@LÇKkIÇ`kxWL@„ƒ@@bUVUb¯xWKk„Å„VlULW@ƒŽn¦Ul@I™lmUUUVm@kWƒnkKma¯XUKWmnwVwÝL„mŽ™VUbUVWb@Lnxm„xVŽmbXx›¦@„nb@`™„ƒVƒ@kbƒLU„mVUlkbVXkºmnm@@xk¦šbĢÜlš"],"encodeOffsets":[[118868,42784]]}},{"type":"Feature","id":"1307","properties":{"name":"张家口市","cp":[115.1477,40.8527],"childNum":15},"geometry":{"type":"Polygon","coordinates":["@@k™ġۙal¥@wn@nml¹UWlaVknUVƒ„Kla„@„Ušƒ@_ma@ƒœ¥WwnaU‚wnƒmw@KXaVUVašUnmWUk°™lƒnUVUXWVw™IWVóKUI@WXƒxUU@mma@kUKWLkw@yk@ƒaVkUUċaUU@Wk@Unm@UVmLm±IUƒkJ™kWƒ@a„I@m@U„ƒVƒ„Ula„@VXVƒXmVwnkWKƒKU_k@m¥ƒmX_™JmnU@km@U@KmU™VƒU@U™@Umk@@LƒmW@Û£Wƒka@wk™@aƒI@mmk@mUa@UmUƒIƒwW@aWUƒbU@kbÇ@kwƒ@makVUk™U@aƒm@aU@mxkUƒbƒKUXUƒ±KXVWLUK@wkU@V™@WXUa@WbUxƒJIƒŽ@¦VèVVX@±ê¯KUIƒ`¯UULVx@Vƒ@UKƒIƒVkLmVkKmš@nUJÝbkIUJVXšVVxVbU„VJ„Un™°bV„mlU°„XnK@Ul@lVÈVUXšx@W„@VXšV‚KÞb„n@VnbV„m`ƒUx™kW@UVkL™Km¼@lUnUJVnV„XV@Vm@@LV„klƒIkl@VƒWlŽULWKUL@mJ„@blbUVUlmzUJUxm@UUbċÜk@Ub@VšLVV„¦ôbVŽmšUKUkU@m„„@VlVn¼WbUJ¯@@„°šnIllÈl˜@nXšWlLœk‚J@bkxlxkxlXUlklJƒšXL@bW„n`@nƎXxlL@xl@Xb‚LœKlVlIXblVUbUJW@lX@VL@VVŽšXšJšw„n@WnL°K„bVbl@VI@K„@U@nmVmV@XUWI@aXm@™VUUkWmn@lmUUk@mUmK@UnwVĉ@ƒƒmU_V@XJôVVUšLVUn@šllUnJl_n@šml@XŽlLlw²LVJUL@VmbVblVXmVnlš@Ť¦„nn@܎@bšl„@@XV`„Unb@VlLVb²J‚Xn¥ÆÑ@¥Þ@"],"encodeOffsets":[[118868,42784]]}},{"type":"Feature","id":"1306","properties":{"name":"保定市","cp":[115.0488,39.0948],"childNum":23},"geometry":{"type":"Polygon","coordinates":["@@VbXWš@@UlV@xVLXKWU²LV„VW„L„alVnwV@@b„n@bšVVllUnb„@lxÈ@laV@„aXV@b‚X„x„J‚nV@VVb@nnl@n„J@blšl@„ašƒU_VWUwVUškUm™Ukb±mVwœU@VIUW@UWk„@VU@ynL„m@IV@‚bnK„LVaVmnIlaXwV@@WVL°@@xnX„@V`V@VbUVVLVKnwnL@ll@@_V@VVnaÆ@œKVXÆ@nƒ@wƒKmU—™Wm@km@kÜKXU@ÑW±nIUwVƒ„Kla@I°wU±kškmm¯mƒ_ƒJnƒaƒwW@IVaUama@wƒUƒmU@mVw@aXk@mWa@£km@aƒ_kVmUnWW@¯bƒkUmk@ƒVÇm@@kUU™KUU™@UVUamVUaWIkb@xU@@amUkKƒVkam@@kVUkUWmKmUkLUb@xmJƒ™U@UImVÛVmnUwƒJƒU@VƒX@UWm@Ub°¦UšmxklmX@`ULU@@UW@@xkn¯@makV™UmxUb™°ƒlUšƒbUbƒnUJƒUUVƒa™LkbUU›JUU@mUUUƒJkaƒ@™xUIWJƒUnƒJ@V™zƒ@kb@`@bln@l™bƒŽ@X@š@š„@Xl‚bnbVb„@„„VJlInlšbVw@U„K„l@lbnan@Vb‚JôLn‚UzlV@lÈLVbVK@LVx—VWXX`WxXz‚bV`UXV¤nx@„bVlVnVlUL"],"encodeOffsets":[[117304,40512]]}},{"type":"Feature","id":"1302","properties":{"name":"唐山市","cp":[118.4766,39.6826],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@„@VVl@²„lJ„UVVšbČVVb‚@@InV„@‚V„nXx˜JXb‚xUL@b„Lšl@VlI@Wnk„KV@VXnJ@I„Jla°I„W„LVVnkmaUç„WVkôaܯ„@nV°wnJlaV@VUnUUaW¯wXWWwna@£UaWKU¯ƒ¯@aVUkKUamUUƒn»‚an™„IVwUWlkš@„LlWVakU@K„_lƒšbÞU°@šy°n„@„KÈkWW™ţ¥ĉōƒkġWUw¯£¯ƒÇwţwƒ@kK@kƒ¥ÝwÅbǤېťV™lW°@ĸ™x@VVVULVLkl@V@Xƒ`Ub@Xm@UWbƒk@ÆVbnLWV@lnXUbl‚@X¯lmU™VkKWLkK@_UK@U@UmmUxmVXLWVULkU@`W@ULUK@XlJXzV@@xml@VU@UX@Kk@WbUK@Xn`ƒXmJnšmškxUVbUVlVVxUbV@nKlL„kVKÞbVKXI°KVšmVUIUKULVxVJVLkV@Vƒ@UbU@WUU@UbUK@b@nƒV@VkLmb@b"],"encodeOffsets":[[120398,41159]]}},{"type":"Feature","id":"1309","properties":{"name":"沧州市","cp":[116.8286,38.2104],"childNum":15},"geometry":{"type":"Polygon","coordinates":["@@@ln@UȄŽl@Vn„l°aX@mXnVlU„`@bln@¤Xb@nWl@bUx@nnV‚„„V@xnbVbUb@J‚X„x„b‚mXa@k„UVwlW„k„KôVm@w™kkK@kl»Èƒm™VKXkla°@XVV@VI@ml@@Vn@VX@V@J„@VxUzVVšš²blVk¦@šĠ@@»š@VK@VÈLlK@XnJ@alIUl„a„VVbš@„n@a„U@WUIV@mUn@mKXml@lL@LnWšb@XV@@a„VVb„V„@VV„IVWÈb˜IÈ»ƒǟlWšaVUÅUƒƒ™Um@kVU™WVkaUwmaóUƒJUU¯ÑU¥mk™¯UaƒKÅnÇyóXmWÛX¯aċbÛa›J—W™ÝU¯»ƒaóóUm@IƒšVVl@bƒLUJWLX@@xšXUxl¤V@V„nVUV„XVbVš@Ž„@@VVn„°VŽ@ţU¯VƒUmƒUWV@mUXƒaƒbUKUwUaÇKn„ƒVk¦Wb@VnLmV@bkV@n„xW`Å_UVƒV@bƒUklVX@VmlUƒx@VVL@x—VWVL@VW@UUm@"],"encodeOffsets":[[118485,39280]]}},{"type":"Feature","id":"1301","properties":{"name":"石家庄市","cp":[114.4995,38.1006],"childNum":19},"geometry":{"type":"Polygon","coordinates":["@@la„@šy@U„I‚m„VXIVJšw„@lb„IVVnV‚@VVœIVVlašK„bVU„VVI„mVa„aV™„kš¯VanwšVlUnb°@lm@wX@@VV@VK@_nWlknwV™¯¥Van@VX‚@„W@U„V„IVxnmÜUnUVJV@„šnI@wValKnV@k‚mU£na@mVk°K„LVa@UU@UƒmknWWkXU@aWW@@km@UaU@@klK@UkaWaUnamm@U„a¯wWU@UkƒL@ŽUn@x™V™lUXVJUb™LmU@aUWUkmKkLUUm@mW—XƒaƒmmkkWUm@@U¯JUUm™kU¯@mKĉxÝwÝ¥LƒUóŽmwkUUUWVkKm™kKmLX„lxVLVxXJ@nVJnz@VWL@`nX@šƒxƒ@kVUUmJmIXx„JV„ƒnUVƒ@UVV„@LUšƒ`UXVVƒ„ƒlXL@l@b@VmX@b™xn°™UƒbkKWLXlW@@bƒK„mKULmakLUlmb@šXb@xmXU`V„b@`lLx@nWVXL@‚°WlXnlb„KVK„XVb@˜X@l_lJ@V@XnŽ„I"],"encodeOffsets":[[116562,39691]]}},{"type":"Feature","id":"1305","properties":{"name":"邢台市","cp":[114.8071,37.2821],"childNum":18},"geometry":{"type":"Polygon","coordinates":["@@nKlLnšlLXUVVlVnxô„V‚KÞ¦ÞxĊwnL°@lVnšVV°I@Vn@V‚lXnl„n„b˜WnXn@VVlKnLVlVX@bnVšKVaUIVWškšU@wVm@¯@U¥VmU_°lšK„k‚w@LX‚Va„U@wšUƒUUKlUóW@UVUœUlƒ°K„wlKU_na„KVnlKkkšWWa@IœJVa@IlJnU@„KVUUmVlaXUl@lm@kXWÝÑnkƒ™±™k@wğ›@@U@mKĉLmVJ@zmlnŽWLUÝJU_ƒ@@šmJkXUVlbklÝ@Ýa™b¯@¯±JÅwġaUU@ƒkU™@mVI±bUKƒL™WUXƒJkaƒLóKULWbUVkKmnk@@bmLUŽƒl@b@mnmJkUULƒaƒbnŽmn@lVV@¦n@„l@b‚znx@`Vz@b„xnV@xl„lbnKVx"],"encodeOffsets":[[116764,38346]]}},{"type":"Feature","id":"1304","properties":{"name":"邯郸市","cp":[114.4775,36.535],"childNum":18},"geometry":{"type":"Polygon","coordinates":["@@„bVKlVnInm‚@@a„kVnK@al@nmlLVUXaVKôL„Klb„IVWšX„KVL²a‚JnUš@lV@„VVĢbÆx²I°Ž°@šaÞbÞ@lkkaVUlWnI@™„@V`ÞI‚VXKmnk@y‚InUĊKƒÇkUUamUUkƒƒ@aU@U™ƒk@WUwVkVJVkkw°a@„mK@UX@VV„LVW@wšwVa@¯Xm@@lUIWaU@UWkXWmU@UwmUkKmn@lkVƒ²™VƒaULUVmJUUUwƒLma@™UmkIUm›L—mVšmx@b™LUamKÅL@VmbkU¯KÝamzkJUb±Vkb™L@lU@WIkJƒzkKmKƒnUalWkkKW@@nkbk@WW¯XUVUJ@XlJ@Xƒ@XlWLkUƒ`VUnaWa„UV@UVIƒaUxUUmVƒK@I@W@DŽU@@U@bƒ‚@nmKXmx™@UxkVWUX„@`VLlL@`™zX‚Ýb@b‚„@VUVkIUJVz°KVlnLlKnL„xlLVVUVlXUJ@nn‚„I@mVUlbn@@Žm„@bV„nV"],"encodeOffsets":[[116528,37885]]}},{"type":"Feature","id":"1303","properties":{"name":"秦皇岛市","cp":[119.2126,40.0232],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@lnV@Xb˜škx@lU@@LUVlV„LVbnl‚ašLXVVn‚l„I„V„U„JV@UnĊ¦la„bš@nJ°UmƒV@„wn@VU„JVI°bnWlXnWVLVK²b‚akk„lI@aUaVƒUwVUUalaVwnUVak¥šX@W‚kœLVÓm„mUK@_lWš@n_UK@alÅ@ğÅƑŃݍmƒ@їţÇlƒLƒ@¯m™z¯@ÝV™ak„ƒ`@LlVUbkXƒK™@klVXUxƒJmšbm¼V„nVVblLUV@b„°V°XLVb@¤mbXxWX°xXŽVbmVUVU@kbmI¯xmUƒ@Û°óbUl"],"encodeOffsets":[[121411,41254]]}},{"type":"Feature","id":"1311","properties":{"name":"衡水市","cp":[115.8838,37.7161],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@„KVlV@X°xƒb@VnnmbVŽXblb@VkL@lV@Vbn@@l‚@XX@bWVXlmXnlV„V@@VUbƒK¯LUl@nmbV¤n@l‚LXnlVUV@ln@lb„UlLnV@bV@@wlaXJVbnUVbVUš@VVšLVVn@VVX@@U‚KXU˜U@wUK@U„wVnk@UUWlk„V@a„UVUÆ`X_ƒw@mlU@anUmK@UXal¥„UmƒÈLVbVxVL„a„bVW@nXU‚Vn„„V°UŤV@Uƒ¯Um@Uƒ@@U™UaƒWVUmUUƒU@k£Vw™W@wW@XKƒIUa@wU@@al@UK@_mKXKƒbUU@aVKmš@Xmƒƒ±@kbÇakLğVaUw@a@ƒmkUJƒk@ykw@£ƒWX@lknk@WVkbUŽVnUVƒL@‚mVkI@JUb›I@JXb™XllkLUmƒLmbV`kLƒx¯Lk„›VUV@VôXkVVL„V™V@xƒVUbW@Kxƒl™L¯kV`UnV¦°@"],"encodeOffsets":[[118024,38549]]}},{"type":"Feature","id":"1310","properties":{"name":"廊坊市","cp":[116.521,39.0509],"childNum":9},"geometry":{"type":"MultiPolygon","coordinates":[["@@la„Ušš@šUnL@VWbklWxnIVV„V@X„JlbUlšXVbn@@K„mV@@X°WVInJmn²@lmVbnL@amKV_kwlmX@@LVamaXaƒaVU@UnJVanLlUkaW@UaVakK@IlKUU@an@ln@alKUƒkIVa@a@klaUKUV@UkUV¯šKVƒV@kUmƒU@@a¯ImJUU@VV@UL@Uƒ@@WXUWa@Ukwm™@ƒX@@w@al@@aVIUmVUUUVWUknK@I@™l¥kU±a™™UUVyUwƒ@@I@UUWm@@Uk@@nUJU@WU¯@kbWlULnšÇ„k¼@llLšl@xUnóŽƒLƒlkXUxƒV@lWb„I„`°nnn™llŽV²¯x@JkbƒLU„VxmJX²@ÒWVÛL@lln@‚Xn˜šnV„L"],["@@@kX@Valaa@KWI@UXW@WanaUIW@UaUKķŽk_W@UVUKUš@bƒ@UamxVXnJUbWVXLVbn@W°kb@U@Wó¼mIU¼k`V„@bVbl@„lX@lUôVlUœIV`lX„Vn@lUlVn@„l@UVaƒIUWl£Um™VWU@@UUKlUUUnƒVL@KšUnLVWUa›@™U"]],"encodeOffsets":[[[119037,40467]],[[119970,40776]]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/he_nan_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"4113","properties":{"name":"南阳市","cp":[112.4011,33.0359],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@lKl@nVV@„bn„@VVnm‚nL‚LXx@š„‚VLlKVU„IXWÜ@șlbl@XUĊUlwnW„LÞw‚m@ÞUVmnVl@nX‚JXLm@VnnJla„I@VkxVb„@VŽln„J@knKVn„@°aVanal@XK°b„‚@š¯VJXIš„VK@al@nV„k‚@nK„a‚b„@XL@blVVKVLXK„@VaVI°mVaX@V_@a@yUkVw„VšIVašJ°™@anIlaV@nKnXÆm@wUUV±UUWUKnaWwXUWmŁ¯Vƒam@kakImƒUKƒ»lan@VXXa˜W@@UlUUa@a@UlwUƒV@Xal@@anIVaUK@V™XmwVmUmV„LXl‚@nalLnal@„šnKlkV@@UnJ‚UXnl@nVl¦V@@VnJ@nUVVVVIn@Va„JƗn@@K@m„kƒa@kmWVaUI@a@™k@@aUL@mmaVIUKUVƒ@@IU@mƒUmmL@K@UUUU@mW@@nU@ğ»mVmbk@klW@UXnV@LƒJm„™lUnUJ™UUUWƒƒ@UnkKƒxmLa@ƒ@@lUU™bmUVWk@@nkUmam@UakJU_ƒVm@ÅlÇLUVmVUwULƒKU@ƒk@UƒVUlU@@Uƒ@UaUUWaŎƒzJƒaWLkl™b@bmL@„kKƒabWŽUVƒ_@mV@b¯JmXUbUK™¤ÇLUU@b@JkLWmkUWIkJ@VmX@JUbVXU`¯VV¯blK@LXKl„UV@Um@@Uk@kxWŽkbƒL@KkbmL@‚UXmaU@@l@x@blX@xUJ@bULUlULÇ@@VšnU`W@@nÛ¼U@@VmKUkm@VVX@@xǚ@bUbVb@VX@@x‚LUb@lƒ¼XLlbUlVVU„Ub@n"],"encodeOffsets":[[113671,34364]]}},{"type":"Feature","id":"4115","properties":{"name":"信阳市","cp":[114.8291,32.0197],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@VllInJlknJVkVU@mXlUÞ`VnV™VU@U@y„@nXlKV„nJVkXKWaXI‚b@yVk„VUkVwn@‚K@nW@k„KlUXVVUlbnUV`n@V_V@llX@@V„b@bV@@nlVUb¯‚WLnbmb@ŽnLnK˜b„U„bVWnLlaX@VVUX@Vln@`kL@ll@VXVJÈIVl@XÞJ°Una„LlylU@UXKlnn@lanLWWnbVI@KXKVL@LVWVL@UVKUIVWX@@XÆJ@In`@lJVI@a„WšÛnK@UlK@UU@VK„nlm„nXal„UllLUbVVšknJ@nV@Vm@a„l@@xnV„„lJVUU@™w@aƒk„@XW@_mWnUlŁUmVKV@VXwW»XƒWaUwnkWUkVUƒU@@@WlaUkkaƒIWVkm¯xmIUmƒLUVƒaUIó»m@mmwXk@a›mk¯¯l™@wƒmkLmmU@UbkUWJ@XUbƒJ@b@l@znÆmK@Xk@Ub@lm@ƒI@akmVKUUVUkU@U±JUbkƒ@IWmkxƒa@UUV™UWVkIUaW@UlLWn@VkJƒI@VkK@L@bmKƒkJmUUaUKWXk¼VxnJ@„V@@VULV¼ƒ@@UkaUlWL@U@W@IkKmL@KULUWULWKUXUJmIƒb—KƒŽƒ²UW™nWKUUkLUƒmUUam@UU™@ƒmUL@xkV@„VV@bmV@Vk@mwkUƒVUx@mbX‚ÇnVb„‚UL¯šWŽnUVLVb@xnlWnU@UVUVVUbVVlVkn@llVUXUWUXVbUJ@bmLUJnb@nVK@bl@@š@bVJUbnX@l„b"],"encodeOffsets":[[116551,33385]]}},{"type":"Feature","id":"4103","properties":{"name":"洛阳市","cp":[112.0605,34.3158],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@VVUllLXl@LWn@J„@bƒKUVmnL@`VblLnbV@„b@JmL@LnV@VV@¯„VJVnXL˜@nm@aÞ@‚a„k@m„IšmVbXL‚ynLšk°@°aVJnUV@UVVXk@WJ@VXLlUnJVnnƒ°U@»°U„wl@šb„WmUXƒÆ@VLXU@m@U„a@I›mkb™a@naWW@_@WXUV@@U‚ƒ²@„K@I±U@¥kKWLóLlƒa@£Um@kWKXU@mlLXUVKUU±J¯_@`UL¯Wmk@Wa„kkƒlUnƒVUVaU@KUU@mmK@_ƒa@KX@VaUIm±™k„aVKVUkw™@kaƒƒW@kbkL±UUaƒK@UUKVak£ƒ@UmmL@lƒIkmUƒ@Ualw@UƒJkbmIUmn@WKImWk@mUUnÝV@ŽnÝxƒKmXkxĉVWVk@kaċšÛ@WXƒJUV@zŽm„VWnbUbVbšLlUnŽ‚lUÒnWV—VWnk@@Vm@kxm@Un™l@Ll@@V@šXnƒškJV„šV@nlVXx˜U@l„n@aš@VLnWĊ¦nxš@lbVKXLl@ރVLƒ„XJl@XXl`lIXVl@Xl‚XUVšK„wV@lanx„zUbVJ@VVX@b"],"encodeOffsets":[[114683,35551]]}},{"type":"Feature","id":"4117","properties":{"name":"驻马店市","cp":[114.1589,32.9041],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@n@„b°UƂXnVlnLÜ@VLœm@n˜@na@J„„m@k„@lVšVxXX@„V`lLV„XVV@VVÞLVV°„²@lašbnxV@@b„Lšmlm„_VWnIWUna@lšLšbnV°ƒVL@KšV„LVUVaVLXK@mÆXna@wVm„a‚@Xw@KlL@a„@Va@wUkaWnIVƒla@Kn@Vn@VUl@nKVn„J@LnK@aVkVUUWƒ@VakUVanI‚²X‚W@UUU°KnUVLl@XaVK@ašU@KUI@W@_lm@KkLUKV_Uƒ@»@UVJ@XV@@mVL@K@U@Kk@VwUUm@kmWL@VkVkzƒKmb¯VÝI@WUkÇJUIUWk@@klK@_km@UVWUUW@kbmKUXƒaƒV—amLmK@namaXK°VakU@mU@@aƒa@UW@kkU@U`m@U_mVkaUVWUkVƒL@lmX@ŽLm@UxVlƒUUl@zaWJXbWLUlmIUƒkLmWƒ@@z@VUVUšUmÝ_kVWŽ@nUVUlmIklmIkJUkƒl@n@Lm@؃IUbm@UJUUVU@mmI@UU@k¥mUk@WmVmI@VU@klmLƒ™k@mbkKmb@WkƒKUŽVnUnnxšW@UVLUbmJ@bk@WbU@V„kx@V@bVbkV@V‚@‚—XWbUWm@kb„¼VLn„lJlb"],"encodeOffsets":[[115920,33863]]}},{"type":"Feature","id":"4116","properties":{"name":"周口市","cp":[114.873,33.6951],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@lšnb@xlJ@UnLlKXUlJl_„KnV@xVL@bkbVVUè@šWb@„Ubmš„ŽkšVšmbX„VJnUl@„a°@@b„LVbƒlXx˜InmnLVw‚anJÆw²IlmnXVl°VVbÈaVb„@lkn@VWnLlUVmÞUUklƒkƒVkUaVaVaUw™K@kkaVWmw„_„‚l@nU„VVb@b„aV@VV@zXJl@@kl@šlœk°WVnÆbnbUšVJ„Iš@VKVm@k™K@_kK@a@aU@@wW@@k@aUW@IUWVUnLlUlVXKVwmk@W@—VWa„¥@k@lnƒUIÇKUaU@ƒUUVmIUV™Uk¥ƒVma@¯k@Wanwmƒ„@@n@@m@UIVƒkUVamUXWƒaV™U_™@ƒmUVUImW@aUIĉK@VmI™b@lU@@n™JƒkU™@KƒIUmmLk@UVm@UŽm@@LkbU„mJXlbV‚@xUbƒ@@bkK@LWx@ƒbUn@xmbÅW@nWLUKUbUVƒK™U@LUK¯„mU@šVV@xULUŽVL@bU`WšUz¯aUamKUaƒ@@xkX@x"],"encodeOffsets":[[116832,34527]]}},{"type":"Feature","id":"4114","properties":{"name":"商丘市","cp":[115.741,34.2828],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@XVl@lLȃ„@VkV@V»UanƒWX@VaÆÇô@ÈaVX@xVJXUÞU‚aVLĸbXKl„V@šm°Vn_ny˜XX»mUk¥lK@a„_@yšInaVKVa°_@WXI@ƒ@K‚VnIlbnaV@„l„@‚a@_w@ƒlwUKm™Xa@UV@š»Vƒšw@kUKVUUm@w±VUXUKUwmJUUƒ@km@@±mXkmUI™@mm™KUwkbWakLWaUIkJmŽƒX@l@@VUX@JWbX@VbULWbƒlUVULknlV@bVJk„mb¯KknWmk@@nmVkx™@ƒVmU¯KUnUL™@ƒJUIV™maÅaUm¯X›l™kk@@lk@WI@yUUU@ƒb@aUaƒUmVk@ƒƒ`nxUXlb@lšLVxUbUbVbUll„k„VlÝVUnkVmKUXm@klƒ@ƒnUx@xnxƒn@`VX@V²x@V@b@„Wl@zU`VUVVb„L@Vƒb™W@bkXllkLWV@V„@VVÈwlVœ@@X˜K²Llb„WnnÆL@VnJWn"],"encodeOffsets":[[118024,35680]]}},{"type":"Feature","id":"4112","properties":{"name":"三门峡市","cp":[110.8301,34.3158],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@WKUmUI°ƒU@@UmU@KnK@IƒaU@makKUa@_‚KnmVU„L@a‚ƒ@IXm@KWkkKVkUU@aUW@UUIVaƒymwkbU@ƒx™LVUWWkk@WUkJk_WWk@WI„ƒUK݄k@WKULka™@mwĉ¥mXUK™@@bƒm@k—VWwkU@m™UUƒlI„™Wm@™@Uk@@KškVmn@lwn@@Ul@Xm˜UXUmVсkmkV™KUaVamaUXnƒ‚@ykLUKƒ@™WwKmKnUm@UmƒƒaU@mUk@kL@lƒxċxUnkVmnXxWb@`kzWJ@V—LmVUn™lmUL@lW@Ub@VšXUbš`VLUbUJ@nmnUlUUm@@bUJlnU„š‚U@lxkbƒ@@XƒJUnƒ@kb¯VVVmlXXlJlzn@VlkVW@bkK™bmškŽUbVb„lƒXVxšKÈnšwÞlĊKlšVnKlwX@lL@xlUnVn„@šl@lmX@ƄÈb°¼ÈwVJlx„_°xšašlšUÈxlUnbVxnL@lllšbm„n@nb‚@@V„L@V„@@„VLšJnIVVlKnV„_"],"encodeOffsets":[[114661,35911]]}},{"type":"Feature","id":"4107","properties":{"name":"新乡市","cp":[114.2029,35.3595],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@XVlL„K°bUblbUbšl@nX@W„XVVKVkš@@Žmb@„Ubn„W`kL„LƒV@VVLnKlVXIlVš@@a„@l£nWlƒkVa„@°bnUlLVlna‚bnUVUXKlU@ƒ@lk@a„I°y„@ôkUU@wšmôšnkWakml™UkVmkUlmUUm@nkUKWanamU„LXW@U‚VnUln„`l„œblL°KXV@ĠJ@L°„šJšUVw„anK@UUImmƒkK@¯±Um@IVmUmmÅnWaUK¯aUk„w@W±kVƒx™U™VƒwƒnÅJUIWaÝJóI—bm`ÝbÅImJUI¯¥¯@mU¯UƒJmnUVóUkl±V@zXl„bWVXL@bm„mº@@XmJUXU°llk„@nWJk@U„@¦U`m¯ŽWx"],"encodeOffsets":[[116100,36349]]}},{"type":"Feature","id":"4104","properties":{"name":"平顶山市","cp":[112.9724,33.739],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@l¤UbVL@V„LVb²VlKlaX@„„lbš@lxUVULƒbšln²VJUbW@@L„b@`nL@nVV@LVŽUbUVm„kVl„ƒlXbl@Xn°ŽVK@_°`²IVVV@VUVJnInaWK@Uš@„K„LÆ@nmlXXWVUUw@klKVa@knyVkVanI‚JXUl@XbVUl@@aša@mXk‚bnK@UlK@UUUVaXaWmkUm¥n—WmXaWaœkl@VmÞb„KVL@aVI@mUwVm„@KōméUL™KVaUk@kUK@U˜WXI@VlKXU‚@VVnInVV@VLlK@UUƒkKU_@ƒWWUwU™@klƒn@ƒƒ@Imb—@@m›nUKÛ@mKUkWVXxmbVLXŽVVU²VV@xÅnmWmLU@kbmJ@b¯š™IUb™JƒUUxVl@z@bU`W@Ub¯nUJUbƒ@WLUKULkU@aWKƒ@aƒbmL@ƒlmUk@@bUL™ƒWJUI™°@ƒŽ¯aWLk@mbUb¯b"],"encodeOffsets":[[114942,34527]]}},{"type":"Feature","id":"4101","properties":{"name":"郑州市","cp":[113.4668,34.6234],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@@nWVUKÅ@W„nVnI‚ŽV@œkƂšwV@šnn@lxÞlnôJ˜zXJl@nalUČVlƒl@²UlkôVVUnm„I°VnV°@°¦VJnIÆJÞan_VmU@ama™@kU˜¥kaUklw@UIV¥kVUI@ƒmmUÅmUlƒwVU@amU—JWbUakVƒ—Vé¯Im`ƒk—@ƒwVWmLkU¯ŽƒXkWmLmx@UUƒbm@@x™J@LbW@UUVWUkVKƒ@ka™IUamKUkkmmLƒUkJUVWXkWmnÅ@ƒKƒL™@@VXLmbmJUIUVU@ULWVkK@nWVXL@lVn@¤„b‚kôKXKlL@¦²V@JƒL±@„@VU@WV@X@`XXmb@Žšblaœn@Jƒb@V"],"encodeOffsets":[[115617,35584]]}},{"type":"Feature","id":"4105","properties":{"name":"安阳市","cp":[114.5325,36.0022],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@°kVaV¥kVmUkWkWVkVKUwkkmKUU@a„wWWXWakKWkXmlašIVmX¥ƒU@a„@WnK@kƒƒ™V™I¯ƒ@KğI@WU¯LkK›akƒƒ_kmmVU@VWXƒKnVmbXbVLmln@VVknlVUnVlkšlnXbmlmlXblnÈlWbn@@nšK@V„L„bVV°VVzšlnš@V™xƒI™b™ŽU@WLUa¯V™UkWõ@¯kkmxk¼l‚„XUlVbVLnlULmU@lƒLkVUlƒX@xW@¯mUƒ@UmIUW™L@aXa˜kU™¯anƒWk°@k™kKmmUIWaambUkkKmV¯aƒ@UblŽk„mXk¤ƒ@@b™@UbULWVnb@lUVVnmšnVVU„J@bWXX@WJkL@blVU°UV@XlWnXUbW@UVkVšVWbnLUJWLUK@Lnn@blVU‚„nUblxVUVJXU„a˜@Ub„LnUVV@mVIVVn@UbV@‚XbmbUV„_lVXUWanJVI@WkI@WVIVU°WXXl@la@mX@lLXl‚kVbœm‚X„ylIXJV@@kšKla²UVa„IVyÞb°LlVna@UÆKnLVbšK@anwU™"],"encodeOffsets":[[117676,36917]]}},{"type":"Feature","id":"4102","properties":{"name":"开封市","cp":[114.5764,34.6124],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@lUVbXa˜InV@bUV„x‚knVVÆnn@„VJlUU¦VJ@kxVllb—¦lVš@nb@bVŽUn˜aôJÞIXbVJÆI„m„xšUšV„w‚U²l@XƒxVl°bVLXb‚`XklUnmVblLœ@lmšx°LVK@UXIVašWlL@Ukƒ°KkVaVUXmmI@UÅKmmƒXka±K—L@W›@kUÇxUUƒ@@UXUlKkklW@ašX„a@UƒKUaVUUV_@yXk@ƒ@a@U±w@UUW@_„mmw@wVw„mUaÇbUa¯UUkmWkn±JÅxmIbUxmKmn—JWw„kUaƒK@a¯@ƒbk@mVUIWƒ—Lmwm@Ua@WJUb@LUl™@UUmLUbWJ@VL@VmXWWzUJUꄘ"],"encodeOffsets":[[116641,35280]]}},{"type":"Feature","id":"4108","properties":{"name":"焦作市","cp":[112.8406,35.1508],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@V@VL@x@bXŽWV@XkššlUŽWX@J„@nI@KlL„KšUVaV@œJlL@KUk@KÞL‚l²_‚@nWlL„UVVš@nLWVUJVn@anV@a„wÞUVLVx„b„@lW„@lbXn‚Vn@@¼šL°mšKVn@bnl@nVK@blb„L„W„U@VWLXV@nlKn@lVVbXw°nV_@¥Vƒl@XI@mlƒkkV¯VWnI@W‚@n¹nƒ@aWKXUƒaWk@yk@k„ċUkVmbk@WI—yóImÝkkwm@™mU@™xŁ›lU@mJƒX™ak@ƒx¯V@¼¯Vm„UmmIkVWK@UXIl@UWVUU@mVUI¯b¯@™lmKzWKUa™nƒJ@nƒlbÝ@@b"],"encodeOffsets":[[114728,35888]]}},{"type":"Feature","id":"4110","properties":{"name":"许昌市","cp":[113.6975,34.0466],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@lI„VnKlnVlnLVbšJlb„@ULVlUXVVX@‚a@KšI@wn@„aVV‚@nwnKlX„W°lVnKUX„x˜@„ln_°JVIXy‚XnW@U‚K@UXIVanKVVš@Vk@KVaXI‚@Vbn@nx˜KnaU™l™ƒn™Va@ƒXa@™VçUUla@aUK@wmUƒLk`kIWVkLmK@V@XUlƒn@JXV@nm„™bU‚óIƒmUa±@@ÑóVUUk@UlKVU@akWVUUlUUaUK@UUKWbUkÅJ@XWaƒ@XbmJ@nUJ@bUKƒLÝaUnk@›lXbWbXnm˜n¦lVXnWbUbVV@VkL@VmLaWl@n™b@bk@UVWak@WVImJUbUlmz@lUbkL@lVx"],"encodeOffsets":[[115797,35089]]}},{"type":"Feature","id":"4109","properties":{"name":"濮阳市","cp":[115.1917,35.799],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@lLXbW‚XXƒx@bVVnLllVxULUl‚XXlVlUnlŽU¦Ub¯l˜nœK@V‚bVb@šXbVL„KVxVVnIlašb„a„¥lU@wnalLnVVlVLXnlWVXn@@lVI@WnU@mƒÅW¥—aW_k@WwXy@kmƒ@wU„mš„š¦šlUxVLV@UwšJ°xš@VX„@Vb„@š`VX@VX@llšIVbnJlI„bšV„l„˜J@ƒmѯLóa@ƒƒKUa„k™ƒ™Xƒ@UK@wU@ƒlWUUݯImW¯aƒLUKU@ƒkƒ»k@mƒwƒa@UnKWI@ƒUU@akVWK—k@a±ƒbóUWKXUmk™KUmLƒbUx„„@lmLXŽƒ@@b„VW¦Un™JkbWnXl"],"encodeOffsets":[[117642,36501]]}},{"type":"Feature","id":"4111","properties":{"name":"漯河市","cp":[113.8733,33.6951],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@@Lƒ‚UnVxnIWa„@Xb@WÆIVlXaVL@VVLVbkVVŽUVlX@bUVkLV‚l@VVôU@Ò²@Vb„nôJVšanƒ@mWU@I„mVk@WkI@wmak™@wlW@w„@VbnLVb°bVyX™V_@aUKVVK@wUU@™™a™K@kmbXVmJUXƒ`kn™nƒK@aU@mw™akb±@¯ƒUUÝKUUU@WU@VkLUKU@mUmJUU@WVkL@UWJ—X@VVL@lVlUbšLVKnêƎ"],"encodeOffsets":[[116348,34431]]}},{"type":"Feature","id":"4106","properties":{"name":"鹤壁市","cp":[114.3787,35.744],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@ó™™n@xVVólƒ@¯zƒJ@bkl@@„kVWLUVmVXbVJnnlLlš¯@Xlm„°bVš—lWb@bšKVXnJ@VV„°nX@@w„WVklU„K@knVVKmkUKUaVkƒWkl»nwlŽ°lö@lXšV°UVbXKV@šša„Jšw@Um™™kUy¯UUUƒaƒK@U™L@mm@XaÇkkmWank"],"encodeOffsets":[[117158,36338]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/hu_bei_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"4228","properties":{"name":"恩施土家族苗族自治州","cp":[109.5007,30.2563],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@VK‚bX@lbUVnL°„@VlVnUl@VUX@„aVƒmaXƒlašUUU@wmaVUn@Vƒnmmk@m™U@kna™aU¥Vam™X_@WƒU™mW@_kƒVaVKnL‚lœ@VVal@k¥@kUW@kUKVUlUVсW@kÇaU»ValmkUVUVak™@aƒV¯_@W‚UkmVUlU@aœƒƒalI@akkVWUaWXUWwœWVbÆ@„„l„alIVK@U™m@UU„W@al²a‚¯UağÇm@ƒbkk@wƒ@@W™aULmxƒIU‚™ƒb¯@U`UX™JmL¯aƒKX›WUL@aknmK™@aWUXaWm@I@UÅmVU@™™aUV@b™VƒI@WkU›bXkm@VakwUKULWKXmJ@XUK@ƒmL@KUwVaUI@KU@mmn™mXka@»V@@UUaƒw¯yVk@ƒUUVmmkÛÈU@mWUnmx„šmlUbV¦UlbWVUL@UUƒ™IUmÇKV„VbUVVxkn™LUxV`VX@š„„kJVVUXWaUVVlUnmKUbkI@WULmK@L@LVlƒLnmUIWV@aknƒ`VXUJIVlUVVbUX@¤mbnLm‚m@UXk@mm@Ukaƒ¥@kV@@KkU@aUKWbkLWVkIVŽk@UbVlmX@bU@@mmL@bn`@Ln@llVLVk„@XVVU@`VXUš‚¼k`VULka@VllVIn¤VU@@bl܃bkx@bkL›škKƒn@bn@@b@JUnV`UnVbVKlVXUlbn@°ƒVx„@@b„nVbUllVn@V—VK@UnW@UVUšlnk‚VÈޚxVb„VVI„xVaÆ@@aka@UVaU@@a„k@Wl@nbVIƎ@Jk@„L@VlXnlla@VJnw@UmwXU@aVK°ÒnllnLlb„xnKVaV@l¦²nVl@llL„x@XVVœ‚Ķš@našx@U@al™XUVa‚LÈþV°XxWXkK@šmLnlUb@b‚xnLVlVVkb@UJ@xWXXš"],"encodeOffsets":[[112816,32052]]}},{"type":"Feature","id":"4203","properties":{"name":"十堰市","cp":[110.5115,32.3877],"childNum":9},"geometry":{"type":"MultiPolygon","coordinates":[["@@@a@w@kV@nbVK@ƒnUla„@la„Ål@nlVakwWX@WkLšaVmšwV@anK@UlIXmWkk@@mmLkWlwk@U_mKXwWK@U¯K@UU@ƒVUa™kmƒkI™yUUVUmanU@mlwkƒ@_mWXaƒUWU@ǃ@U@aUaVwUKUIƒVkK@UWIXƒmaV@k@Vm@UnwlƒUamk@V@„ULUamxUJkU@Iƒ`WkkK¯XWak@@W@IUV™LWJkXkaÇVUKƒ@kUmbmUUƒUKƒbkKWUkI@ƒkKÝ@@aƒUm»nI@mƒU@UnWV_@aUmWbkLUl¯b@a›kkk@WkkJm_k@UV±@J@b›nU@@WÝIUJVbXL@nlJkx@„Wn@VkJmb—LmUƒ`VbUL@xVn„@XVƒŽ@„mVVnnJVbU„ƒx@„V„nVUbVVƒx@šn„™bUK@bƒ„@bƒJ„šm²„VU‚lbXzVJV„„JVbn@@Xmb@V@bVJÈ@‚Vnkn@°aVVV@šX„KnalLVmšUnnVKVlnLWlXX„Klk°š™šXŽWškLUVVV@nU@ml¯nmbk@W`Å@mb—LWm¯UƒxnêVèk@mbƒVƒnUK™@kKmXk@@JUI›lÛLllnbVnlJ@LULnlÆaVLnŽV@nkVJ„@lkô@²bÆm°w„L„WV@VXšKšVXI@W°ÆVšK„b°U„JVIVV„¦XKVL@l‚InaVÝnUl@@bX@‚™nmVL@lVL„lVLVUnbVW@xXn˜bœU°¤V@š™„a@kWKUUn@VlnL@UV@Ü»@mX@V_ƒakaÞ@VK‚¯@kkW"],["@@mUkUUm@nllVKXXVK"]],"encodeOffsets":[[[113918,33739]],[[113817,32811]]]}},{"type":"Feature","id":"4205","properties":{"name":"宜昌市","cp":[111.1707,30.7617],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@°`„U@blšUbUVlVkn‚ŽUbV¼Èb@l‚XUÒkVUVVL@lVX@ll¦k@UbU‚›@kmKULUbl„@`nXšŽ„V@XW`nšUbV¦šbmb@lšV@nnlmnU„m@UVnb@xVV™VkbW„nb‚VnVa@an@UaVU‚JXnWlXX@l„¦@ŽlKÆX„bX‚V@VV„@°¯°xXx‚XV@nV°UVWU_VWXkmaVnWVkn@lln@lb@UVLXWlnX@˜aXUmaVK@UXU„U@WVI‚W„XXV‚U@¥VKœ@‚Uގ„„‚a²LlV@kV@UanKma@UVUnK@UVLXyVL‚knJ@UV@@UXKWUXaV@Vb@mVLnKW„m@aUUm@@UkK@Ula„LXKWaXI@alKlmUk@wVKXL@m@WWn@UVa@K@wna@aW_XWWkXbVW@k@U¯WWwka@UUaVIVƒkU@m±@U@@wVKkaš_@VV@XUVwU¥‚šyUkm@V±ÈUKk»ÇL„m˜mLk@ó£kmWwƒm@U„IkWKXwWU@ƒkLƒwkbmaƒbkK@VƒLkmWIUKkUUƒÇIǫJ™XÅJULVŽÇLUVƒ@UK™@kI@WVI@UaƒWmXVVUL`±kÅLmKkƒƒkƒÅ@Ua›XXxWVXŽVbUXll@bkJ„b›„@bkVUVlnV@X"],"encodeOffsets":[[112906,30961]]}},{"type":"Feature","id":"4206","properties":{"name":"襄樊市","cp":[111.9397,31.9263],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@@Xl@Xb°WlLXl„_@JlVVInwVbVK@ƒ@UnlVbk„mx@VUnl@U@nbW„XJ@VlL„UVJVLUxVb@b@VȄ‚@XV„VWbnX@`l„kx@nmVnbUVVVšzlJn„šlVb„UV@@V°L@VXLWxnLV`l@kxlXnK@nl@XlWn„`Xnl@@UVa@VÈKš£VLVanW°U@UVU„@„`VIn‚mV@„nV@Xa@aVW@UšalkXKšblI„yƍXnlJXbl@@VV@nklU@`„nVK„LVKVb@V„U@UÈK„UVKšIlUX@V`lIVbn@nblVVmV@@XXJšUVV@knKVn@`@X‚VnK„wlLVmUUU@ƒU@aXL@WlU@UUW@UmU@KkLWaXkWmXUWm@U@ƒnk@UmK@U@UaUVUUKV_@al@namWUI@KUƒK@aV@WUIƒbƒ¥ULUJkIm™ƒK@U@K™V@U@a@UkU@K@wVaUwlU@mUƒULmKUkV@@anIWmUK@I¯„mKkl@LUb±lUakLmk@WwUKÝVUIm`¯n@Uk@makJU_@ƒƒJma¯ImwUVkKƒb™aUÅ@wWaU@VU@mXIVmmUkJkwm@mIlUKWzUK@VmLUV@VnbmLVbU@@lkU±KbƒƒÝV›@UL@¦VWUƒWXUJ@XƒVWV@VULnbWV—bW@kmWXUK@Vkam@kkm@UlmXUŽnbWlUXV`UX¯VmUU@Ul@Lll@nnJ@LƒnWmbmš@b™`ƒš","@@kUUm@nllVKXXVKmU"],"encodeOffsets":[[113423,32597],[113794,32800]]}},{"type":"Feature","id":"4211","properties":{"name":"黄冈市","cp":[115.2686,30.6628],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@VVUnWVXnVJ@„‚U@V@VXŽV@@IVJUnŽ@V@L@KlIVlVanLVbnVlI„ƒn@@a@Kl@@I„JlI@aXU@KlK„kVblJXU„VlU@V„bVkVKXn@VlxVa²I@VlVUxln@bšJXklaVWnLmÅ@y@k@ašI@W@aXIlVVaV@nnlKnLVW@IUa@a@K„UVVlI@wXKVV@IUƒla„@lUXwWƒnƒnalLlxXLll°@XwVKVaXIl™nb˜@nln@Va@U@k°ƒUmÆUVaXI„JV¯ÇUmmkU@WaKmakVm@U@aVKkkmKkVmIkÇ°£@aUUVaVVnKlkX‚mkƒ@ƒlUVaX@@Um@‚™UmlUXV„UVU@w‚K²¥Ua@I@UV™l@U™V±UIUÇ°»VkUmVI@a@U™m™ĉ™¯V±bŹĖğaÇL¯lmŽkX@‚óĀ@ŽmšÝêb±WkLƒn@xXx@Ž@b@V@LW@UbƒlţXƒ`kxWnXô¯¦ÆV@L@JVLƒxkK@V@bkz°l‚lXz@J„UlVla@XUV„bVKXnW`XXV@laVV@V„X@V¯xƒx@xULVbUJ@n@LU@VmmakbUK@b™IWWUUVkUmkLm@VJkb@nUJƒ@`V@kX™aUaVmmLkUmJ@Uk@U„±lkzmJUb@b„VUxVXU¤ƒL@JƒX@VlL@JkLUVU@mnUl„¦@V"],"encodeOffsets":[[117181,32063]]}},{"type":"Feature","id":"4210","properties":{"name":"荆州市","cp":[113.291,30.0092],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ÈJV„lVVLXJln„K@UlL„anbla„xlK@„XVWxXLlƒJ@V„nXxlnô¤l@nKn—‚ƒÈKl¼VL²Ç‚Un@Vl™zŽV¦UxWVU@@U™`lbUL@xV@²@@nlVU„UJVb@VlbXx°XVWX_VKUwVKVa@UVKUUVk@KnblaUU@wnWl@UX@lÆ@@a„IVmUk„™šxVJ„U„bܙ@Uk@WWnk@Vƒ„™Vm@I@m@Un@m™XUlVlUnJ@knJVU°@@aÆLX@ƒllL@¦nJV@XblLVa²U@UlWš@VX@`@LV@@bXJlIXml_lJœU°b„KÆLnVVl‚@ö—Vƒ‚mXaVIĢllUlVnLVlX@@b‚ašnnxšV„L‚bn@°ÆXmmkĉƒ¯w±™™™Uċ@KÝÅƧŃÝ癙Uw¯ƒm™¯k@W‚kV@¯UIUJW¼kb™Uƒwk@W`@¦Uônb@VƚlÈ@VU@ƒƒ£UWWnUÆUnmJkUÇ£VWUI@aUU@WkI@Uƒa@JW@k£kaWVUKmnkKƒb™kkVWb—VmUUmwU@kk›@UakUUa@V@nlx@lUb±lUbnnWLUyk@UamœUK™@mlk@Wb@VXL@x@xWI@a¯Ž¯V@bVn@LkKmL@`XmKmVU@@bkL@V±bk@Uaƒa™L™KUVƒIƒ„™W™XamVVbUK@b@Lm@UWkxULWVUnm@UlUX"],"encodeOffsets":[[113918,30764]]}},{"type":"Feature","id":"4208","properties":{"name":"荆门市","cp":[112.6758,30.9979],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@n@lxlInVUnWJ@nUVV@Xb@xVƚb„alLVUnx°Jnb„I@„V`lInbl@@V°mn_VJÞUVLXx‚@nllKVb²kVa@KlknL°ƒ@JVLXnmJ@bU@VlnLVKV„@nX@lUšKVaXal@VKn@¥°L@Unw˜bnašV@KV@VUX@lVXI@KW@@IXWV@laVL„„KlaXUVVnkVWV@lwXblIXWVkVmšaU£VaUmVIkU@y@WakKUamU@UUK@kmK@w@@mK@LƒV¯™U@WwkmULƒamVVUU@ƒƒIƒbUKUa™kmƒm@UakLmxU@UÒWlULţÿmwkIUm@a‚kÈblW@UVƒUUk@JW@XkWWUkUKUIlw@aUWknWUUmnIWƒ™aUwVaۚƒaƒVUI™wƒšVlUnƒJ@bÅ@@kVWk@mX@xVVkbma@LUlVVUL@VUbULVxULW`UX@V@lUXWaXlWXX`@bmb@x@LUb@VmŽXX@‚@nWKUL@xVlknkL@bWJXbWLƒKkb@VlL@Vn@VV@bƒnX‚mLUK@nUaU@WbXVWL@VU@@V"],"encodeOffsets":[[114548,31984]]}},{"type":"Feature","id":"4212","properties":{"name":"咸宁市","cp":[114.2578,29.6631],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@ÞƂLČ@šV‚š²š°xĊ„nlWnŎ¯m@aƒK@„„°‚n„Jšwn™VIUaÆJšÅ@wšwV™XW@aV_l@²V°lĊwlaXLšwlUkalVVaX@lVXI@a˜UXJ@U°UU¥VIVKVklanLVa@VÈIVV@nk@aVa@mV_@a„K@klKUa@UnKWk@@lU@@UW@@nUWUwmaVIXƒ„lV@mLXblJ@kV@kk@KU@WƒkUWVÅwkLmW@UmL@lUL™KULƒak@maUUÝwUJƒIb›KUUƒ@š™aWK@kUWVkUwVw@™mÝ@™I@wkW@a›ww@LU¥™kƒJ@nVJƒIkVVnkV›UkyUIUl@xWUkaW@@°kz„ŽWxkLUWmzk@@bVVVš„b@‚@XlVœ@Vl@bVbUn™`Wn—@Wb„VVI@`„LVbXLV`mnU@@lƒL@LUŽƒak@ƒLk@WbUJn¦@lVb@xVb@n"],"encodeOffsets":[[116303,30567]]}},{"type":"Feature","id":"4213","properties":{"name":"随州市","cp":[113.4338,31.8768],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@„@nš`lw„k„ƒ„UmUVWX@lk„@VanUĠ¼V@@mX@@nVV‚VXLmJVLnK@b„V@@J„@VUn@VaVUUUVWVLV@@Kk_@almaVkUU@WVƒVUVLXmmk@wUaUKUV@°™@kmaUaÈmW„mUƒVklaX@lVnxl@@UnaUk@ƒVUVwVK„nš@VVn@VbVJUknUmmVmk_Vw„KUUm™Vak¥@UVKVIkW@UmIVWkIVƒkmmLkwmVUƒ@LƒUU@VVXL@JmLUbmK@UUKmkKUUmVUaUnÇlk¯™mJUnmLUaUJUaWL@UkJ™ƒUƒ@ƒaklkU@¯@KWLUmUUWVkbƒLƒŽUKkbU@WX@JX@@LWJkUW@UVU@@L™Umb—amx@V¯K@¦mŽULk@WbUb™LkVW@kVVxUb@x@LlV@V@b@VšU@L@V„LnšlJVIVK„¦„aVJ@XUŽ@b„LV‚@LVJnXmbk@@bU`VLUVV‚b@V@VnL@Vml@„@VXnWVXnWlXblK@LnV@VVX@VkV@XWK@b„VV@VV"],"encodeOffsets":[[115830,33154]]}},{"type":"Feature","id":"4209","properties":{"name":"孝感市","cp":[113.9502,31.1188],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@VnXK@L@°lVlk„b„@„VšlI@VXKVbVIVbnKVmnI°šlŽÈkVmVbnUVVlLnVL@VnLVanK@IWKUUV@„V@KV„nUlxnKlnU„lJUXnJ@VlXUJUL@Vl¦UbnšVVƒLUxl`UnnnmVVlnVK„bšmVX@a°Ý°LšaXJV@VUnKVXVK@LnKlLUbVVX@VwVJVn„@@UU¥V@@UUK@ƒmaUVUkkJ@L@K@UmVUI@JU@W@U@UV@ƒUIWmXUVmUUÇ@UVmIlmnmakK@akaW@UwVUkKVnUlKVwk™ƒVU_WKUkVW@UXaWkUa@w@VU@XaW±@IkbƒKƒb¯L@WƒXkWƒ@UakL@UV@UmVUmL@UXWVL@ašUƒVUUUVU@yUUƒIUa@wUKWVU@kƒ™™Wk¯UkwVKƒLUx™K@nVxUlUUWVUmw@wƒUUyXWlX¦WbUV@„U‚@blbUVVbXXƒl@lVL@bk@lxkVVnVx™¦ƒ`UnkL@V@L@Ž‚@@xnL@lVL@VnVVblLXb@‚@zlVUJVnUbV¤™bUnUlWXkJWakxU@UXml"],"encodeOffsets":[[116033,32091]]}},{"type":"Feature","id":"4201","properties":{"name":"武汉市","cp":[114.3896,30.6628],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@nbnm‚knJVUÈ@@Uƒ¥VknmV@VUlK@IkK@U„W@I„KV£UWVwƒU@aVanIly²kVƒl@@VnIlVnKUnVbšblWU@@_„‚VI@mlaUIn@lKVnUlVVXXšJ@aVLlanbUnV@@K@mVIUaVK@w„w°w@UƒW@UUUkbU@WWX_WmULƒaVU@WkbkUƒV@IWyk¯kly@a@UlL„wUK@I@KÅUW@ѱUm@wl¥kaƒ@@_Vw@ķƒa@akw@ƒkKW£XVUVwVwUaU@VUU™™xWKkbĉx¯k±Uk@U`@bWXUš™x@x™ÆÅIVbUJmš™xƒImƒ¯@ƒ™Umx™nUVVbnJV„@Lƒ@@ŽkV@bVnƒ@UVULlx°VXlššl„V@XUVL@xVb„JVV@zUVVVUV„™V@bUKWX@VnKUVVnU@@VlKVb„@lX„W@X°K„a„Lla@JX²Wb@ŽUV@@xVbXlWb@VUXVlXLV`Uš„lŽUxkLmVUŽlLUVVxX@lb@blL"],"encodeOffsets":[[117000,32097]]}},{"type":"Feature","id":"4202","properties":{"name":"黄石市","cp":[115.0159,29.9213],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@VšUVV@VbUx„aWUœblUVmnKlX@bXJVIlVUxVVVIU‚zlx¯š@‚VbnL@x‚x@UVaXK„b˜@Xk‚WU_Vm²klW„XVK„Žl@nXV@@w„mlK²X‚aÞén™@ôÿ@lWn°kUKmmUљUmm@ƒwkImWU@UakL@bVLUVċ@™bUK@alIXKWK@™nXnKmkUVwƒ@¯b@L„lUL±W™n@KULUaW@kL@lƒL@bU`@nUb@bmlU@UÇJ@UUbmKkblŽUULUJV¦¯V@VWI—V@bWJkUW@UbkUlbkV"],"encodeOffsets":[[117282,30685]]}},{"type":"Feature","id":"429021","properties":{"name":"神农架林区","cp":[110.4565,31.5802],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@n`lIXll@lœl@b°aVklKXaVn@bU`mX@V„V@nmJn¼„V@bÞ@lL@„lJXVlL„aVLV„nVnalV„@VLÈUlblWXIšKVU@J„™š_‚@an™na‚X„m@KmI@mkk@KVkWWw¯w¯°ƒ@UUU@WƒaÅWkL@ƒ¥@kWWXkWmIUVVbm@@bUbmUU„ƒbW@UVk@mVkU@U¯ƒmKVUkaW@aULƒÆVbƒb@VÅ@Un@VƒLWl¯Lš„"],"encodeOffsets":[[112624,32266]]}},{"type":"Feature","id":"429006","properties":{"name":"天门市","cp":[113.0273,30.6409],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@@K@UlKVm„_š¥UwUmlUkwl@@aUK@k„kWWUaVUka@aV@ƒVUXaW¥Xk@WWIklm@ÅxmI™VÝUkxkaƒ„@bWJaUL@„W@™l¯UULU‚ƒbƒkV™Ua¯bm¤UnÇUkmUšUx˜b@VkXÇal@bVnlJnxŤĀVKXkVÑV@nwlKVbn@n„šlVbVL„a„J@„VV‚UnU„bVKlnXxV@°š„U@KnL"],"encodeOffsets":[[116056,31636]]}},{"type":"Feature","id":"429004","properties":{"name":"仙桃市","cp":[113.3789,30.3003],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VK°VškX@@ƒVK‚bXI@a„ƒlblwÞVšUnJÆwn@lkXJ@X‚WVz„V@xnx‚VXUVVVkUw@mšLVw„KVU„@Um@alU@„@@KUƒmIUaVUšmnwmw™mb@aW@UkmKkUkVġkUJWbnU„õ˜@UkmUÅKƒL¯a›VkIk`WnkJƒ@xVLUVVbUbk@WlXbm„VxnxUblbUV™@@VUV@nVL"],"encodeOffsets":[[115662,31259]]}},{"type":"Feature","id":"429005","properties":{"name":"潜江市","cp":[112.7637,30.3607],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@UbVxšbX„mJVnXVlmVX@bkxVJVLVlXXWlX@@IVl„V‚U—aVwV™lnÈVVmn£°aVbUš„l„aVUK@mVU@Uš@VUkaVamwUwnƒWaXkl@VaUaVUUK@w„WI@aU@@K@_UW™@kX@V±VUbkKWaU@mI@¥kK„kW@ÅK@b¯@UVmI@lmIkVkUWVnšm@@V@n@JUnƒšU„@ŽmlXXl@@V"],"encodeOffsets":[[115234,31118]]}},{"type":"Feature","id":"4207","properties":{"name":"鄂州市","cp":[114.7302,30.4102],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@°¥WóXmlw„_ŤW„kVaX@@K@U@a@WwU@mWk@ƒULƒWkX±lUnV`XWl—@ƒaWLUb@Vw@wmKUa@°™kw‚yVUJUUVwkUUJWI@akWmLUnkV›aXVƒbUxUVWX¤lL@„lx@b„b@ĸUx@`„@lbk¦@x‚n²VƄX@"],"encodeOffsets":[[117541,31349]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/hu_nan_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"4312","properties":{"name":"怀化市","cp":[109.9512,27.4438],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@@n„‚@b@XnJ@k°x@aVUnl‚UXnV@@VnJWUJV„nIVV°ŽUbVVVL@Ž²LUVa°V@aV@nm‚UXblLXWVXVmVLVK@an_„`@X@l°„VlXXW`nX@Jmn@b„@nV@Lm`„bUb‚n@VUVl@nIVbUlƒV@LkJUnVV@xVblVUbU@ƒzUKU@mx@xUnn@@WV@lbUb@šnVWXX‚V@VIV@VUnJ@VUz@JWbXllI@VXVVL@ŽVn@„„Wlb@„Žl„XVlL„aV@VJ@XX`„kVwVl@bk„‚bUŽlVXIlƒnLVa„mVwV@@nV@XaVJVbX@lwV@n„@nV@VWnIVVUŽÆ@Xx‚a@I„UUKmk@mVƒ„IXmWUš™VJnUVU@anaVwk™›U@UXa@W™@m_@a¯@@K@UVƒ„bnK@blIlbXa@WW_n@VƒU@¯bmyƒUkUJÇÅ@WU@kWKÅwƒnm°KVkmankVWnXVWV@UƒƒwXkV@mƒ„UlLnaƒVaX@VUn@VnVK@xlnXWšU@a™@@klak™Vw™mUaV@™wmIÛ`m—@mVUXmlIXƒV‚I@K@aU@UaV_UK@wkUmmUKWXŽmVkUƒL@mƒƒU_nK‚™@aVU@Ukak»@U™™@ymUƒ„¯™ƒUUƒVKkam@™nka@ƒmwkLWb¯mkaƒ_VaVKUƒ™IUw@kKmU@WK@UnƒmaULkU@wUalWV¹U@@WUI@WU@‚_@W@U@mƒU@WbbUK@Um@@UmbUwWWkk@WU„a@anUUwlWUwUU@wlJVUnnV@@mnI@m‚K@U@w„a@wUm@_mƒVUUaVUkƒƒƒ_kċUk™VWLƒ@mlU@kn¥W@UwUWV@VÝU@lXLWVUbVLXlVIl‚knmU@VUJk@@„ƒ@™kVmwmVkxU@@XmVUb@xnKVLl@VxUxkIU`@bWVXX@JWL@bkb„¤@bmUUU¯Kƒkmb@V™VU„VVn@@„Vb@`lnœxmb„lUn‚bk„@xU„mV@bmWbUV@VJ„Il@nVUb‚K@nn@VbnJVIlJVkXJ@X@lmx@bnnWVXJWXU@UlU@mk@@llb°x„IUbnJ@VWbXVmI@JVX@bk‚@bWL@JUXUK@U@Uƒ`n@@Xm@XVW@@nX@@`ƒImxU@@JUI@KƒLmK@UÅUUV@VW@™¯kUU@UamVUUmJ@n„xmLKƒkmJkwkKm_mKXU@aƒU@b@Wk@ma@zUJVUmbUlU@™xnXlWlXXblK„¤V@@nUVVLkVš„l@Xb@VVK‚nXKVx@znW@X‚@@lVK@X@JXbWbnn@JUamLVVXIVxnK@aWUX@˜x@VnI@WlI@anV„IVxk‚l@lbXXšxVVVJVInbV@@ln¦ml@XXVWbkJWb","@@XLVKVXVKUa@UUUmV@l"],"encodeOffsets":[[112050,28384],[112174,27394]]}},{"type":"Feature","id":"4311","properties":{"name":"永州市","cp":[111.709,25.752],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@lxUXV‚lXUVnlVĢ„JVbUXVJV@XUW¯„VIUK@klW@Un@„nl@V`XUVL@l@šVx@„XXW`UnUbšxUlVnUšV„lb@VnJšUVVVInJlUšVnwVklKnw„LVJVšV@nIV@nbVa@KVVVUUa„KV_nVVJ@_VW„nV@n¥lI@anƒl¥X_VKlwVlULUVVVš@šU@VXL˜ƒ@IUmn@VU@wmKXUWU@m²šl@VIXWWkWUkWlkIVamUXamUnmWUU@@Un™lK@XJl@kVUk@mWKXkl@@aVU@UVWUUVa„In`VUVLnw@U@K@Uƒƒ@w@UVmUUƒ™°K@UnV@bV@Xk@KVm@amk„aU£VWUUmUUwm`UbULka›KXU@kVmU™@aV_UWVIn@˜y„XXK@klmV„V_kWVUn@WUU@UƒmaU@™wnwWanUmmXkƒam@UakLmK@b™xUUUU@Km¥Vaƒ¯@ƒkUaVUlm„UU@mUUÇmUk™Uyƒb™bUa™XUWWbÅLmL@V™aL@WWXUKmmk@a@UUK™XW¥kU@VƒUkxmVkUWbUJnVJ@nVJXzWxkŽ@lVbUX@VVL@`mbUnšŽUn™VV¼k@Ulm@mwLƒb@lmLUK@UamƒWkƒK@£Ua@ƒ›UkJkUmbVlkX@bWbUŽVŽnnUVl„@bšbVK@VX@lb„V@nU¤šx‚²„Knblb@x„V„ô@šlŽ@b@l@XWxnVl@„VV@XLVl‚LUŽUXV`šbXXmJU@@bm@UUkLW@UlUKWUUb™wUm™L@nklVVmVXXm@@bUKlÆn„‚XkllVUVVL@nUbV‚@V@nnV@xUn¯U@JW@UX@xĉ@™`m@@LV@b"],"encodeOffsets":[[113671,26989]]}},{"type":"Feature","id":"4305","properties":{"name":"邵阳市","cp":[110.9619,26.8121],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@XIlJšI„VVK@n@VVVKnLVwVmnLVK@U„@šw„J@wVIƚ°X@ÜȄUÈxll@kn@VwVaXJWXn@@WVL@UUKVKV_U@@aVK„x@U„aV@lk„@XylbUaV_šVnal@W„U@a„I@aV@@aVUl@Xm‚UXWaXml@@kk@ma@V_UnUV™UUWJUa@kkaWLUmk@@LUVWUkJWkK@¼UnWJƒIkV@b@JUIm@Ul™V™m@Uw@a@kWƒXWKUknW@ƒWUU@k™mx™UkVmIUJUU™VmI@UkaUƒV™UmVk™wVaVmX_WW@ƒUw@™@kUKWVU_k@ƒmm@@VkX@lVLUJƒX°WVU@UIVWUaƒIUġmkVUkWUVWkwWXk`mI@¥kUVƒUƒUn±@m›XkWknV„UVmmU@@XƒVƒUk`@Xƒƒƒk@¥¯»mbĉó@mkU@kU™ƒƒ™KmX@˜UnmL@lULkKUƒWUU@ƒbUaUnƒ@Vb@l„¦Ub@l™@UKmnƒKUnl„UVVbUVn„@`Vn@xƒb@x@VL@nmJ@nU@mmUVkI@xVVVxkXVxmV@bƒbXVl@Xl‚XVxna@Vn@@VVL‚aXaV@n„‚@@V@X`V@@XVJ@XV@UºkXVb@xlVVKnbm„@VXLV@n‚lL@VxšJV„ULUb„`lb°nXalKnx@„lbšmn@lbULV„„V°š„ƒnV@zšš@Vl¼lb@VUV@bšmLV`„„@n„KlVnU‚XWVLnnlV@xVLU`VbV@"],"encodeOffsets":[[113535,28322]]}},{"type":"Feature","id":"4310","properties":{"name":"郴州市","cp":[113.2361,25.8673],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@²zVaVlnVl@nšVk„Jl_XJlIVmnL@mV@VXn@lV@‚XzV@lyV¯²U@UlJ@XVKnVVIXl@UVLV`@n@J„I@mlI„KVLnUlVUVVLXašKVLl@nb@ŽW„XV°KUnVV„L@xVJ„L@b@LUVVVU„˜VXbmbVbn@@lUbm@x@XVVVŽ@@˜@bkImx@Vm@Xbƒb@l°XU¤„a‚L„mnL@bl@@™VUX@VxnV˜anLnƒWƒ¥XKVwnUWXmVIUWÆLVx„L„w@wVmlU@¥XƒWUkwlÇn_Uw„WV@VU°wnU—ƒy@aVškVlnL@lVn„w@VlJ@b„X„x@bVKnb@U@WVUl@@Vnbl@XLlK@aVLVKnxÞn@a„LlmUaVU™ƒm@ÅknUmaUKmVk@m™kk@UlWUkVm@w@kUU@W™U¯™¥@w„Ç@aVIlUV@kUWU@UUm»@k@mKVkUKUwƒaUaUa›@k„kUWJkImaU@UK™@maUzk`@zƒy@XmJkL@UUJmUkV@z›@kŽkVmK@¦UbWL@a@UbmKmwUK™Xk›VUUkmVkw@UUKmL@WUIWa—JW_k@@WmI@mk@WkWULUUVKUUVm@šU„bš@‚nUǃ@U@w„™V@Ua@aƒL@ak„›l@k™UƒJƒwó@@L@V@„™`@œƒJ@xnn™šmV@bkJmUó@ƒn—JW„UUmƒU@UV@Lk„WlnnmVXbmxšxV@nbV„V@XVm@UVlXU`ƒUŽkn@lWLƒW—zm@UJVXU`@bVšUn@lWVœLlbVKVan_VxnVVVUXV¤ƒbnl@bUn@LWlU@@amU@V¯L„šVVUn@V@x„„@V@L@VmxUKUVm_ƒJUbVV"],"encodeOffsets":[[114930,26747]]}},{"type":"Feature","id":"4307","properties":{"name":"常德市","cp":[111.4014,29.2676],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@l™U™mkUwUyV™@VW@¯Va—VmUU@KVUVUVLnaWƒnkUÓV_@mVU@݄w@ƒka@kVmƒUmK@IkaUamKkXWaUW@WUk„™@@KVU@aU@™L@J@XÇVUKVak_mWkLWakVUbmLUUmlUVKUU@kUWW@UImJ@xkLkKm@@Xƒ@ó݃@UUk@UKƒV™ƒULƒKƒXkWWbkaƒIUƒWU@mUk@WLaUJġ™ƒ@@XÈÆVIl‚„Vnz°aV@U„m@X`@XWbkakJ@amLƒaU„@V@L°@@bn`š@@XWb@VœVlšUxmb@bUVmVUI™šXVWnƒJU„@nnlVLƒV@JbWzk`m@UVK²V‚x„k„LVl„@Vn@V„„°xVKVkœVVlUblx@bU„‚Æœ@@nVnUll„kx@VW@@VkLWxUL@bÝ@kKkVõV@bkXVVUVƒ@ƒVkUkV›LkV™a™@@™ƒ¯xUxmX@JVb°WXkK@Vm@k„Vb™bn¤‚xUXkJƒblxnXÆK²l‚_@Wnašn@ŽUL@b‚JnIlV„@lUœ@@¯ô@lWȂIVKVm„U@aXaV@lwVXn@@K@UVKUUnU‚bn@lWšX„ƒlJnUšLšKV@„„l@²a@UlK@aV@naVX„WV_nKlL@KUm@a°U°@VXL@a@wWmXal@„k„@VLn›V@@bl@VnX@mwVa²aVU@mk@"],"encodeOffsets":[[114976,30201]]}},{"type":"Feature","id":"4331","properties":{"name":"湘西土家族苗族自治州","cp":[109.7864,28.6743],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@@KšL@wnK±nƒnm‚—@WUk„ƒÜÈn@n»@mVamk„mšU„„l@V™nmmU@wUan¯VKšLn„VWlInyWUœI@WWk@KXU˜n@mnUmU@WœƒmkV@ƒkXašaVaUm‚Ikƒƒ@kaƒX@ƒUm@UKWU@UkJWkXa@IVy@UmIUVU@UJU@WXWmU@™VakaU@@Xm@Vm@wnwV@VL„yV@VakUUa@wUUVmlI@K„UVkUamJk@VU@UmVaƒan_@KmUƒ@@anm@ImWX_WWUk¯ƒ@k@Wƒ_m`@bULUKUnUWWXkKWaVmnU@@b¯UUbVŽ±K@UKUUVa¯UUmJUƒVIXmI@UU@WmVmkUV@b¯w@lmI@W@aƒ@m¯LXbmJVLklWL@V@XXŽmbVVU@@VU²Ul@VlX@bš`Xx›zUmkUVÒlŽ@bXLWxXVlš@V„bkLma@nmVmULVbmVUb@lnzmbUÒVl@°nLV„lJkn@bmJk_ƒVmmkblxÈx@LUb„xVb@V™n@JmLVŽUš@„nV@¦VbnJ@lVVbkx™bm@UxVLV@n`UnVVV„kl°z„xVb@VU@@ÆlXnWm¦nbVK@XVVUVVl@X„KUV@nVL@WnIWŽXLVKVLlxUbVKXVWbn@@UnKVLVb„JšU@aVU°b"],"encodeOffsets":[[112354,30325]]}},{"type":"Feature","id":"4304","properties":{"name":"衡阳市","cp":[112.4121,26.7902],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@lšV@XV@„mXVlXL„W‚X@l@bVxn@šŽšUVkn@VJ@I@alU„JXIVm@»‚LXllIXVVU@Kl@VnXKlb@lVbXIVVUšmVVU`@nbl@@lXLVVVKVbnXWJ@VXbWxXb„Ul™VK„¦nLVVUVVbšb„K@U˜LnK@Un@VxlUV`UnnL@VVL@JV@VUnxnKVbV@@VšIVUnJUVUl@nW„XllIUa„KVbÞLV¼²`V@VIUwlaVmXa@IWanK@U@m„kVƒVUVaX@lšnaVLÈ@‚¥@kkJUWJUaƒXkaUm‚wVXJ@_lWUU@¥n_‚KkamUK„™@amKƒnKƒbV£¯W@k„aWan@@UnwlJ@a@—@UUU@W‚wn@Va@km@UanaWa—UVƒUUVU@K@aƒKUI@wƒKUUVm¯LWUXƒ@mak@UK™LWbUKVUkUmVUKƒLkJ@nƒJ@I@mU_UK@VWkUJmUUL@WkI@V±VU°kzU@Wy@kUm@UWU@@nmKUnkJWIk`ƒIUlm™k@mUUkUb±yUX@VUV@bk@WlXL@nVlUl‚k@WI@ŽkLmš@VV@XVmnnVWbnVUblJXkVl‚XXlWXUJk@±™@nXVWVnL@xUVm@Vn@J—„WK@U™V™@UUVUVKUkkxULW`k¦m„@bkJm¦U@ƒmUX@`UImUU`ƒLVbUVUU@LUbmaU@mJU@U™UIƒKmxkLUl"],"encodeOffsets":[[114222,27484]]}},{"type":"Feature","id":"4306","properties":{"name":"岳阳市","cp":[113.2361,29.1357],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@@wUklmUUmU@@UVm@wUaV_mmUKmwkIkJmUUnm@™™@UUƒbUKUƒmÛamm¯xVLkbÇƃUƒVUzkVUlƒUUKWLX¦W@ƒVUUUaƒKUbmLKm„@akU@aƒmVaUUVIVWkk@wkƒƒ@@xmLlmÅwmbVlXlÝIWVkK@kkVƒL@VWKU@Ublnaƒƒm@b@bšnW`@XUJk@UUWKƒk@UKƒnn‚@xmLUVm@kbVbV„nV@V„b‚@KnV„LWšXŽÆVĢ¦VblŽš„n„UJWz@ƙVóUVbkV™aÅx@¦lVUbVVknWKƒ„k@ƒwƒK™VU„Å„ƒl@zkb@`m_mJ@xX„mbVbœ@llV@n„@llbXL˜UXalUšl„alVnwnLVKlšVbX@@I„V@blJ@bVL@VVVUXȤ‚VnkVÑXmlbnš‚„VKkÑř@UmaVç@±XUlI„xlV„@VaX¯lUVVUšVJn—V@°°nŽ°„Vxĸł°¦šb²¦lJ@U@aUK@kUm@_m±VIXal@„Kl@„bV@K„K@k„m@UmUUaƒK@_UJƒaXU˜@Xmš_VmUk@WUk›@kU@a@m@UƒaUUU@al@ny‚XXWWwkly@¯n@@bnV@k@mVI‚„œVlUUmlU„JUw„I‚bXƒVaUal@K„b@ƒVKVkXVl@VkUU@ylUœVVaVL"],"encodeOffsets":[[116888,29526]]}},{"type":"Feature","id":"4309","properties":{"name":"益阳市","cp":[111.731,28.3832],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@„ŽÆxXL@l‚V„@ĢšVI‚bXKl@nVV@„XVŽ„JlbXalX„W„LVKš„„UVLl@VV„@ôބ@@Wn@lLlK@wnIVJX@VX@lVVUL‚VnkVVnKValUXblKnXl`UbVLÈU@W@IšKV@@bUV@Lš@lƒXV‚@VXXblWnLVblb@JnL„VUn@llb@„ƒx@ÞUV@nU`VÔmlX„mbUKUVUV@LVVUn˜ŽUb@°UXš@U‚VzVxnlVškšVnlVnaWƒ@wnIn`@_la@y„kƃVƒšU„L„xl@„ƒXLlmUUVakU@¥ÆwšblUUaôVšU@ÅXyVImƒ™ƒkUaġ¥ÅUWX™ƒKmU@Lƒa@UmUUƒUalan@VUnK@wm„m‚L@V„lXLVVl@VI@WX_™m@a™¯mKUkwW¥UK@_UWWLUVkUWL@WUIkVƒU@JƒwkLUUmJVI@WkXm@VmkKUIU@mmm_@VUV™@™„kJċwUU@KUWkkW@IWW@km@klwkWVkkU™V¯m@kWLU`mIkmkXm@@`@L@xUKWkU@VL@JUU@mbUKVa¯WVnL@`lXUVkU@xW@UbUWVU@UJ@„lnU@m‚nÈmVƒa@bUL™wUb™@@VkxmUUƒ™UV›K@IƒUƒmk@akm@wmIƒŽkK@b™VWXkm@wULUmm@UVW@Ub„mbkKƒVn„U@Wl„xV„U@UXmWUXmlnbUl¯Lmn"],"encodeOffsets":[[113378,28981]]}},{"type":"Feature","id":"4301","properties":{"name":"长沙市","cp":[113.0823,28.2568],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@lVUllXkx@lln@‚XX@JlXXl‚V@LVVČxlIšƒš@VU@Un`nnV@VJlLUnn@lW@XUJnIVVlK„x@I„VlUVJ@XXKlVVUXKVX@`VLX¦lxVŽnLš°‚an@„„‚bkmVaV@XL@U„KlU@llLXUÞJWkUknaÆxnŽ‚knK@w„@l„@xllUXUJVVUb„n@blV@bnƒ‚LnKVa„LVbVV„UX@W¥XKVL„VVklUVy„U„VÈÅlaUK°wnnÜbn‚V„VL„aVVš@šn@VmnVlIlJna„@Valkn@na@amwm@„UXw˜K@aUUVUUaVa—wWK@kU@UaW@kKUUƒƒ@k™W¯XWan@k„™mmÅ@@I@U@KmLkaVUƒKkLWVUƒk@UVmU@am@kkk¥ƒUƒVUK™„maUb@ŽUb™I@aƒKkkWm@W¯K¯b@VmaULVxUXlVk@UxVJVbUb@xULƒ@ULWW—LƒĕmxVVL@šVb™KUwƒaŲWwX@@WƒUWLU@VbkV@aU@@VUnmJ@VUn@VƒLUK@U‚mUIk@UÇmU@@UW@J@LƒbUmVI@aUmW@@bkXUx@lmLUbm@UbkJ@V@XmlUbkKm@ma@kUaVU@aUK@mImJUIkVƒUƒVUakbWwka@UWKkLUamKUXm`Å_U˜ƒULmaU@@lUV@X"],"encodeOffsets":[[114582,28694]]}},{"type":"Feature","id":"4302","properties":{"name":"株洲市","cp":[113.5327,27.0319],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@X‚‚Unw„Ė˜KXXVK„@VK@wVaUaUIVwl@kUVWUwVKnb@U°a°LXŽ‚@Xnll„L@bšJVa@VanbšƒVL„U„V@al@@UV¯ÅÇ@Ummk™w@¯ƒyVwnUVVVUkmWV—nKVUƒa@WXkVKn@lUVU„VVVXIlV°VnI@VlKnV@mwVm@LXKWkU¥wWwƒƒ@k@m„X@KX¯V@VUVa@VnKWkœƒV@VUkm@aWa@wkUWwkmV£VÿXUVL@mVIXaò@nW@ašUš@@am™@aUU„UmXmWUk@ƒƒnUW@_maVm™wUkamaUL@aƒwƒW@akI@UƒxUm@kmKUk™lUŽ@b„zV˜m¯xUVU@ƒXVxm`kÈlxXVW„@¦kVUn@xƒxƒKUwÅKVXUJWnXŽmVUxWL„¦XŽm„mK—bmUUwW@UV@šk@ƒšVLnŽlbLm`@¦VVkX@`WIUŽxVnlb„WVbXIV‚lI@l¦Ç@UKmbk™W@UbUVU„ƒl@n@VmLXb@JWbUnkbVxUJUxWXXlWL@V@V@XXJWx„zUVVVVKnXW`@bkIUl‚„nLVJUbUIWVXlWV@XklVbnn@xlš"],"encodeOffsets":[[115774,28587]]}},{"type":"Feature","id":"4308","properties":{"name":"张家界市","cp":[110.5115,29.328],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@@InWVw°wš„@š@šblUœKlUlV„U„@VUUUlW@aöUlUlLÞ@@aVKXwlK@UX@@UlwkƒVkUm@m›@ÅVƒ@akwVaUk›UUlUL¯wƒƒ@UUmƒ@UkƒKƒlw±UULVn@l_XyWwÅ@VUUmJUXU@@mmƒU@kxW@UaUIWbU@@mU@UxƒnUbmKk„WJkUValƒ@aUkUxƒlW_@WUIU@ƒbkKWUJVnUb™bWb„lU@nl›„@XnVmV@n—mWV@LXl@X›JXVmzkJUXmƒ™KULm°Vb@xnVmnUšk@ƒƒ™VƒnnlUb@nm¼m@Ûǃ„Vl@X˜mnm„²ŽmL@x™K@LUl@nULÆx@V@VXVWbXX˜l„@nLlm@bVKœX‚W„L°bnUš@VaVUš@šmšVw„JnwVK°zn@V‚Vb„a„@Ċ¼"],"encodeOffsets":[[113288,30471]]}},{"type":"Feature","id":"4313","properties":{"name":"娄底市","cp":[111.6431,27.7185],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@lL„nJ@xln@bnlV„‚„@JœLVUšŽV„nVlw@Uš@VašxVK@a„bnUmÇnV@km@ƒ‚I@VUVVXVaX@@wlVVUkW@_mKXU°‚UbVLnaV@‚V@IUKV@XlVL@w@K@_n@lWlnnJV_XK@l°nšU@WVU@kV@nbVK„V—lƒ@nLlƒ„LXU@ƒlmkw@nW@UKVa¯IVn@@aVUUKl@nXVKVn²a˜ŽXblKnLlmVI@KUU@akLUaVa‚UXm@aƒ@wVUVKnLnWlXl‚n@@U@anUVm@U‚Inm@IUK@UmKVmU_kVUwm@@VmL—K@VƒL™aUaVUUUmKƒ¥ULkšƒVWaXwWa@UXImWUaULUUWKk@WnXbWŽVWnk@UV@bU@@bƒJ@bƒV@XkŽmb™UU`VbkaWzƒ@klU@ƒb@VƒwUL@bV@U`ULVL@VUK@Xm@XWWIUbUxm@@lkkÇwƒVÛÇW@¯Å™UJ@xƒI™xƒ@@VULmKUnUxmKULUUm@@‚ULƒU™JkIWJ@b@LJUW„kJWnUV@nn˜Ü_nJšxU@VbšnUxlškb@lš@"],"encodeOffsets":[[113682,28699]]}},{"type":"Feature","id":"4303","properties":{"name":"湘潭市","cp":[112.5439,27.7075],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@Æ`n_VWnLVblKXL@VlbXxlaVb„U„VlUVJnInJ‚@VL@bUVVb@lnbn@lLVank@W@UlIVan@VanK@kVwlW@aX@Vn@bUJVn„a@K‚IX@@VV@nŽVÈl@VJn@VVL„K@UVm@UnIVm@UV@@blUUaV@XK„V@XW@XxƱ„bVxšLUa@™UKWk™@wmmUalk@WXUWkXUVJVaUImKƒVklJ@aX_mWULUUVUƒyXwWI@W@U@UXKWkXWVwU@±_U»ÝKUaƒLVbkJkƒWmXk@UVVŽmIUV™J@UU@UamLmwUVU@mnJ@VUnmV@b@Vm@kkWmXmKULUV@x„Ž@bWnVUbVblK@bVV@LUJknmKkLWa—±bUmULmWk@VLUV@bm@U°JUbVLX@@mlxkn@„WVƒKk„mK@k„"],"encodeOffsets":[[114683,28576]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/jiang_su_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"3209","properties":{"name":"盐城市","cp":[120.2234,33.5577],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@„n@‚°ĀÞ°@¦ULWKkx@bkLWb@lUlVXXJVbƒnUKmxXV@bm@@Xš‚„LޚܦXlVnš‚mzVJ@n@‚²ÞôkƃÞaȰĉ‚wnljÜó„éVÛnĊīČlj‚ĉ@ō@KÞUlU@ƒkklÇÈњÑlġXɛ@UġƒƒaU@U_ƒW@n™@kaUL@VW@kKmkUV@bkbWW@bkzma@ƒJWI@KUKULƒ@U¦™`@XUJ™U@KmXƒw¯KXkmy@aUIWJXXmV@K¯UU@@bVL@¤VLXbV@@JVXVK@„„JVn@bkKmakVVXUVVVlI@`U@nzVVƒb@¤n@@UlKXLVVšI@V@nV@V‚@ÈUx@šóVōšƒkÅWó@mU@bk@Ýwk@WbXxm@@J@zV@kVƒbV‚nLWVUX™WUXUŽWLUŽ@Wl°z@VkxU@UVWIxWJkbƒĬ„nW@@bUl"],"encodeOffsets":[[122344,34504]]}},{"type":"Feature","id":"3203","properties":{"name":"徐州市","cp":[117.5208,34.3268],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@XKVX@WnIVx@K°Lnll@@I°K„nVašU°x²mlxš@VanU@aƒk@akmV@@w™@Ua@aUwVwUw@w›@UK@£kaĉlóIÇVkŽ±@@kUKmVkIkxW@Ua¯UUm@UVI@WVI„JV@ƒ@Um@Uana„U@m‚I@J@XV@XaVlkXƒVaUUWLUyVIXmWak@ƒXkJókƒJUL@KWkk@ULU@Wa™lUIkJmI™mk„VbVš@lV°kXUKWKULU„mb@VUlVnƒb@VV@IVKUUmU@ak@@bmV@xklƒUƒU@UKmV@nƒJVbkXƒKUamLUJ¯UUVmI™bVV—Ll`@LƒLU`m@kXUVU@V„lxUK@xkIWbUKƒx@V‚kVVn™b¯@@U™@ƒxk‚mbkLÇK™b™@@XnJ@LmVklƒ@@XƒlUƒVkxƒakVVb@bVnUbU@@x˜VUšVb@š„ŽnIĊ`šXVVôJš_„K@xlU²Klk„U„@VaVVÈm@kVUVmnamUUaVƒXIVJ„@‚ç@¥nkVLn›„@@XVK@VUX@JVUV@UnVJVLUJVLUVlšnI„b‚KnU@m°™VanI@anV‚KVL„an„lK„blš„KÞk@¦@¤@„VKnLVK„L„KVzlWšLX@VmV@VbnU°@Ualk™˜WXLVU„KWkUUWšƒ@£Wa"],"encodeOffsets":[[121005,35213]]}},{"type":"Feature","id":"3206","properties":{"name":"南通市","cp":[121.1023,32.1625],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@VJ@bnzWl°L„xnW@LšVVI@Wš_V¥„@VKVL@LXJ„I‚@nbly@aXXla@aVUnllLX@@UVKlbš@@m„XV`V@„bĢ„lkČÇƃȘ¯šwnĕVĉVÿšUƒUĠƒŦğlXÑVǵ@±ōLʵĖ¯lÇbÝÞ¯xk@Çkķé™n¯@ğŽġƴǫ@kVVlUbƒL@xULǂóLUl¤@nkVV°VLkxVb@l™aUXUKWĖklVX@¤UšƒUkb"],"encodeOffsets":[[123087,33385]]}},{"type":"Feature","id":"3208","properties":{"name":"淮安市","cp":[118.927,33.4039],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@šnźUôÒɴ胚l¦nĖV‚kbmš„X@xVlVL@xUb@bUJVnUx‚šœ„lKVLÈx‚m„zXV@lW@XV‚b@bȚVxnb‚ƒVIXa°L„aÆVVaXUlK@aXIƄVlXKVUlIXalK@alwXLVK@¥Ý¯¯ÿ@ƒmVk@aX@ƒm„īlaXI‚wXJVUV@lw@U¯yb›UaƒUġUÅaUKVknaġm@kUm@wÆIV±nLÆw„ÇnUUkƒ@ƅÝU¯JÝI¯¦Ul@bƒ@@VVL@l@LƒLÅmƒL@b™@UaVaUWmLUKV¹KƒLWKX¥WI@mXk@UmaUVUU@VmL@W™bkIUWƒUmVóIkbmm™@UbVLUxmJkU@bkJWbnXU`Wz™KUÞÈlVb™Lmx@„kè@Æ"],"encodeOffsets":[[121062,33975]]}},{"type":"Feature","id":"3205","properties":{"name":"苏州市","cp":[120.6519,31.3989],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@ôèĊVnX°¤²„lxƒÈÜ@²x@J@b@X‚`nIUƙUUV@bl@VVnL@L@xƒJ@X@blJXnW@@`XbW„kVƒ@UbVxƒXUxkV@LóxVbUVWš²šVJĸklUǬ@ĢƳĠ°@šmƒī°»ÈÇ¥ULUU±a@bU@¯ƒU@KnImUVWUk™mXUVU@lIVaUUVWKUbUkWKU¥n£WakJUkUL›K¯L™KkƒVIn@VaUƒVUUƒ›UkVk@ƒU@amUkJƒ@UUlwX¥W@@UkVmk@JUakL›@kk¯ÝmJUn@nmVXlmbVVkn@„UJ@±WUxV¯a¯KōbżÇxUxƒšUUlWL"],"encodeOffsets":[[122794,31917]]}},{"type":"Feature","id":"3213","properties":{"name":"宿迁市","cp":[118.5535,33.7775],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@XbWnUJVzXKVVUbW„klUWbU@@W@IJ@nƒVmbVbn@@V@„UŽƒIUJ@XUJ@VVn°VVbX@lwlJnUVL@l²@lÈUôJĊklb@¤VLœ@@xVxUxVx@bVbš@@xU@ln„mnX˜mXLVmV@X@lxVnVJôL„LXa‚x@b„@@KVL@bn@@m@™@alLUUVaU¥nIV±‚I@mXI@aWWXU@LlUXWW_XWmaUwǙ@aaWUX@@kWUƒynÇwUKkL›ƒ™VwUmVI@aVa@wUKUk@wƒWn™laUmĕk¥„™ɳçóÑŹV™mmzkVmm@a@Ióƒk@@LWU@`—„WbXLWlkImJVn@`nXVbXŽmL@Vn@‚l@nUVl°Xx°U@LVĠ@z°˜@¦UV@Xn@VJmV"],"encodeOffsets":[[121005,34560]]}},{"type":"Feature","id":"3207","properties":{"name":"连云港市","cp":[119.1248,34.552],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@@‚lzXxmÆV„„@@¦„@l`XnlKšXXm‚KnLla„b„@„xmbm@kL@V@Vl@@VUXšJX„mbš@@„°Æ@èÈzlW°XĢJlÈ`lInbšWV_@mš™@UUķnƒôw°ÆmnaVƒVÛVmĸ»Ģw±Ý@@mUIny™UmWkۥݙƒK™@Wn@@aWUnwVL„mUaWIUWVk@kkJUVWLUkŃWJ@bkLWVUbÅUƒb¯KWbUJ„WXX`WXkV@KWVXX@bWJ@nJU²mJV¦UbVVkK@b@š@nm@@aUK@Lƒ@@awWbƒKóKUIUmkwW@U@UnWK—nmWƒn@b„l@bmVUb™@kw±n¯w™VUb"],"encodeOffsets":[[121253,35264]]}},{"type":"Feature","id":"3210","properties":{"name":"扬州市","cp":[119.4653,32.8162],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@VUXblVVV„b@xV@kz„V@l‚wVLUbVV@VU@VbUbl‚b@nkĶ°IÞV@Ɔ„VlmVƒÈÅxmKU²ÅJ@xVn@lĢnmbUlVLÆbĢV„V‚bœV‚aXk‚@VXKVVWšXVWXUmKU„aWaU@™¥@£XW‚UUV@@ynam_VWkUVUna@ÆV@mnkWmXkWU„W@k„@@akklƒlWUI@UnKl¥™I@VVma@a@I@U@a@anK@UmK@ÅVUnJl™kI@aVwka@mVIUW@UWL@WÅbmIƒƒULka™UWƒUxkLUKWlXL@VƒImƒÅVƒU™mĉL™Uól¯I±l@ÒUbVbUVVXUJUnVV@lnbl@"],"encodeOffsets":[[121928,33244]]}},{"type":"Feature","id":"3201","properties":{"name":"南京市","cp":[118.8062,31.9208],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@k@ma@kUUVmVIUWVUUaVa@Ѳk°Jôk@Wmk¯KmX¯aUakKƒƒWU„@XU‚LXaV@@mUaVUUl@VmkaUXm@ƒWUUna°IlmV™m™IUW‚@Uk@@aV@VVX@„V‚I°»nm„U@VKVan@m»UaU@U_@WlIUa™aVaUala@¯n@‚ƒkaUkUUWKU@mwkUUmmL@K@ƒLmUUVƒKƒVÅImU—JƒƒVkVVLšèVLVU@W„L„V„š@nVÜULVŽUL@bW@XbWbkJƒUUVUxVXmVk@WUUkVmIƒV@„nbnVWbƒJU„kUULƒa@Jma@XkK@VVL@L@JƒLUVU@V¼ƒnXlƒbm@kbUKmn@lVb@VXXV‚UV@b@LVbÆxXbl@@lV@U„VV@XVK²VlIš`„UbVbUlVVn@WXn@@VUV@„@KmbVLXқLkKƒV@nX@VVUV@b™nVllbšmnb„IWVXU@`lLlknVnmlLlbUmVInK°nUƒU@l@VU@Vn@„ƒ@alI„`VIXaVaVa"],"encodeOffsets":[[121928,33244]]}},{"type":"Feature","id":"3212","properties":{"name":"泰州市","cp":[120.0586,32.5525],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@lUU@@y@In@WwXal@Þxl@@anVô@ÆX„lŎ™ôU@™Vw@ÇUU@@m@U™JUUWKkL@Vm@@£„aUUmyV@@_kJUUVUUWlUnblL@aUmƒI@ƒULUW@IU@WaUK@£UK@aV@°V@LnUWWXIla„VV™@£UWlkXĕVLVWšb@kUalwUKU¯lU@mk£VôKȁVK@w„KVaUkķlUI±™ğ¥ÝUŹš™Ž¯ôm¦ƒĸ™‚@XXK@VVXUJ@nlbUx@blJkšmIUV@ÆnL@VmL@b@b@V@J@bnb‚U@UšJk¦mL@VVJkXk„ll@bƒ@@lƒXXVWlXnml@nÅU@ŽmbUVlVUXn`mb@zU@V‚VWX@¤š¦V@Xb"],"encodeOffsets":[[122592,34015]]}},{"type":"Feature","id":"3202","properties":{"name":"无锡市","cp":[120.3442,31.5527],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@nLƒÒlxUVkL™am@™ƒkVWUULUxVVVbUV@bVLU‚nnź™ÞVĠ¦X™VUUaôw@KlUVw„WUwVa„@lUXƒWa@_X@WmkI@a@W„I@w@KmKUUk@@aVUšVVÅmJ_@W@a@I±wÛ@ƑÇkw±ƒ¯£mWĉUóçƒK¯VkUWK@XkV¯UWabƒmUa™UUb™lln@b@xƒbXŽWX`@„VxUblL@bn@Vb@`m@XbWnn@l¤„n@xnVlU„™VLÆWœkV@VbÞJ‚_nƒl@nKVU@aU™U@mVk°WVLUV¯bVXŽ˜bXlVn@VmL@x—V@bl„š‚@œnW@X@VVJ@²VJVU"],"encodeOffsets":[[123064,32513]]}},{"type":"Feature","id":"3204","properties":{"name":"常州市","cp":[119.4543,31.5582],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@„L˜ŽnxUbVVƒL@xnnW‚nn@VVXn@‚yœImx„„°ƒšL„a‚¥n@VkšKVw„W@nX„VJ@b‚@UVn„ƒ@UnUV@L‚b@`VLklVÞn„Æ@VaXLl™ÈJšmmVUK@aVUUaUUVwVKXVlUš„n@šblKVUkw„ÑmKUVUI@±UI@U@WmX@›™kƒ@a˜U@wnK@UUmWk—aWU°aVUUK¯XUl@nVŽVš@bUVmLk@m„`ÝIUaU@›lÅXUKƒškVmU@wƒmk£m@XmWan@@_Uam@@akKVaUw@ƒW_XW„a@w@akmm@mL@UJmnUKƒ@@XnJWLkKUb@„Vxk„WƒL—aWVUImVULUK@L@lkLVVVllb„m@@°kbVbUbšbVbkJ@XV`V@Vbn¼"],"encodeOffsets":[[122097,32389]]}},{"type":"Feature","id":"3211","properties":{"name":"镇江市","cp":[119.4763,31.9702],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@šVĊKšn„VÆUn„„J@UWKXkVLlKVwX„šVlbVK„„nJÆaš„ķn¥°óÇIkšWKUbÅ@mƒUÝlkUK@_a@KVUVm„@mƒVU@@aUIWƒ@mƒXUx™LUlm@¦ƒb™K¯„ƒƒnw›Jzm@UW@UmmXmm@w„KUUVamw—ƒKm@UbUL@ŽƒVmn¯¼JƒUW@UUU@@bl@@VŽVXšJšnnU‚‚k¯JmbVV„Xn@VWlbUnk@VVUŽVb@nU@WbKWVƒ@XV„„lLVb°bnW°Lnl@X"],"encodeOffsets":[[122097,32997]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/jiang_xi_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"3607","properties":{"name":"赣州市","cp":[115.2795,25.8124],"childNum":18},"geometry":{"type":"Polygon","coordinates":["@@„`l@Èbln„@„KVLl@„V@bȎlnšKXkVlVL@„lJnb„¦VKVVnX„W@w°@VU„mln„UV`šU„bVUV@„xnKVI°KXKVkVL@al@Xa„LVlULWV™VVL@b„x@VXVmb@x@V™VV@nn¤„šlb°b°KXXWbX`lbXx‚z@x„`VIVUnK„L‚x„WXLVKVbVLVU@wnW°b„@nalX„‚mXVJn@U²mKkVl„U@@xlnœaVmlKnœ@JVLlŽnVššl@XXÆèVlUX@xVLXVšb°W@wnUWmXk@K‚LVwUmUkUKUw@wVaVK@kƒ@WnkUKWkwlmXL@KVUlLVKXmWU„L@ašL@malaVk@aa‚ašƒnXš@VVUblb„Jn˜ƒXa„V‚wn£„K@UWmUk@ƒUaWIV@b™JW@KmmU@aUUUkmKkVKlUU™nKVU„lVaV£Å¥WUUK@UkUUw@m@mIkƒƒUUWƒLƒK¯Uw°¯@wUKUbƒKmƒ@kkKUL@UUKV¥U@manw@k@U@Wm@@U@Wwkm„wWaUU@UUmV¯kwƒ@@kmƒkKkUW@UK@ÅV@XWWkXa@Ul@Va@KVaUUU@ƒaXwla@UkVWaXk@K@lmkUmV@Vmbk@ƒ»XIƒ¥VUkƒVUVU@anKVUƒKUalU@wX@˜™@a@K—@ÝwƒL@ŽUnÇlUIkJmn@ŽƒbVVb@VmnkLƒV¯U@ƒ±l—IWmƒ@kaUI@aÇU@K@KUIkbWbƒJUIUyƒX¯ƒUbU@méUUmUk„WK—xWIkJm@V¥U_UJUwmVkšƒUU@ƒƒƒ@knƒwm@UmkWJkL@n@VW@@‚U@knm@kUml@xÅxƒ@@XUJlb„@VX„JVxn@lbV„@lULnV@VlnV@bWV@bXL@lVLVb„V@blLn@Vl„K@xln@bX@lašLVbnKUVVb„KlXVVkxƒV@nnVUb‚lV@@z—°WWkbƒIk‚WL@LUJ@bUI@b™`@UmI@mkK¯XW™™mUV¯@UUVUUam@@VULWUJƒIm`IUJ›KUkW@Uxn‚WbnnmlXbmIUVmV@Vnb@V™LUKWLnÒVVV@V„UL@„kJUV@bƒÈ@ŽšV°šŽ@XVV@l@xUz"],"encodeOffsets":[[116753,26596]]}},{"type":"Feature","id":"3608","properties":{"name":"吉安市","cp":[114.884,26.9659],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@lxnb@V@bV@ln@‚n„‚lInš@blVXK‚nk¼@VUKWL@b™L@`UXU`ƒ@V¦XLĠ@lJ„¦@„nV@l°nn@‚mVXnaš@nb‚K„n@l„IVƒš@VanJ@_lKVVnš„L@L‚K@Vn@VbšUVanKlLnbnJVbšnWVnVVanI@‚Vb@L„bVKVanXVbVJVU@aXLll„bôlƼXxVLVK@Xn@ƒxnVVVmb@LnVVKVXV@@mnaVXUVnV˜K@_UaUmšwnKV_‚anKVLš»„K@¯ÝU@›™U@kWlUn™lknK‚VnaUkma@ƒUIUwl»Åw@ƒVwV@n™‚n@ÈXlKVmna@kVw@anm‚@n_WWk@™™mUkUK@Im›kLUn›bkm@wV@kƒlUnLV±m@UInWƒkWmbƒ@¯amX@xUVUKUaULWKƒXwƒKmLUVUJƒ_@wyWwkaW_XaWW¯L¯akaƒ™m£@mUUš@U@wnaWU@Uƒw@aUKšUXUVKUkƒKWbk@@bUKUlWL¯LUJmLƒwU@UVƒa™VU_ƒVkmƒnUV¯@@xƒXmWUUULƒ¥makI@ƒUKUkWl™LkmǍ@aƒUk@UKƒLƒ@kmÇak@ƒ_VlkL@`lbnšlLVanLnbmVÆln@škJlbknmKUbÝmmwULUK@bkLWKULUUma@Kk@UV@L@llbVzšxUxnl@bVLmŽšŽ@IVJXœVlƒLV`@bn²@J™@™V@Xmbñ@WbUJ@bm@@LUĬU‚„¦lV@xXb@blnUV"],"encodeOffsets":[[116652,27608]]}},{"type":"Feature","id":"3611","properties":{"name":"上饶市","cp":[117.8613,28.7292],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@„„@„V‚š„„I°`nm¤²@bVJUVVXUl@Vmb@xV@XbmVVœ@lkLmbn`VbnU‚@Va„UnbVllUXV„a@w°VW@_VWšLššnVlbšLVbnl„KšnVK@IUW@_@am@™‚ÑUólK@U@WU@VwU@UI@aUU‚aXƒƒ@kwmJV@yX@k‚anƒƒ@mkwVmmI@aUU@aUUW@kVkV@@anKš»„XVWnIVUl`@_„W@wlUœV@UWKnU‚bnŽ°InJl„UV@VnI‚b„Wn@VklL@l@Vn²m@U`kI@bWJƒnV@°VXnJm„XVmx@VVL@bkLmWULUmU@ƒbWXb@llnX@‚xkxVV„nVV@¤nL‚nVxnJVXX@˜ššbn`VI„b„@„blmlLnaV@„blWXnlUnbl@„ƒšKVanUVmm_XK@kWWnašU@UnaWUXa›ƒXamUkKmXUWƒLX¯WakKm™nUWwXa@KW_„aXWW_@WnIVl@XU‚LnWVknK@ImyUUÆbXK„Û@W@IÆUnƒVÝlkVK@mUIVwkUVaUm@aVIVyXIƒaÈwmmk@UnanVUmÅaó»lwšW@kkUVmUK@WKLƒUmWULkamK™Lk@Wa@wk@UU@U@mbUIWVKUXWmkUmVm›U@LkakKƒw@w@U™¯ƒ‚ƒUUn¯l@bmn@xkJWxkL@VkI@mƒkmJUI@V@b@VVxnbWlkÈkVƒLƒbkKmVƒL@V@²nxW‚kLUL@xlKVx„bXmVnšWJ@ޙ°@n™xUKUw±`UImVmnU@kalm@akwƒU@UUJmxU@@Uƒ@kU@Um@@Kn™ƒVm@k™KmkU@@WUnkLWxkVUwmKmLkU™bmKUbVŽ@xUnkJ@n±ŽšUxVXUšWJ@LUb™lUnm@ƒW@nknUJUVm@kXllknVbÆK„VVbš¼V„@šUl"],"encodeOffsets":[[119194,29751]]}},{"type":"Feature","id":"3604","properties":{"name":"九江市","cp":[115.4224,29.3774],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@WUkVUkmaƒVUb@mVUam_nalK@kU›nUWaU@@wna@UVkUWVUUI@a‚±n£m¯_ƒJ™ƒU@ƒƒƒĉ¦Ul@UV™Km™mLlm@ğ¹m`Uk¯@@UVK¯™@UUK@amkmKkVVUa@UkUƒKƒŽUa™L@VVXUJ™@ƒnƒ@™š™WUbƒnVb¯V@LÅlÝIƒJÅkݙm@Ua™WUU@UmUXmmwVUUKWUX±mUam@kWƒzUaVmÇw@aÅLmKXƒ‚UWKkL@W¯IƒwVw™lkUƒJ@Um@ÛÈWŽKUxWkƒaUU@KkLVl@„UKUX±KUb@nVVUbUVmaUlUL@„ƒaUL@‚@nUlWzX`@„V@lx²„@Vlb@bšVÞ@°nl@UxVL@lUbVV@n²xVUVmnUÞb‚a„J@IšV°xnbl@nbÆ@VwnK@VnXlK°xnUlVX„V@Vl@L@lk@W_XK@KƒkWxUL@J„nVx@aX@VVUa˜IXlmL@bVVX@VbnK‚a²XVWƒk°a„@UnV¤nbmLmW@XbmJUbVL„aÞK„L@K@U@aVKlbV@nXlJœxV@VnšŽVȚ„ÞKôbźĕČmV@ĊšŽ²xÆIšV@Þ¦ĸ¼ÞVlŽVÞnxln°Jœk‚LXWVUVUVwnJVI@yn@lXlaXmWI@w—»ma@UmK@akKkXmW@_kaWakKWk@@K@IšWƒkUa„ƒ"],"encodeOffsets":[[119487,30319]]}},{"type":"Feature","id":"3610","properties":{"name":"抚州市","cp":[116.4441,27.4933],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@°V°UnÜ@n@lnLlV@bšV°L„lnLllVzVVXlV„V@@L@xX@WlX„m@UVƒL@V@n„°škVmVUnKlaXxVbšnlU@lVVnaVI@aX@V„šJš@V„@b„b@šVbš‚@X@lUL@Ž@VlIVm@wUVanLšalVnKnLVxlUXwlKVm@k@Una@mWIXKWUÛVƒk@a@UVWn@@kl@@W„XlW@_Um@UVK@a„LnalInWV@@xnI@¥‚K„—šm@kKmƒnk@mlI„¤laXbVblknV@U‚KXVlUXa‚@@Unw@±mU@ak_±a@ƒUJUIƒVKW_Xa@aWU™šK@mmUVa@IXa@UWmšannlmX¯WKXwVUVwƒ@XUlK@klJXa@kƒkmm@Uwƒw@¯ƒW¯kw@WmbULƒaUUU@mVUU™WmkUb™KmkkK@aƒkUƒ¯¥Uƒl—ƒm@akU@mš@KVIVV@KUkUVUkaƒUWb—„mƒIkaVaUU™@mW™„b‚b@bUlkb‚b@n™K@bƒKXVWnULkKUV@LWKknlxXŽVLml@X„Ž@lULUb@xVxVLVlVnUxK@LWlXnmV@x¯X™aWUUK@wVWUkÅçm`@mn@bUx@lmbUnkLÇWm@mšU@Ux@„Æxk¼VxVJ@„nbVlmbUmLklmškVlX@‚VœšV@°Þ"],"encodeOffsets":[[118508,28396]]}},{"type":"Feature","id":"3609","properties":{"name":"宜春市","cp":[115.0159,28.3228],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@@VlbnK@b@JšLlUnx±ĀXxÆW„X@lš@V„@@blJ@nX@˜xUbVVUbVV@b—VmnmJœ„@bmbm@klUbƒLmbœš@lVb@xUX@bVVVbV¤@LVV„bXlVw‚LXÜÇn@@V„IlVškUx„x°J@XlKXLV„‚WnLÆK@bÈxUnVb„ylXn@Vbn‚W²XV‚LVVUŽnxWnnV@VVVšXVbn@ޚÆl„IÞJÆk@K°UUa„mVa@UUUš»@wV@VƒkkUKUVW£U@UmW@@aXkVUnVlKVV„UUkVmU™@kWaUanU„VVamIX¥W@@aUaUVW@_mW@UnIVVn@VbVm@bVL@anKVUkƒWK„UXV‚Ikx‚@na„bVK„b@nVJ„_V›@Vw„‚VUVVXUlUUaV@X@VblašbnKlkVaXaƒ¯@m@U„KVUn@WƒXkW@@w@KU@UƒWkUUUykkmKƒk¯K™U@akUmK@k@mmÛ¯V¯U@‚ƒL™¼UKmLbU`mL™xVnVb@`—LmUVUUWmb@nU@UWULmU@KnaUUmU„wmJ¯IUJWIkVkaWVUIUlWaUIUVkKmbUIƒÒlVUnnŽ@VlLUJ@bUX¯@ƒaWVUKUXƒKUbm@UwKWa@a@VkUWn™@Uak@mbX„WJXbm@mL—aWVk@™wƒL@WmanU@knwWmkaWL—KWUXaƒU@¥l„UVVVbnwƒ¥nKV™»@aUk@a@UƒJ@kƒmLma™@mbUWnm@ULǺ@LXnmxUŽm@UbkbW@@akLmWk@UXmJmUkV@VUXVlULmKUxkL@lmXnJ@X‚l°Vnb@bU@WbKUX@VmKUX"],"encodeOffsets":[[116652,28666]]}},{"type":"Feature","id":"3601","properties":{"name":"南昌市","cp":[116.0046,28.6633],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@šXš™„@„mš@VIUW@UšKVb„„LlV@VVbUŽlUnLnl@bVL@V°šUL@V°@Vln_Ġºn@‚knKnššLVU@VkĊ¥Vk@™Uƒ™»UaƒUÅLUalmkklWn@VUVIlm@m„Xn@VmškVa@KXIV™UWVw‚™²@m@U@VK@k@W™Ua@™ƒa@aUƒ™@™IUƒW@@bUJmbUU@kkV™mUaWwkbmLUVUn™lWbUbklmL™akbUaW@U@VbkVWVUUUVƒUx@‚Uœƒ`UI@mƒaULƒamb@lwJWUƒVXLl„UVmL@bUK@aUnUam@UUmJ@VnX@`UXVŽVb@bX@W¦nJUbƒUmVVbXb@lVšUnVlƒVUUkLmUUVWl@bX@VnV@X¤VUVLllU„U@@x™¼VV@V"],"encodeOffsets":[[118249,29700]]}},{"type":"Feature","id":"3602","properties":{"name":"景德镇市","cp":[117.334,29.3225],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@VVX@Vbmz„xUlU@mbmL@V²xVbUVVblbX@šVškVykValKVI@bn@n`lVWnX@l„L@™WKnƒVIVa@¯nK@alIXJVIVWUw‚ƒn@nU˜„nK@alI@a@anKm_™a—™W@UWmIUwmmK@£UUƒmUUlwwW@km@kWaX„aV@VnVKnXlK@aUK@UnwWUnƒmIUW@¯mU„XI@alJV_n@m±@U@kkKUlm@ƒXamJ@UVUkƒmI¯JmamVXL@V›UkV@xƒX@`k_UVmJUXƒW™¼mL@bU@UllX@VV@bVV@bnJUnlx@n„Žm„b@lWŽ@zU‚nIlx„@W„bVV@bVJV@UxV@@X@VkLVôÒ‚šn@@b@`VX@J"],"encodeOffsets":[[119903,30409]]}},{"type":"Feature","id":"3603","properties":{"name":"萍乡市","cp":[113.9282,27.4823],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@VWnL@UVW‚LXaV@@ama¯Uk@WmInW@klKVwnLVKUkVW@UlUnVnIVWl@nXlK@bX@laVan@VnwWm@KȹVK¯m@kmU@ƒƒ¥kIğ@WKU¥„@V_VW@_šK@aXKVL@Ul»mWLkU@am™kJƒm@kmU@@a@UmakwU@›„Xlƒ@VXk`UIW¼kWWX@‚œ@l‚xV¦XlW@Ubn„@ŽmUkL@UmJ¯UkUWVUaƒUlm@UXWl„nUJ@LmLU˜nXll@bUVUUmVUn„Ž@¦šxlŽnn@VÆÈU°kbV„VxllnL@VnVVUl@V„„anL"],"encodeOffsets":[[116652,28666]]}},{"type":"Feature","id":"3606","properties":{"name":"鹰潭市","cp":[117.0813,28.2349],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@@XV@nlšL@lUnš„mŽ@Ln@@VlV„@@VV@nwVI@V„Vlx@bknlbV@nmnUVJ‚_²‚VxVLšw@mš¯@ÝXIm™nUWƒaUwkL@wVKlKXmw@±@U„KnUlL„a„KlUlÇXkmaUw@U@a@Uƒ™UkwUJ@zWJ™w@WbkVWUL@VmUklUaWakbƒ£kJ@nmln„lL@Ž™nƒ˜L@¦mJ@wU@mXkJmbƒK@bUL@VVn@`kXƒW@Xk@@lm@UX@V@b„lÜUXVWLXJ@nmb@V@l"],"encodeOffsets":[[119599,29025]]}},{"type":"Feature","id":"3605","properties":{"name":"新余市","cp":[114.95,27.8174],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@m@@WULUKWwÅ»ókƒakkWK@bUVUIUamWUbULƒa@KUa@mJUbmUXU™mUamImakKmLUb™VUam@@UL@KƒKm™UUkL@`mIUb™@U„@V@bVl@bš¼UŽmL„¦mxUaUUƒVkŽ@¦„VWbXV˜LXKlbXnmx@lmVnb@X„Kšxl@XU˜bnKn@WaXIWƒnal@Vbš@XmlV@U@bXb‚LVxn@Va„LVWVLXU„b°@VW@aVIkK@UmVmkU„ÑVJnalLVUVJXbVkVJXUlblUXJVI°JnI"],"encodeOffsets":[[118182,28542]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/ji_lin_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"2224","properties":{"name":"延边朝鲜族自治州","cp":[129.397,43.2587],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@Wxĵ„mš@„ó¤VX@@xܼƨš²xWxƒV„V@„XVƒ„„„ƒbWšXllaÞU°Ċ„@ô¼„LôÝWanV¥ƒÑnĉ°¥šÅX¥°¯@w°w@»°k£°mÈŹ‚mÈbƃŎ¦„K°z@Žkxl¦UbU¤šššklV„KŤÞȰ@@bšV@nVVUlÞ¦lUllœVlU°ÑU¯Vƒ°w„bXxl@VŽ²„˜@n„ô¼ƒó°™kmVk²ĕ‚w@wV™ÞÞ@@Ġƒö»˜¯œ@‚„šbnb°mÞ¯°V°„ÈJmX¥mam™UřƒUƒlaU¯™ƒ@w™Kk—l±n@@wƒkÝVUUl±¯I¯b™a™lƒ@™kLmakbƒ@ġƒŹé°™Þb°šékƒƒLm™„wX™‚aÅb@bVlƒbVb—ÒVbUb›UUanwƒakbVŽUV›ak„¯„UŽƒLmxV°UxnôŻX@J„Xkl‚bkbĉaƒbƒWU„ƒ@ƒk„WUU¯@@klmƒ@@™Å@aƒwWXlKkI@WbUaVIUanUƒƒ@ĕƒ¯K™„mUnWUwm@£ċèkUmbUmm@@nkJUalwk@@nmWUan_óaWmnw±KœIƒwl@UmƒI@an@@mlUÅmV_™KUkƒ@U`@_ƒKUmU™@U¯™mmb¯@kb™ImV¯ƒƒLkbƒKƒƒÛ@ÇnɱJóaÝĢkb@„›x—ÒÇllœ@‚Ž²V‚„ÆUVV„UÇ°X„óxlV¯„lV@bƒV@n—x›@—¤@„șŎnxV¼knšJ‚nšKX°˜¦UlnVbUbÆVnÞWVX¦llšb@l°œVJôÒnLVbšbXŽ"],"encodeOffsets":[[131086,44798]]}},{"type":"Feature","id":"2202","properties":{"name":"吉林市","cp":[126.8372,43.6047],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@ôl‚zšaÈV°„šK@„mŽ—LWl™nšVxUV‚È@ŽÝĬUÈn‚ôLša‚„²VmĀkV@„ĠĊnU@b„V@b˜@nl°UVnÞaôJ@bš™V„¦mlkššbmVXx¯@Vxm„nbƒ„šbÈK‚V@bÈL„wĠyônšmnbÜ@nn„V˜x@n²K‚„„J@k„al@nxÞU„Lź±Vwkw¯LWWUš™kŎīVwƒw„°y„Vĕ°wÈVlkÛ»@wW@Uô£@ƒn™ĶƒXwW™aUamKóÑUI¯›@k™akkW¥XUmÝÅUVaUa‚mVk—¥W¯™Lm™IlmU»mwȚō@ƒ˜£kJUÇk@am¯y¯UVwƒa@wġx¦ƒKƒƒ¯X°Ċ¯¦U°ċWULÅa±b¯@UkÅWmVƒ™ƒkIUlóŽċ¹™`óIƒlX„WŽXxmbUƒLݏƒbƧ@ƒx¯bƒÈ—l@xƒš¯zƒaݤ@nšm„VWb²bmn¯J¯Ò@n„š"],"encodeOffsets":[[128701,44303]]}},{"type":"Feature","id":"2208","properties":{"name":"白城市","cp":[123.0029,45.2637],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@ó™ǩŁ@WlwUaƑwÛÅÇéĉamKƒōÇ@Iƒ™ôġVƒȁÑŹçƒ™ÝUƧċĉwóóÝ@Ƒ»ğL¯ll²@ƆÅV@¦m‚Åb@nmlU²VxšlUn™@VbnW„bÇbk҃š„n@èlnlšU҄Ž°Lšx@¼ĉb@҄šUŽċxՃènLVxƒÒƒbÅJ±a@_ÅJÅnƒŽVb„Kl„nUÜĊ@„Uš™xXVÆn„mšVššJÞ¯V™ĠwšƒXw°xWL„x„KV¦ôU„wVÝǬóÞޙ¼‚‚„ÞkŽVôȘxބU„lVn¦ÞšĊa°w„b°@šbÆw„lŤL²`„z°@V@@™nJVnl@@¥nUmmn„@mwnmmUnk@mlwUaƒLnƒ›wn¯°anƒWakI„ƒÇmXwÆamUXUlJXa‚UUklKUknmÞV@‚K@VWÞ@VkUwVƒ"],"encodeOffsets":[[127350,46553]]}},{"type":"Feature","id":"2207","properties":{"name":"松原市","cp":[124.0906,44.7198],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@„šźèȂÒU„óĢ„š@JŎȄ‚‚LnŽĊbÈêÜƃxVbkx@XǪłôš„kÞ`„šW„b@n°ašbšKšnVw°`š_X`W„š¦„ĊIkmVšakw‚K„x°UÞb„U@lšƒl@°¦œVW„šaÞbšxÞI@mVI@ƒVkŚUWK„¥nL‚a@ƒ„@ȍ„@°ƒÆ@nU@KÞalkUwVékUWw„™kU›VkkƒJk¯@»ókƒV¯ÆÇI@bĉô¯@™ķw¯nmmÅL¯wƒVƒUÞy@UówÇLkmm@@UóxkkĉmL¯wVwkWWX™mLõm@kűV_ƒƒô»ÛƒÆ¯@™Va™VšaĠVlmğwķUóÝƽ£ÇJkbǫaƽLW@nxݤkzƒy¯XɅm@VšôÇX¯Ė¯ºÝnUŽnLVlUÔmV"],"encodeOffsets":[[126068,45580]]}},{"type":"Feature","id":"2201","properties":{"name":"长春市","cp":[125.8154,44.2584],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@„U°xÆKnn°mĸxš°@Ċó@aÈJ°Å„Uôl@¼l°„IllœUlVƒšXxlVUêVxkllnÈUVll@Vx²IÞ¤VUlVnIôlރlwô_„›„bVaĶLXÅÞÇ@K˜¯@wÛaƒçn¥š¯WXyW¯XwƒUmmÛ@ma™nómğzƒxÇK@aUÇL™a„ƒmanƒUw°@WwnU™al™nkƒ¥šU™@aóIÝbUm¯Vmk—@@aƒU@amVğĉ@ƒlUnÿ±Uƒ™bóKmVÇÞī@ÇVUUw‚™šmXk˜Kn@ƒ™L¯ƒÇU™byókōè@b‚n@lÝX@x¯ô@ƙUV_maXm@aóƒJWxnX@ŽVVnĖVnUJ@nōÆǼV¼kxƒLklÝw@xƒx@zV`ÅbmxU±xU„nnm‚kn‚ŽğU™bUŽ‚šUb@šÅ°Ü„󼄄U`Ʋ@lön‚KšnXWlXUx°xnKĊllôw@Vn@lnÈKôx@VÝz„V"],"encodeOffsets":[[128262,45940]]}},{"type":"Feature","id":"2206","properties":{"name":"白山市","cp":[127.2217,42.0941],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@Ušl¦kÒÆ°„IlÒU¤ôz„¼lJš„U„n‚ÆXVl°@²aÆbVKČXV¯°¥¯ĉ°W„„„L‚¥Ģw@x„bUx°V°zn‚‚b@ÈlVŽlIœ@˜w@m„U@akU°ƒkUôwWƒÈ¯VUƒVUƒÅ±U›@kÈk˜Ñœw@ƒlaÞġƒUÞ£@ƅ‚KnÑĢ¯@W‚aUaVUVkkw@a¯@¯™Ý™ƒVXnW@@WkXmK@xkKUb@bW@Uw¯„mmb@WKUbmUbUaWbƒJĉIVW@I—l±LkšmU™bUm™@ƒnkKWa¯n™@„`Ubma™„ĉL@bƚ—@W`ƒL@n¯‚Xb‚@kb@x™Lƒ„™@V‚kL±™™mlUIU¥mL@lÅx@_laƒƒ@U—aƒV@kmmƒK„£ƒƒLƒƒmKUnÅKVbmXVlèĉUUbml„ĢŤƒIlŽ¯bǦœl‚@ô¼Ģ„@x°„l¤„n„a„l@x™b"],"encodeOffsets":[[129567,43262]]}},{"type":"Feature","id":"2205","properties":{"name":"通化市","cp":[125.9583,41.8579],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ÆlXnĠxĢ°lÈ°š„K„°kXm‚@¦Vbk„ŤJšnݤk„VÞVVkȄb°y„™@w˜k„Ç°a„wƨ@„aސ„K‚VnaWwXWƒ„kôJš_ČºôVkƒ»óyV£kуJůlÑk¥V™ša@wƒkƒbƒmk£¯ƒ@wġƒó»@›kÈ¥°ak„JÆ£ƒġnkVaĊVkçWUnUaÆLVmnL„„‚KU™±@—„m@a¯U„bmV¯m@_ƒK™™U™ƒaƒÅ™Wó¹ƒ@UanmWak@@wmI@y™@mk„JVa™@UaƒIkJ@n™@Um±kkxƒm™Ik„ƒbÇm@Ž°bXn„V@Ž°ÈmlÞ¼¯XVº¯Lm„kWWXLmVVlknƒ@@lnWƙ„Vxbmšnšm„¯lÝaVȁè@¼V„„b™„ÆŽ°ÞUVšJ„„kx›I—xƒƒƒIV¤™ÒXxmn"],"encodeOffsets":[[128273,43330]]}},{"type":"Feature","id":"2203","properties":{"name":"四平市","cp":[124.541,43.4894],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@Ɇn°W„zlyÞ£mwX@ƾKǬblaÈIƾ¤ôÞĸVĠxnmmVƒ²w‚VnwÆaU_@y„w@wÞxlk„KlwU»È»ŎÅ@mVIUmmĕUU@mWXw„Iô‚@bWnnbU`‚šV@Å°ó@wÞW@km@aŎ烙@m°Ñ°Inm±aXaƒU™n@mƑšU¦@šÇŽ¯aU£šaU™ġ¦ÅҙJōUŻókUÇ@™¥¯ak¯mUVak@@aċçÅaUƒm¦Ý`XbƄ@n`ƒI™xĊÞōÞml@šUb@Wl™_¯JkšÇUÝÆÅb@n™„llUb¯„±a@ƒ—ƒWĉJġĀ¯™Unóšm¤œxôaVnƒxôI@x„V@bmƙ„@lnLmޯޙxVb¯þ"],"encodeOffsets":[[126293,45124]]}},{"type":"Feature","id":"2204","properties":{"name":"辽源市","cp":[125.343,42.7643],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@żôŎVšIÆÑĢ¥Vš™bV¤°bȍ@™V¥ƒ™Þ£lÇUUUÝlƒÞ£™mţIlƒUa@¥nlWƒ¯ƒL¯™kÇġ¯ğwWmÅk¯UƒVU„„bWlXlmnƒbUx¯xVVknlŽUbV„ÇKUb@„™VnbmlnzUº±bmJUbWÈnèm҄š@X`WL"],"encodeOffsets":[[127879,44168]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/liao_ning_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"2102","properties":{"name":"大连市","cp":[122.2229,39.4409],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@‚IÞmVk@wXWÜbnwlLnU„@‚nLlbXW@a‚wnbl@XL‚aš@Ċ¥@LULnJ@xVnmV@VXXV@VJkn@VÜKXXôJlb„xl@„IVbnJVLUbn‚lnVw„JVU@ƒXU‚aUUlwn@°ƒn„VKnV°_VJšwl@nwlV„IXWlIVVnK@IWmkIVaVU@WÈUlmU@U„WUalkXġŻ@kIƒ»mm™akUm›ĉUŁV»²ġVĕ@aUU؍IɃ`ȃ@kƒw@ƒUƒmwĉ™@ƒWķсIĉÇbÝLkymbIƒwÇmÛbmbU„¯ÜõÈkÆVbŎxnXVÆnšǪ¦„bš¤Uš™xÝnĉÒmĊVȄ¤Èš„bƼ„Ā„„ÆÆބźb„VVbX„‚°²¤"],"encodeOffsets":[[124786,41102]]}},{"type":"Feature","id":"2113","properties":{"name":"朝阳市","cp":[120.0696,41.4899],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@na@UVI@m„ÑW™kaV¥UI@wl@„aÈbšm@wVašk„@@K@kƒ™@a@UUmƒUUalmU@KÇUű¯@±kUKVkUaƒaU@¥m@@¯k@WLUmkn@mmIkm@amU@wVmkU@Klk@U—m˜aXIWWUL™aULVbƒmk@UUmUk±™_Uym@mbkImaX¯WW™xWKzU@WƒkJWwkV™@Um@UbVVVVXb@VWX—@WŽ@Vkb@V™nUK±aUUlwX™ÇWKknU@mmUkƒLUVƒVUUVƒUaƒw™bkKmwnIƒ™kJ@nmbƒ`kmVkLWwUm@UUU™K@UmaUa@UUaWK@mUƒ¯Wkk¯VmUUŽ„xVXUVmL¯ymXkWUbmXUKƒVknWx¯JVnkLƒl@VVxnxlĀVL²WlX„l@bÝVUn@bnlÜaXblIVl@šš@Ȧ@VmbXV‚@@x„VVnUn@`°@VnXU@K@„VV@VmbnVn@ln@b„xƒ°Ub@bšLV`Ånƒ„W@@lUšnnWVU@Vbkl@Xl`XxV„UblŽkX@Ž°¦V„UVVbUlkV›@UbVbkLUxmJkXšš@b‚bœxVKÆlXX˜bnŽnala@ƒUk@U„VVklKVUXKVU°KVan@VUnLšKVL„WVaU_@mmUXa@m˜wXwVkVWXk‚k@›„k@klm@wXKl@U@KVUUUVaUƒV@„alL„xUx@b°°VnnVšxlIXJmx„LUVlV@bnX@Všb„aVx‚@XJ@b‚n@VŽVXȄl@llX@lU„Vô°°@ބVbn@‚V„k„@VW"],"encodeOffsets":[[123919,43262]]}},{"type":"Feature","id":"2106","properties":{"name":"丹东市","cp":[124.541,40.4242],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@lzXJ‚U@š²x‚@@Vš„@bUVmKUn„°n@lnVK„„nV@n@VlV„°WbXn@‚VzƒJ@¦@bkb‚bUl@bkbƒJ¯zƒWULWbklV„nb™¦VJ@„„K°U„kl@@W„bVn°@„Všm²U˜nX`„UÜLXmVXlKVbUVVnUbn˜ƒX@VUL@lUbWxš@²kl`n@Vlb„@nUVWVLVU@aV@²bl@ÈmšxWX„VÈU„JV„l@„„la„WnX‚KÈkÈ@Va°bÆm„@XV°IVV°UnalƒVUn@UwVU„@@VVJ„I@bl@XK@wWmXU‚UVbkJVXnJVI@mƒknwlKXL@`l@VI@UUaVKÞn„aVm@aÇ£XW„U@aÇUU@mbkKm£™@WW™ƒL@@Kk@kl›U—bWKUkUU¯UõÛƒmUUaVU„U@WU_W@kVkJƒ_WKkV@bUL™¯¯ƒ±mk¯ġƒğÑ@UmwƒKUakƒ™ƒa@a„m¥ÝƒIUWmk@w™mţ—L›KʝbȗKWĢklVbƒX@VV‚knÇV@XUVUblJXn@J"],"encodeOffsets":[[126372,40967]]}},{"type":"Feature","id":"2112","properties":{"name":"铁岭市","cp":[124.2773,42.7423],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@XJm@¯šmXUlnVbUJƒU@bV@UJWL@VXLmJVbkXlJXxVL@b@V@n@b@`Vbk@lxknV@VV™V@bUL@bV@@bVK@VXLWLXJ@LV@nbWJ@IUV„x@LVJUXVxVx@VV@@LXJWL@VU@@L@VnL@bVVmVX@@VVInJmbnLWVnVULVVU@VVmX@@JVz‚l@„nVVKVXރ@mk_lm„UUWV_nJlUÞÑÞVVUVƒVL„UVJ@I„Vna‚@@KV@XwWknwnKlalU„w„aĉݚwšJl_@aUaƒKUUU@WU@WXUÆ@@UVK@n@UnVVšblK@bœllb@b„bW@Xbl@UlnLl°°bš¦nKlVnI„V@UWU@WXkƒw@am@nm@aVw@I@KUaVIm±XÑlknJVnVJšaX_VaUaVKmwnkmmn@lU@U@mnašXlKUmUIVmklaUK@UlUVUW@U™kVm™a@UUU@JmUU@@bmb—KWV¯XUKm@ka@UVKVk@aUKmLkKUUÝUmbXbÇJ@k@WU_@m™™@klm@UXKVaUI@KWUXaƒÇWk™aWUkWUL±U@lUU@ƒUJƒI@V¯JmIm@@aU@Uwƒa™@UV@VkI›V¯aUkƒWkb@bVL„@@VVVUXW@Uaƒ@@b—‚ÝbUV݄@ŽƒLmUkVUbVllLUV@LššXŽWbUXm@U`@„kxlnnJlbnIllšLX„lVlUXmVK„n‚V@L"],"encodeOffsets":[[126720,43572]]}},{"type":"Feature","id":"2101","properties":{"name":"沈阳市","cp":[123.1238,42.1216],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@ȚĊÜ°„b„L‚lÞxUbUn±‚@ÈnVÆL@xnLšlUVƒbƒxkImJkn@V±LUxkV@bšbšKVKnzVl@L°@Va„xÞUlbôxVVœ@@V±bnŽ@llXL˜ŽöXĶŽnal@nkVJVI@aU@@aVK@ašUUUU@lmkwl@Ua@_@a@m@U@aUKWwkIlWUanIWK@UXKVIU@@a„VVIUa‚mVknW°™n@WI@KUƒmULWnkVkUWƒ™KkkmJkamIkmlw@ƒV_n@VWXaW™™@KVUkKUkValUnV„K@ÞƒVUÞa˜@a„@VbX@VWUU@Uƒ@UK@ala@IkKmUUa@U@ƒVƒkk™WVwU_@KÜUXbl@V¥XUVmƒƒƒXa‚kŃlUUkIm`UIUJW@UIKmkm@UUJƒImmU@ƒVUXU`mIUbUK@LƒJUU™l@Xƒ@UbƒJ™kU@ƒŽn„m@Uam@@ƒ™aUmLKƒwƒ™mWXUK@kUaÇa@JUIUa@aƒKVUƒUXmƒUy™_@lmbkLUKWLX`‚n@bVL@JXL„‚WX@Vnb@Vm@UbnVmL@V@x@LUbVV@V@LƒUVl@mb¯U@xU@UVVV@X@VVblJ@bn„VKUn„x@llnL±¤™b@k`VXÆK@„kV@¼kl@bWIUl@VmLnbm@@JXXmb"],"encodeOffsets":[[125359,43139]]}},{"type":"Feature","id":"2104","properties":{"name":"抚顺市","cp":[124.585,41.8579],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@„XVl°bœUlJ@UVUš@„bVxV@@bn@nJ°I@U„J‚I„VV@V@k²VVKlXXVšb‚lÈX„ŽWbXV@LVJUbWL@Vkn@lšš@nV`@X@lÈIWanaÞVVVlLnKVL@bUlUL@Vlbn@VL°WXU˜Lna@aV@nV@IVV@VšbUnšl@V‚XnKVa@U„UnyWkXaƒaVk@ašašbnm@_WKXmWanU@alaU—l@XJVLVxX@˜wnKnVlwƒƒ™@V_@a¯¥@UkKWUaUU‚anK@IƒaU@WUaVw@klUVyUUVUUÇ@Iôbša@mnUma@kXa@UWak@Wa—l@a›@WUƒLmU@U`mIUU™`mUk@@UUK±nkJƒbUam@kwm@@a@UU@Ua@@K@ƒVK@kmKU_UKƒUUaĉWmkkL@`™LƒnmlkLkbmK@k™@Ulmb@b™„@Ž„xUVƒIUlmVXXƒxm@™JUUk@WUk@ƒakx±@¯x¯Umb™KUUVmUU¯UmVVn™WkÆ„lWb„„„ŽUnWVU¦k@WaÛV@LV`UxšXllU„@„@VVbnVlL@J"],"encodeOffsets":[[126754,42992]]}},{"type":"Feature","id":"2114","properties":{"name":"葫芦岛市","cp":[120.1575,40.578],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@ll°X„ŽnV‚@XLVb@VVbnb@VšLVV@VVnXxlKnU‚l„_na@mlI„šmJnxlLša„xVbU„VV„UVU„KVlnnV@lmXLšÈWŽkxVV²bVLšm@Ula@UX˜@XW@UWaUUUUVan@V‚š@lUXxlIX„V@‚yXLšw‚ŽXXW°nblJnan@Vzš`l²nVVVl@„nUaVKšbVKnXVaUaVUšyšnXK@kVK‚@X@m@m‚LXa„LWƒU¯„w@™ƒa@UVw„¥°™ó¯¯y¯ƒUǯ»›w¯Iƒm—¯Ç™UUl™¯»ţKċÑţķm¯w@mU_ómk¼VnU`±IkbVlƒnnŽU¼±Lk`@X™Wl¦UbmVUxkXVlkbllU„Vb@bkVmx@XVV@Jb±aULkKWXkWmX¯aUJmIkVm@ƒxU@n„"],"encodeOffsets":[[122097,41575]]}},{"type":"Feature","id":"2109","properties":{"name":"阜新市","cp":[122.0032,42.2699],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@šXnb°lš„VlnXVJ„LlVnl@zÆxnK@b„blKVLn@@V„aVLVK@L@Vl@XVVInVVKVwlUXwlKšL„ššVVb@aV@X„lUXbVW@n„lWnXKV@@V@XUVVLUVV@@bVVV@@ln@VbVUXV‚I„xVanJ@UšIVWšL@UV@@¤V@nInw˜W„k„lnIVx‚lnzUVÇJ¦VVÜLĸUnW@aV_šWĊXXa‚Knkl@nm™L™a@alUVw²K@UlmnIlJ„w„aVU™kmK@wÅKmU@DzVmVaÝwkƒKƒaÛ¯șĉķ¥ğ¥ƒ@kUWkƏī݃ƒ@@akU„K@KWIUm¯nƒU¯JmwUVmIkJÇLm@™UImJUU@aW@U@@nUb™JƒaƒbXVWn@UVmX@V@b„š@l@Lƒ@™lUb@x™nÇaƒbk@@xVJU¦lbXšƒÒ@nUJ@Vmb"],"encodeOffsets":[[123919,43262]]}},{"type":"Feature","id":"2107","properties":{"name":"锦州市","cp":[121.6626,41.4294],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@nJ@nlmVnXKl@@°n@@¦‚V„bVbUlVL²l°@ƲÈV@LV‚knVb„VVnnWVU‚@XmWU„a„bšIVa@mV@X@@bVVnIVJ@š‚nÈKlInJVUnx°I„V°mVnXJ@LƒLlV@b„@ބƐĬXllV„@Ġ¦ĸ¦naWW@In@manK@UVkXJ@alk@»lU@ƒÅLUWl_@ša²£‚Kkm@kƒwVmULmƒ@akIUa@U@WUUVU™aÝ@ğ›wkƒƒmĉ£UWƒ@@bÇL@m—a@_mKƒlƒXUwKƒLţÓ@UWw@K@U„I@m™U@UV¥„@°UnJ°@@_™KUwƒW@UnaWUmmI@m™ķwUaÇLóVĵwݙUUW™¯šƒ¦Ux@V„b@šƒxV°X„ƒKWbK@n@nW‚@UL@lWL™m™zUVVbUbmWXXWJ—b˜n@Vkl@LlVUn@xnV@bln"],"encodeOffsets":[[123694,42391]]}},{"type":"Feature","id":"2103","properties":{"name":"鞍山市","cp":[123.0798,40.6055],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@l„œxĠŽÞ@šbV@@w°Vna‚@Uk„V@K@UUUVa@K@w@UnKmUVan@@Uma@UXWƒWK@IUK@amW_XKVLlKna@kmKVak@VU„@VmšU@anIÆan@‚a„šUVnb@blLV`ÞLlU„bna‚Kn@naVU@¥°IVK@anUUKVaƒUVak™@mJƒkXƒ™UVwkƒVUUa°U@Wƒ@WlkXWlIXUlJlaœx‚IVVXLšll@nLV@lLXl„KĊzš¥maUƒlkXaVK„X°y„Ila@aVkala@a@¥„IUy@WmXaƒ¯kU@U@mmUƒƒULkmm@ƒ¯VmnLVU@a™ƒ@U@±w@™VWIkymLUUkJWXƒJkUmxk@™xUI¯`mUULmƒ¯„m@kxVVbWV@„UVƒIUx@bkšVšVVšxUbVV@V@zšJVXU‚lnk@@lkLƒlƒLUU±Jkšm@UIUVƒLUVU@™K@UƒnnV@l@Ll„ƒaUJ@zn`@nWlƒIUVUUUV±Ln‚@nmL@VUVkLVlUxVLVlÅXma™@@akLmWUX@JUnVJVkXJ@X@`WX„VUVUIlb„W@bVUVL@`Un@¦U`@bUV@z@Jm@@XV`„LUL¯J@IVKmKÅI@J™nWVnLnšVxV¤™z@bmV@VUV@bUL"],"encodeOffsets":[[125123,42447]]}},{"type":"Feature","id":"2105","properties":{"name":"本溪市","cp":[124.1455,41.1987],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@lb@Vn„lnVVUb@šVJ@nnJ@bmXUx@xVbkbkŽWLUxnl@Ul@„xWx@nUV@¼Ull„knkK@bmbnl‚LVJX@VIVJn_lJVVšXUmnU°VVVUnVVšLna°V°w²@lw„bl@XVl@VVšIn@„wWWnUVk„JVUƒw@šƒ@anaVkš@@lnLlalKnk„mšK@_lKnlĊXVb„VVLV`nL@lUL@„@L@‚VbV@@V@bn@lxn@Vb„alI²mVL@Vl@nVš_VVnJV_‚@nV„K‚V@Xœ‚@b˜kXbl@XblylUUkš™@Xa@UVIlK@UUWVU„Llm@UUUnKWU@K@UXm„XVa@U°KVUUWUk@ašUVKkaWkƒKUknaWa@U—@m@mk@ƒaUJk@@_WKkLmx„l@nUJmIUWlIUaVWVXn@xWLk@@aƒJUI@Uƒ@UVVxm@UVk„mb¯VUU¯JWUƒ@Ån¯aUbÇ@ÇlLmWƒXkbƒƒk@UƒƒIÇVƒUXW™wÇnk@±aU@@bUVUKUXmVƒ@kaUm@k_±l™@XwVa@kVK@U„Wm—VaUmVUUakLUWWnÛKƒVW_—m±V™nƒU¯@Umƒa@Xk@ƒl¯V"],"encodeOffsets":[[126552,41839]]}},{"type":"Feature","id":"2108","properties":{"name":"营口市","cp":[122.4316,40.4297],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@ĊĖƐn¤„„°Ċ¯ŎWšô„@xXb‚wnKl@nX@VUVƒKmL@VU@Ux݄@Vlb„x„U@VUb@b‚kœ`‚IUlVUn„V@@UV@@JnXlK@bš@nbÆWUkUKVwUklKVU@UnK@mm²KVUVVVU„JXk@mm_@yVI„bkƒ@K@kmU„m@VšLV@VU„KVUVJn@l™²IVV„K„klK@kl@kmVUW™I@y@UUUVa™wUUU™l™@akmmVaUKmIUaƒJk@ƒwkaóIWWÛL@UlmUIU@WW@UnUUm@wmIVK@Kĉ¦™@bWKk@max@bWXkamKƒ@mVkKmxÛaWX@xUlÝnJ"],"encodeOffsets":[[124786,41102]]}},{"type":"Feature","id":"2110","properties":{"name":"辽阳市","cp":[123.4094,41.1383],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@š`Vz„‚Wn„VUV„L@bVbVJ@IÈbVb@lVLXW‚n„š„x‚LnKVŽšb@„n@Vbn@mƒ„V@šl„IVa„@@WškVV„I@KVLVanJV_VW„UV@nn„JVI‚Vn@na@alLlmkƒVk@»VU@mXwƒwk@@VmkVwXKllaUa@wVwnW@amI@mUI@™VaUUkmmƒ@UkaƒL@ƒUIĉyƒLWkkKU@mKk@™kWKUUJ›wkbkIWVkJWXkl@X„‚@X¯VVbUVl„UxšVW„„lnIš@l‚Ub„VUbVLmV@bUL¯J@¦UVmbm@LmbƒakVÝKU_kK@amaVUƒ™bm@ÅbmJ@b™VUnƒ@UVl@UbnL"],"encodeOffsets":[[125562,42194]]}},{"type":"Feature","id":"2111","properties":{"name":"盘锦市","cp":[121.9482,41.0449],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@Vbĸx‚š@nnJVnXŽmb@V„XVxšL@`¯@mI¯Vƒ@U¦@VšV@nƒJ@V@LXx@VŤÔ„K‚LVx„W„knL@`˜b@nÈK@a„@VXĊ¤„nVK@aVU@UnU@ašyU£Uwm™mKXUšm@IÆJnLUL@J°IVKƒKU_@Wn@@I@yVU@aV_@¥Vm@_UKUV@aƒXkaVJVUƒUXW@_@WWIUlUIVm@IVW@IU@@VU@mƒUVVkJ›_l@aVa@UƒVƒwka@UރVwV@@UnK„LVU@UmWk@mLxWa@wóƒUVUIÇÆĉ¦¯¦¯xʟJ"],"encodeOffsets":[[124392,41822]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/nei_meng_gu_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"1507","properties":{"name":"呼伦贝尔市","cp":[120.8057,50.2185],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@„m@Łkƒ™Žƒklƒôƒ@£kJ°ý™ɅķÑó¤ğLĉÅlÇğŁW¯¯›™ƥóÿlwkţÈéÝƛó™°ÞÅxV¤ĉĖWƒ¯lȭţυ̃ɱÿķƅˋğɱřÝţϙȍƧĊţ@¯kWKUKm¹Å@ķJU@ƧÑƧ„ō¥˹Ɔ@L@„Þ‚VLnš@VōČWJX¦@JŻbU@ţÞmVU@ȁýóbkWWLƒƒÅ™¯UWġkmóƒ±UŹôV¼ƽ¼ƒł̥ĖƽǬʉxĉŽŻȗKΕ̛ʵƨʟÞ˹»Ƨţ»Ǖō˷Ȍ±ȚʊĠUɾɜɨmÜ֞߼˸ƅȂ¯ǖKˢğÈÒǔnƾŎՂ@šĊbôô̐¼ƒ@ĊôĊŽÞĀ™xšĖƧL±ŽœŽ‚Uš°U„°ĬƒČ°ÜƒêɴȂVł°@ƒ„nxŎèƒbȄÞȌ΀ǸlŽ²IlxĊl²ÒmšôĖ™Èl„ĵºm„ÈêVþ„xɛČʉÇĵVmš„ÒƒÈɆôƐŰǀĊ°ÆǬĮƾb„yĊ@ĠšƒXǀċm»ôw°Ûk¥Çm¯ç™kkÇǫţǕéX_ĶWǖīŎaÆĵĸĊ@ȚȘ‚™ĊLĢĉ„VÆĉʊÇĕóaU¥šĉ°mkÅ°ġUĠřk°mƒÑČÿ˜ÛƒWĸ£ʠšÆxÈÞŎÞ»ʈ²ĊÇČalÒ°Ť±ĸz„ŽĊKȲm¤Ŏ@Ò°¼nyȂUźīǖƳÈē°@šÝĶƒ@ƒÈkl¥Ççkxk™›JXÇƒUÅ@˜£k»„óƿīÛ@lÅJl¥óý@¯ƽġƍÅan™ċ™°é¯¹"],"encodeOffsets":[[128194,51014]]}},{"type":"Feature","id":"1529","properties":{"name":"阿拉善盟","cp":[102.019,40.1001],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@™ƏnǟƨʫšŹɆÿ°¯ÆV²ˢ™żÿ@ÝÆŁȰ¯ȀƳĉó™™@ğkyš¹@īš›ƒwl£Źƒƒ¯Ŧé@™ÇÇxŋĉƩUUŃōL™Ç™ĵóÝnƒóç@™™ó@ġƒƱ„¥ƒç™WUçÆōƒ@é—çťK™çȭVһƽ̻aW¥ȁ£ʵNJǓƲɳޗǔlżÞmĠóĬȂɲȮ@ÈĢŮźÔnĶŻǠšŎȭœгŃċóȭţΗÆƑÞƧÅΫóȘǫɱȁġlÛkÇ°ȁÈnšõl¯ô„ÞɛÝkĢóWĊ„zÇɼʝ@ÇÈķlUČÅÜķnέƒǓKȮŎŎb°ĢǀŌ@ȼôĬmĠğŰōĖƧbЇƧōx@ķó£Ål±ĀƧīXÝġƃêĉK°Ýʇƅ@ΌʉżÅÒϱʈ@˺ƾ֛।࡬ţશóЈèʞUš¤Ґ_޸Ƒʠɽ̦ÝɜL׈ɛϜóȂJϚÈ@ǟͪaÞ»Ȯź"],"encodeOffsets":[[107764,42750]]}},{"type":"Feature","id":"1525","properties":{"name":"锡林郭勒盟","cp":[115.6421,44.176],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@ʶĬĊIȘƨƨŽ@ĬÛĢșŤĉĬƒĀóšU‚ÈŚÜènŦƐȤȄłϰUƨťƾÑ܆ğɲƜǔÈèʈƲĊƞƒšɆ¯̼V˺Ò˺ȂŤVĢêU܃x„Āˌ˘ƨ„Æ°ѢmÞżU¼ÆlŎ@ĊçŎnÈÒͪŎźƒĸU°lżwUb°°°Vš£ÞlĠĉĊLޏɆnźÞ„n¦ĊaȂīġŃ¯Iĉůl»kƒ„™Çý„¥Ŏ¯ƒén£ġљÝȭxƒÇ™@Åçķ»óƱŎ¥™çWÿmlóa£Çb™yVÅČÇV»ÝU¯™KĉýǕċţnġ¯»ÇōUm»ğƒÑ™wƏbċÇŎċwˋÈÛÿʉÑ°Łkw@óÇ»ĉw™¥VÑŹU™mW»ğğljVÿŤÅźī@ř¯ğnõƐ@ÞÅnŁVljóJƒwĊÑkĕÝw¯nk¥ŏaó¦ĉƒV¦Å`ğуÑÝ@mwn¯m±@óƒÛKˍƏǓ±UšÝ™a¯lƒōšșk„èƒĬގn@ŤġŰk°ċx@œĉ`Ƨĕ°@ţÒĉwmĉ@ƒƒnƒƒa„™¥ķnƒÞĉVóÆókĉŽķ@ÝkƧƧÛaƒ°Ç@ÝÈU˜óbݼ@„ÛÒV°™@V¼ˋL™ÞɅŤŹǠVÞȗŤÇĖŚōbȁƜ"],"encodeOffsets":[[113817,44421]]}},{"type":"Feature","id":"1506","properties":{"name":"鄂尔多斯市","cp":[108.9734,39.2487],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@ĶL²ĬVłƑkkl@Ȏ™ŘWńÈĬȗ¯™ºlz@ĠššĊôŦô„ÒĠ°kÞܚ™n@¤„UĸèĸbŌÈXŽĸLlÒĢxɲÆ¤ÈÛƾJÈÝ°UšÅĶ»²VW¯ĸJôšbk‚V@ôlbnĊyÈzVôašb@ĸ‚ÞUl°yǬ²Ǭm°ššk„±lbn°@È»˜JX„VŎÑÆJ@k„LšƒÆl²™Ġ²ʊůĊġ‚řóƛÞÅ@m„ƒmLUÿóĉƧ@™»L@„›`ČĸmšȗÑţů±ĉğl¯Ā™wǎƒçƧŤÛI@±ÜĉǓçō°Uwô™ǫůķƳř±bÅ£™ÓÇwnÑó@ȁƽ@™ƒÇƧĢón»ŏĕóĊ¯b„Å™™VȯÅImƒōKU„™LǓ±Ýxċ—ŋ˜V±Āȗ°™„Źl±šÛ@WÒȁŚŹНŚÅèŌô„¼°ȰɞȂVĊ"],"encodeOffsets":[[109542,39983]]}},{"type":"Feature","id":"1504","properties":{"name":"赤峰市","cp":[118.6743,43.2642],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@ɲŁĢljĊwƾōÞĭ°_ŎŃźȹƒUČÿl»¯ôķVÿǬƽ™ɅġÅÑǫ»̐ʟȣU™¯wVWݍÈġW»Þ¹m݃ɛŎÿŎōͩůV¹›ō™éċ™óŹÅVVĢǩʈ@Ėċ@ķšÛšV°¯xÇÅţ¥™»°Ûô™ĉʟ„¥WýČ¥™w‚灻±mnÅķ¥ˋVƒbUÒġ»ÅxğLƧ™ƒbWĖÅxš¦U°ÝVóŰlô²@š¥ÜÞÛô„V@²±`š¦™„™¯Ý@„ŽÅ„VÒō¼ôš™¤V²ŹĬÇĊƑƒţxƒç¯Lk»ʟlƽýmłÝÆƏ@mö°Ġ@ŚŹĬţÆUĀĠNJĠŽX¼šnźVUҚ¦Ċxȼ@ôlx¯łʊÒÜĀˌÇČxƍČÈƐašx„ÒĠŽn¼ŎVȐ‚¼Ģ°ŤmǖČĊþšLV°ÞŽU¼ċÈUƚzÈa‚¤ôbkŽ‚nXĀšè"],"encodeOffsets":[[122232,46328]]}},{"type":"Feature","id":"1508","properties":{"name":"巴彦淖尔市","cp":[107.5562,41.3196],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@²@Ζǀݴʶհĸ„˜ƒ¦Ķ™̒Uˌ¼ӾÇƾ¼̨UÞĉ˜Ƨ—éÝ»ƒĕĉ—ƐȍœōǪakó‚ó¯a@™ôţ™aV¯Þ¯°@²él¥ĵğťwōxó¯k±š—Vó@™aóbUÇyĉzmŽkaóŽU@l™aó‚ķIX°±Uĵ¼™Æ¯VÇÞƽIÇÜÅ£ɱŽġwkÑķKWŋÇķaķçƒV@£šmۙlÝğ¯ƒÑťóǿƴȯ°Åł@ÞŻĀˡš±ŽÅU¯°ɅĀ™źƧʬmǠšƐ"],"encodeOffsets":[[107764,42750]]}},{"type":"Feature","id":"1505","properties":{"name":"通辽市","cp":[121.4758,43.9673],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@ôƲĸ¼Æèš@„ÈȮwƾ»ʠĢ¥VÆ@²¥@»Ŏњ¯ĊJŤ£k»ÆÇX¯̼ōšī°aX£ôƒƾȁź¥„ƒ™aôŤ™ĢL°ƒĸ@Ȯ¼ÈÒʈŚôVXůÆaĠƛÈKƒķšĉôÿ@ğÈĉ™»ÇVn™ĉV›wXĠÝ°šČÿĸwVƒ™¯¯ǵ±™ĉ‚ǫ™ÅÅm»²Ż±ƽIm¥ţÈķ@¯šƧJV»ÞUÝç¯UġºU£ţŽóaÅÅlƒƒ™Ƨī¯K¯Þ݃ğL̑ȍƽ@ōŎōĀƑɜnÞݺX¼ÇĢގUX°xVšʠȤ̏Ǭ¼ÆÒɆĢšŽǫƾUĀóĸ°‚k¼ċĀƑVŹȺōń¯`ÝĮƽŎĉxġNJɱłō¦"],"encodeOffsets":[[122097,46379]]}},{"type":"Feature","id":"1509","properties":{"name":"乌兰察布市","cp":[112.5769,41.77],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@ʠǠÞĸɲȺƒÒȂƛŎaƙÈĕȘţUÝźǟɆţšÝˌKU»š@U¯ÜÑ@ƒÞ»ôaV—ÞÇÈ@„¯ÜbƨƨÞlĸ@ĊôlôÅĊU„Ýĸmš¦ƒŽ„bm„„„Ċ@n‚ĊxŤÑ@¯‚ƨĖĊ_@›Čwl¯™ƒȭL›Ý„»ƽ¯ķů„Ǔ@ÇǓbċ™ÅÅÆwÿĠÇU£óaƒ¥¯aŎğĠţkw°»¯ůlÝĵkǻݰɱƧǫaóôɱ»Çk¯ŃóƒʇŐŻ›ĉNJŻĢ„Ž¯ÒÈUl°ƒx°n„Ò™Ĭón™Ċğ°ÇŚĉ¦ʵVƒ°°ĬÛżÇJȁńʇʹó˂ƽŎ›Æţ¦"],"encodeOffsets":[[112984,43763]]}},{"type":"Feature","id":"1522","properties":{"name":"兴安盟","cp":[121.3879,46.1426],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@ÆXnlŎ°@LVLĠþœxĊUȮĊnU„ĠV@żaW¯XIŎġƒ¥Ý@K@w@K@I˺ŻŎ¦ƨƒƨÒŎIÆ@X@VºnX°lŎ@ƾĉˤƒȘǷȘÑÝݚÞbVţĸÿŤxÈĖƐŽêÇKnĸ¥ô@›ķÞUnÒl@UŚaƒīˋƒ¯ÑƧx@±kXřƐƏÛéV™ˋ»lō¯ĉ„ÅÇÓǫޗĖġV@ğ»›°ĵ„ÇÞǓ¼¯m˜ÛÅŃĉĠÇƾb²çƒ™šéż¯VƒƒğÞml»ōÑV痻V¯™¯šĕÆU¯y°k¯¯V»ôDŽѰa@Źk™ġKţšóŽšbƒ„Ź¦ƽȂó„W¤¯b™Ĭ̻ŎW°ÅÈl¼ţ¤ĉI™°ōÒ@¼±¦Å@UŽġ¦ʟŽƽ¼šÞĢÒm¤„êō°ƒ¦Èþƒšl„k¼ĊŰ°JĢńȁĬ„°ƒżn‚ÇbV„ݼ@¼óĸţ¤@°Ånšl"],"encodeOffsets":[[122412,48482]]}},{"type":"Feature","id":"1502","properties":{"name":"包头市","cp":[110.3467,41.4899],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@źxżĀǔÆǬVȘĀŤ¥œÅƾōôˁʈͳȂŃÈIÜŻ¯ī„¯ōm™¯ɱĖ¯ƒķÒÝIÝ»ÅV™ƒlÅôфġ™ğVmÞnnƒWçkW܁XƝÆwU»Șĕš£ĉÑ𱱚Åk™„ƒK@lÅIō҃UW‚—IǼ¯@m‚kaƒ²™l¯™ǫnǫ±¯zkŽÝVķUô™˜l²ô°ŎwŦxĶĠk¦±ê¯@Ý°U°šbóŤ@š°bôlôǩb›ŎƏȎĊ˜„ĖÞ¼˜ê—ƨÝĊ"],"encodeOffsets":[[112017,43465]]}},{"type":"Feature","id":"1501","properties":{"name":"呼和浩特市","cp":[111.4124,40.4901],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@ʶUĊ¥ÈřĠ¯šĉômšīƒÑ¯m„wk¯ÇV°ÑƒżġĊljǓɱţǓ›ƝóX¯ƒɛÒóa@nÝÆôƜŚĉĢʉŰĊҙ¤ȗĖV¼ÅxWƞۂlXXèm„ÝmUnšĠƒĢóÒkƚ„ÆUÞ¼ÞJĸÑ°„ɲĕš°Ŏn"],"encodeOffsets":[[114098,42312]]}},{"type":"Feature","id":"1503","properties":{"name":"乌海市","cp":[106.886,39.4739],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@Ș°ÇīXњŗ@ȍlkƒlUŁ±īĵKō¼VŽÇôXĸ¯Ž@šťê„°ź„k¤„x™œ@Ĭ"],"encodeOffsets":[[109317,40799]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/ning_xia_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"6403","properties":{"name":"吴忠市","cp":[106.853,37.3755],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@nLV‚@šVLšaÞbn@@l˜š@bUVlUV„zVx™¤kÞVèšXnš‚@nm°a@UƒÑ„@VŽXnV@Va„UšŽVKUUU@@U‚@@KVa@U²@‚wXkWnk„±lLnU@UmmVKnIVWnI@UK›@UK@@UVKXkmWLWUXmlkVwUyVa@w„w@aVI„K@aVÈw„KlLVV@LnV„VVnU‚ܲ°WÈIUÆ@nÞ¼‚‚@¦™@UÞUVW@UxUxVn„b„K‚b¯ÞU`VbǬ™V@XXÆVVl°InmnUôƒ°¯‚anam£œWVX‚KXmškôaVU@ƒVak@@wmaƒn@K@UÛUWKXUƒÇƒ@UI™b@alW@akLUKV@@Ukw±Iš›nL@kmwkWmk@JUIƒůVmnnU@m@UƒK„VKlkUwkƒƒnVUKmbkI±š—KƒkmVkKƒb@U@aƒVkUmn™`kIlaUK@UUKmbUIݚUa@mUa@aƒ„m@UUULUK@bmKkbWI@WXwlkXƒWa@k@kKƒLVkkK@L@JUVmzUKlwUUnW˜£XVlKUwVU@aXI@aWaUw@W@_nam@¯‚UkWVkUWaU@nwmJkUVkWVUmUkJ@ImbUaƒ@@WÅ_mJknmak@@mƒXƒaUV@„ƒxUšƒ„@‚ƒ„@VUnkVƒ@Vn@`ULUbWLXVW@kbUJ@XW`@ƒnÅĖWJƒ@—m°@xƒxšbnUa‚w²lƒÞ°xŤIVVULۂWbšbkVVXÆ`UbVL„@kx°LlV@Vœ„WbƒJn@bl¤ULV„°@lmL@ƒƒ£U@@aUwmKULVxUVVx@„™@kU™@mK¯LÇa¯@"],"encodeOffsets":[[108124,38605]]}},{"type":"Feature","id":"6405","properties":{"name":"中卫市","cp":[105.4028,36.9525],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@°@Èb°KnLš@lVš@@ƒUwVUUwVKnLVx@bV@„¤@„nK@k‚¯UƒVKk£@a‚m„IXa›ƒ@UkU¯Klwƒ@UKVaÅ_UWlU™aXa܁VKUUţJ¯w„ݱkxVbmŽ™a„w@wn¯˜„@XIÆĕ„m‚@X_@WVIlaX@WUXKVaVK@_Um„@lUVm@U„ƒ@„ƒV™„w@ƒVUÛwm@@W@ImKUkU@Ua‚aXƒ@wWaUKkw@UVaUamLU™nk@»±`¯@k—W@Ua™ykbƒI„„@VWJkLWUkJƒwU@ƒn¤mL¯wm@Umƒ²XVWbnV@bmxƒVkxUblLUV@kVWKU¼ƒŽkUƒ@mn@JnV@bUnmJUn@„k‚@XlxšLVVnKlLVV@š@LkKULVbk`WL@lkXW@kVƒ@UÞUlÇX™lkaUbmV¯@@L@šƒV@bkb@xƒlW„—bƒbW@—±@UJ@IU@mVk„VxV@@l„Illœn@Vm@ƒVUbl„@JLmKÛXmVkU›KULU`@LĉwƒKUX„lVUl@Vb„JX¦̼bÞxŎxɜĖĠ„Ŏaô@"],"encodeOffsets":[[108124,38605]]}},{"type":"Feature","id":"6404","properties":{"name":"固原市","cp":[106.1389,35.9363],"childNum":6},"geometry":{"type":"MultiPolygon","coordinates":[["@@Vnn@°xnK‚£„mV@„xlIXVlKXI@Uƒƒ„JlašzVbX@l˜°@²_@¼mlVšnKVbUb@VlxVLXb@xW„bVbV@VlnL@J@Xn@Üx„b„W@nl@nblmnIÆ`@X„@Vbna@aVUUWVkƒ@kbWakbU@VwšW@_l@nmn@@alVlk@UkmVak@@a‚UXaƒL@¯@KVa@axWI@KnkVaVJn_lJ@„X@‚m@nVanUVb@mXLlJ„VWnLla„VVaVX@KXVVkVKlknKVa@aVU@KXb@klJUknUmƒ@K@_UW@alIUamaU¯kJma@IUK@U„@@UW@@aXLVƒVJVaXIƒKlaUkUV@ambUUJkIWJ@wUI™V@JU@UwV@@Um@™nU`@UkUmVUxWUUV@aÅb@aWXkKUUƒUUaWK@wnm@IVU@aXwm@UmVaUalk@anKUwlƒUwlkK@wmaƒUkmmIk@VmkUUbW@UVUnW@kV@xkVmbVnU‚™@UbUV@a›k@kkW@„kLW¤@„nV@VU@W_UV™UU`VLUV@IUVõVULU@UUUJ@wmkUJ@šWI@l@bkKkbVVƒbVbUL@UUJ@Vm@@L@xbVVVLVlVwX@Vb@bmUkbk@@JWIUVÅw@Km@UkWKXxWLÅ@UVUnWK@xkVW„@KULwWVXVWzXVVKVXkV›V@VUbV@U„VV@š@LXxVL@V„b‚Ž„LnKVLVxXVmb@l"],["@@@J@aƒU@LWK¯UUxVVn@Ġ„„LUW@UbUUUa@KUX"]],"encodeOffsets":[[[108023,37052]],[[108541,36299]]]}},{"type":"Feature","id":"6401","properties":{"name":"银川市","cp":[106.3586,38.1775],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@šUšwVK@UVWÞUšbšw„V@knV˜@@KU_VK@K„ƒn@W_XWlL@Vn@Ċw@Ulaœ@Wanamī@aƒ»ŋó@aÆÅɲÿUaV_°ÝaƒLƒaUmVwVwX@VUVݚ@@¥Ý»@mVÅÇJ¯XÛ±VUmƒUmU@KUUkKƒLÇxUŽ@bƒLUJ@bƒx@xUbVzUxklWnXV‚KnXWlUL@V@ŽVLœ@VL@ŽmJUXmJULnn@VmVkKƒ²mlXWlx±@@VUb@L@@VV@VVUL™ƒVUbU@WmUƒ@„Ò@V¯bmn@VŽƒ„@lVnUšnVWŽXVl@¦VVUn@x‚š@‚XL@¦‚lXxš„Vb"],"encodeOffsets":[[108563,39803]]}},{"type":"Feature","id":"6402","properties":{"name":"石嘴山市","cp":[106.4795,39.0015],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@U¯ķó±ÇÛ¯™ķmbXb›@kb@Vĉxm@@UkKWXX`m@ƒ„@LULV`@L—@mU@lƒU™x™aÝVUX@VUL™x™VkLWVšš@J„nVLXVlŽUV@zl‚VL@V@b„„n@lU²WVLlLVbUŽVxUx@xǀL˜xôҜk‚K²ŽVa‚U@wXa@W™ÈĉUa@‚bÈk„m@¯"],"encodeOffsets":[[109542,39938]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/qing_hai_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"6328","properties":{"name":"海西蒙古族藏族自治州","cp":[94.9768,37.1118],"childNum":7},"geometry":{"type":"MultiPolygon","coordinates":[["@@„V£°š@laœXô±źwš™ô@„Ulƒża܍n™Kƒw@U„aƒ™ša²L‚mÈLƚÈxlaUa„wÞmÜbÞUšnJ°a„kôƒ‚ÑkwÝVğwÇ@ÝkkV¯¥@ò„»„nŤ¥XImw@mVwša@Åw™mLkaW—wƒ¥l»kçƒó„»@ƒWÑĉŽğ@ĉ„™‚Ń„UwóřVómĵ»™™Ý@VǕ¯kšÝĊÅk™°ÓUklkU±šI„ÇÞkƒ±@šƽJƒ™@UġIk@W¦™VÑșÓÅnťKULnŽ¯X›ƒ@¯mUÛ@WřmóKknōbƒxÝ@ƒŽU@kw@ÿÇLţšÝUkšmwƒŽk™lċVŚU¦™ŽƒLkUWlÅÑ@aƒ@ÅѱUóġŹ¼ƒÈĉmŻ@@wkw™Kl¯U™ġ@—„lÇU™Ó¯_ƒ‚Waĉ²Åló¼VbknƒKǎÅ@ƧĢō°Ý@ğ„W™ÅxUUm@™‚ÝXۂW„ULUè¯@mbUaƒLƒbUWġxIUJWz™a¯b™y™@ōÈóLU`ÇXUl™UĉV¯n›mÛbǕLklƒUĉVƒšóaġ„ƏbġKţnkbÝmmnÝWȭȃŽÝXţWókUÇl¯U¯‚ġUɅĀ@°¯„„š¯„VÆnmJ@ĊķnóJUbÝXUlVškL@lVxnnmb@¤Vzš`ÞÞŤ@„VnÆJV„°b„UôJkzlŽkl@²óš@ÆÇ°kĖƒšÇbÛU@lmb™XV˜kzƒV™ŽɅĀXˢlń„ĬŹ@›éÅ@ĉńÆ°ğbUšlŽɜ_°‚@xŦ˜škbVbƒKĢ„ŤVŎŽ°@żÈźlĊ„ôKôb@nôxŦ„Æ@ôŽŎL@þÆb@šnnšWˌbÈx‚InaŎxlU@Ѳ±ƒğVUĢƒƨbɲ@Þ¥ôUUķWVô¯ĊWʶnôaŤˁ@£nmnIôŽǪK°xUXô@Ŧa°m‚kXÆÞVŎkĊ°ÞLȄôyVašIlwX°UVwĢÑÜKôw@nV@œm°nmŽn„Ü‚ɞ£VbmŽXnƒ°ÜÒ@xx@V‚b²UlbkxVnšJUnVVĊ°KȚm°nxÇnn¤±¦@ŽUXVV@„lV„„bmVVȁŽVxšÒ™°šIšbźaȃšbVwš@šƒVL„™ƾÑ@ƒŦô¯ĊkôÑ"],["@@„@šƒ„@n„òVœa‚w²bVxšxÜaČVô_ĊJšIVmšL„a°@Ŏ¥XlK@ƒšk„l„KVbUb˜@nUĢn‚aÈ@lmǬ»Ġ¯œn‚mnƒƨVy™Ñǖ™Ġ»ɲInŽ‚@@ÅĢƳ@¯°™ôV„KÈbVIÇ¥¯@Ýó„™@ÑnīWKšƒk™‚k@¥š™¯™Åa™Xƒ±VÅw@±Ġ¯@»™š™n™Wmw@ƒ™@¯ƒVƒUUWçƒKĉ„a±VkkƒV¯w™x@šUJ‚x@bknÇb™mÅ@Uw±U¯¦UŽ™Kmš¯I¯Žť¼ğĊ™@ǃŹÈ¯@Ý»ÇnˡJƒbÛèÇnƒ„ÅK¯„ġĠŹW¼Ålm„@¤n²ƒŽÝb@b„š¯lƒ¯@ƒšÅ¤W„™¼nV@x„„°@Vx„@lbUblbX¼W‚œšÇ²lšUŽ@¼ŽV¦@bÇlVxUbVxÞbVšœbm¦ƒVV„"]],"encodeOffsets":[[[100452,39719]],[[91980,35742]]]}},{"type":"Feature","id":"6327","properties":{"name":"玉树藏族自治州","cp":[93.5925,33.9368],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@ɆÿĢV°°VÈklVôŤXÞW„ȮÇÞXnmÞnlaŤmĢLƐaĢƒôb„™ĊU„VlkǖKÜaœn°mĊUšVVkÈWV_ôKŎǚ@šz°ašbXyVI‚JĢwVX„a„KVbna°@VçVKXƒÜÞWšn@VVÆwXšĠƒÞ@Ŏ¯ƨġÆ@ȍ„LlmUaô»ÆkĊ±Xb„°`šÔV‚kȘƒĢ@Všk°šLlx@xż@Ċn„Çź»ôĢ²VÆ҄@@bÆÒXklV„KšV¥Æ™ČUšk‚l„nxl™çƒ¥ċç@±m¥ƒwÅJƒ@™™™Vƒ„mÈIléÈa°U¥™™@kÞV‚K²ÑWƒ°w²Ñ‚K²ñšyƐ„ÝšVmw„»kkWĉ—JWUƒVÅwƒL™mÅ@@ƒmw„kn¥Vу»°™°@@»„¯„Lla„JônV‚UůƒU@W¯Umѯ¯k@WykU@¯„wV¥ƒkVwţƒk»šwWǜĉĶçšK„ƒÞ™ÇaĉbƒI™lUƒ@kwƒWƒXUƒ°w™±@UšKn£Wĉ—KWxƒkĕVƒšamwXw™@™„Wmnk@aƒVkƒ™bĉLƒl™Imm„wUÇ‚Wx™nÝJn@¥Æ™kwƒaXƒÜĉ™¯ÅV¯¤mkƒx¯kķܙ²VWôŹVUƒƒ@V£™¥@ƒ°wn@™m@¯@UbUôķŽmn@ÆÛ@ÇýVaUÇĊVƒ@Çlğ—¯xÝŤ™lVÈÈVƒx„ƒ¤Vx™„kK@™@ƒx@„kVƒĖġ¥kIWbXŽŎx@nƒxÅUW`ƒ_—@±ŽUa™LUxƒK¯„WbkVlb—bmŽƒLÛÆWIUwƒWkwÝV@kI›ŽéUb›UUk™V¯Km¯k@Umݐ¯m¯›m—L›Þĉ‚ÛUm™ġ£UxkKm°™Lw›šk@kšƒVm„ƒKVUk›@¯a¯Ģ™móKUU™x™ImlÅn™™ÇbXèVVU„°„@ŽšŽ@„‚xXnmš™ššŽ@¼ğ°@²ÆxU‚„²šWÆb°š™š@¦llš™„XLmĬ@҃šÞô°@ȦUJÇaƒLóU¯š@°ġƴ@Ɓ@mɱJğ¼ǕššÒUzƧ‚m„n›mğ°ǫ¼knÇ@bġmmV—@VaUaƒLƒk™l@„kLW‚ō¦¯@ƒb™KUn™JĉIó`ċUÛb™wUw±ax›bñUmƒƒ@™„ƒ@—bƒaƒbǏÅXm˜„ƒÝ„ÅôVbގ™bl„UšÞVޚ„U‚°„VUxƒ@U„V„@l`™¼nL@Ċ„LW„„¤kXķWġXUVVVķ„UbVb@°kVVxÈa‚@ȦĊbšaźJ„U@Ț„„˜Vœƒlš@XkôaWƒĢ™Þ@laĸUÆb²mÞLĠ™ÞÑôbšÒĊa„JVbm¦"],"encodeOffsets":[[93285,37030]]}},{"type":"Feature","id":"6326","properties":{"name":"果洛藏族自治州","cp":[99.3823,34.0466],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@ÞVŤ™ÈK@ĀlxV@„Þ@„wŎalmôLšnXÆÜ@nV‚°@œ„°WmVKŦLÆmȚԂҚUX¥l@ĢJVš@„ŽƾI@w™W°™™Ån¥›kÅÝVwôƒÈç„@lÑĊĕša„JnaÆLVw°kny°UnkÆVȍĊll¦„Vƾ@@™nUźƒÈǂIn°X„wÞKô¦VWV£„@£°ókċ±I™™am¯Va™»ČĉV¥°™@m„k„¥l@„Ċm@ašU™mwXƒ@wÆxšmĢ_„`VnÆbšKVw„@@ƒnUVğVmVVöIlŽl@@çÛmƒ£UDŽw°@VUƒ¯»m¯ƒJōĖÅLƒa@»ĉĢ±`U_k`ÇçšóƒkX™lK@ƒakÝރš£WċkÝ™kxƒJݯÅw™xķxmIÅx„@k±J@ýŋš›¤UœkŽmV™°ÅÝxkwmġƒnÝVU„š¦ƒŤlmšóXk¤™UKƒç™@mVkK@klīƒ£mš¯VUbƒW¯¼ċb¯ĵam¼mVX„m@k¤ÇX‚ÇbƒUƒ„¯J¯„¯È@˜™bVXVҙ¤V¼kxݚV„@l‚V—„WxÛ¦Wš¯šmKnlŽkŽ‚šU‚@nƑUĉ„Ý@ǺۄċUĉ¥™UƒÞŏ™z±òL±Ò¯xX„±ÒLÝU@lššV¦¯‚ÇbkêÇJƒnU„šš@š„‚ÆI„xn¦‚‚@²Č脦‚è"],"encodeOffsets":[[99709,36130]]}},{"type":"Feature","id":"6325","properties":{"name":"海南藏族自治州","cp":[100.3711,35.9418],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@VxƒŽńƒš@ĊĠŽĊXÒ°UƾĕÞm°£nb@‚@LUUW„Ûº@nlÆǬšĠ£ÞV°UXb‚VȂǵ„éƒ@kWanm°@™x„z„K°¯ĠVšƒVƒkw™Lnm°kÞxÆa„¥@‚wnĉƏ@™œ_l›š_VwšmĸèŤÅČU@™˜Wn@ÑmKU™nğƒK@ƒ°¯UÿV£nmšLl™„UƒUÛé±óókkmƒnƒakV@Ç°óÝXƒWəÞťIţxmm™VÛUVȂÓnWyȁĉkƒVš°WnkĊa„¥‚_œK°ÿWna@ƒmU¯wƒlÝIU¤UXó¥ÝLƒx¯WmJÇÈŹ„mV@šƽ@ƒUk¥ĉkċŽÅUml¯Vmz¯lUxÅKmbƒI™bĉĖk҃@Çèó„UxÆޜlm¦šÆ¯ššX@x™Ž@Ž„²ÝlƒÈ™JV²klVl¯ÔlšĉƙްlUǖÞ@ššĶ¼nŽUôôŚ"],"encodeOffsets":[[101712,37632]]}},{"type":"Feature","id":"6322","properties":{"name":"海北藏族自治州","cp":[100.3711,37.9138],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@ōmġxƽUm±Lǿþġԙ@kxmWƒb¯I¯‚mIUx@bƒbŹVǎƒkĵbƒlĉI¯¥ƒUšm@ƒÆ¯È@šašóšUlƒČ»@w›œ»›wXaƒƒó°ţç݄kUƒaV¥ÅbÝw¯lmnšKlxU„™„ğU¯°ƒLƒyšw¯@mnXb‚l„@ƒêȁǶUWa¯VÝUğ¤ǫ™kÅ@mܹXƒVV@K@ma¯¤ÝnƽĖ¯V@„ƒ¼„ôlèk¼„¦˜xXŽlbnKšÆx@Ž™bUx@nnxWJţ¦ƒmƒ¼ñ@Ž°¦lUÞlÈ@ĠxÞUlxÒó„ƒl¯bmI™ŽÝVÛaÝnƒxVbkbÇwřÇKn±K™b„šƒb@V„xšLmŽÛŽŻbk„ƒVó@™šŹxó²›Wkb™@¯U¤ƒźĊ@lUX„°lÆôU„ƒlLX‚aœV°wšxUb°xÜôÈKVkÈmlwškÈKšwšK™™VUŤĉŎ»„»„Il¥na°LV»²¯Üy@wĢƒ°ĸwlwĢw°±„_lVkš@°ƒbƒÆ¯zƒ‚„š„@l_„@Ģ±lŚVlUaރ„LVƒnKlnȏ°IllČa˜wÞÑ°x„UU™@wƒVkmĠLô»„KÞýôaÞ¥ôĀÞmƁ„™‚mUƒŎV¥Èl°²°a²¥V„@@w„amm@Ñn@Æ£żƒVƒĠ£@W„¯Þƒšl@š»@Uk@"],"encodeOffsets":[[105087,37992]]}},{"type":"Feature","id":"6323","properties":{"name":"黄南藏族自治州","cp":[101.5686,35.1178],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@ôl²ôÜê„VƒVkš™KmnU¤VĀ¯°@„„LmĠVšnLÈL@alb@al@n°Vš_XmWUÈamaVIn@n‚aV£œóVWƒ™U£°ašxÈ¥@™‚aĊwȹ@óša™ƒğbm@k„w@mƒaÆw@ƒ„In¯mmƒ@UkkWƒÑÅ@@kċÅçVkÝJÅkVykŹl¥@¯š™ĢU܃X¥òý—mmX™ÝÅlmU@£™Wly™XW»Åbƒl@aI›»k@klm@UxUUƒVƒ¼¯Xƒl™aUnķ‚ƒI@x™@¯„ƒK™„ĉUU`óšlČ¯ô@¤ƒÞJ„k°xVŽ„n@ŽmbXŽ¯Ā›L`ƒ¦ĉbml¯X™ŽUŽl„ȂĊXzm‚ȁÔU‚ÜVšUnnŤwŦJɚ݄XÞW¯ô@ÈlU„b„mln"],"encodeOffsets":[[103984,36344]]}},{"type":"Feature","id":"6321","properties":{"name":"海东地区","cp":[102.3706,36.2988],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@@҄bš¤ÆI°ôU¼š°UŽnnWx™š@b¯L@lUUWbXxWl„ƨnxVUllš„XVŽUŽnL@lȀý²KVnƾ‚ĢwV»ƒ@mÞ£nÆƒÞÑmL™ƒKUaVżĕƒWVk²ƒƒÆÝ@ƒXw°@„ô™@a°wóUUmIk™™aVmÞwmknyƒ¹VÿƧnŏm£X»˜™naV±„Ýw@ašb@aƒm¯„ĉVó¦kÝWKUU@WanU™b@ôǺĉxb@šÇ¦™w¯bV¤„šUX›ôU¤bmm@UJnbÇbXVWn™`¯Umk@@bka@bÇK"],"encodeOffsets":[[104108,37030]]}},{"type":"Feature","id":"6301","properties":{"name":"西宁市","cp":[101.4038,36.8207],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@@kmKVUƒWk™VkUmwƒƧXkWwXaVV@k°K@aš™XwmmV™¯V»¯óÅJ™£ƒamŽ—X@šċVţÆķç™nUx™`kœ›`@šÅmĊx@Žƒ¦U¦„blVރŤèô¯„„Wbœx›¼œŽ@xċ¼k„™V™ô™bÇ@Å°@„™n„V°¦ĊJ„kĶa„lȍźU„a@aVwnJ°°J„anXlwš@ĢÓ"],"encodeOffsets":[[104356,38042]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/shang_hai_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"310230","properties":{"name":"崇明县","cp":[121.5637,31.5383],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@uŏu»GPIV±ÐɃŜ{\\qJmC[W\\t„¾ÕjÕp‡nα|ěÔe`²„ †nZzZ~V|B^IpUbU†{bs\\a\\OvQ’Kªs†Mň£RAhQĤ‹lA`GĂA@ĥWĝO“"],"encodeOffsets":[[124908,32105]]}},{"type":"Feature","id":"310119","properties":{"name":"南汇区","cp":[121.8755,30.954],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@`y”ĉNǕDwǏ»ƒÖLxCdJ`HB@LBTD@CPFXANC@@PGBKNECCBB@EBFHEDDDSNKAUNBDMNqf[HcDCCcF…@EFGLEBa@ACoCCDDD@LGHD@DJFBBJED@BGAEGGFKIGDBDLBAD@FHBEF@RFDMLE@SGANFFJBANPH@@E@FJjRIACDMDOEKLFD@DbDAJI@AP@BGHFBCBGDCC@DCA@CECGH@FKCEHFJGBFDIHACEDNJDCVFBDCRKRLDLITB@CjNJI^DBCfNVDHDFKHAFGDIICDWBIF@@CFAjFJNJBBHD@CJ@AEFJ@@DH@BFBCPDBMFEQGDIFCNDHIP@HDABFACBJFHEBSZC@DP@@JDBƤ~"],"encodeOffsets":[[124854,31907]]}},{"type":"Feature","id":"310120","properties":{"name":"奉贤区","cp":[121.5747,30.8475],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@~T~JjZdDbLXDLCB_J@@FHFZJJIAGH@HGR@BENBLID@@LFCDF\\FpDBDb@FAHKFE†@dEDDdC\\GreNMACVMLBTMCCFCEGFAA@DAFDLMHA@OD@BMEWDOC@AS@KGAI_DcKw„ÕísƝ‘åĆctKbMBQ@EGEBEJ@@MBKL@BJB@FIBGKE@ABG@@FMFCPL@AjCD@ZOFCJIDICIlKJHNGJALH@@FPDCTJDGDBNCn"],"encodeOffsets":[[124274,31722]]}},{"type":"Feature","id":"310115","properties":{"name":"浦东新区","cp":[121.6928,31.2561],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@EN@JJLNHjLJNR^GRYVBNZJRBV@PDvbLNDN@LGNER@nCNQNuT_TIVFV\\Z\\XnDrI|[Ʉś²ÏJUHOƣ}CA@IO@@CYDATGFIEDAEBBAGCO@GJMCEDCJRHEFANOCADAEG@@CI@FE@BDIC@AGIAIMiEEB@DE@AJCXJDCJEHGBELGCUCeMAD]CIJiM@DSAKJKCLQDQACUECDMIFCBDJGECHAEIWCK@GLMCCGEACNKCEJG@MMBMC@@CIJUINT@JAJSTEPZZCP"],"encodeOffsets":[[124383,31915]]}},{"type":"Feature","id":"310116","properties":{"name":"金山区","cp":[121.2657,30.8112],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@L@BIHFN@@EE@@EFBDGDAADVDD@@EF@CA@IIsRE@GDAF@BF@CV@|FBCHBLCNHAFCADBMDCFZXHILBVEEQA@MWFARJJ@DCX@@TEFBLHAAERE@AJABRPBNK\\BrJ\\VHGND@CNADKDADQjGAGNC@GJ@FCFFHC@JF@@dLBDSFADHVG\\DTEPDDHJALIJkJDJCDIPE@YDCBiK@DONE@EH@BAF@HLJA@EIA@ALKNA@@FIFAFHR@NALadsæąyQY@ƒA±DʼnXUVI^BF@FFF@HBJEDFFGFEBSRkVEXGHFBMFIVW@GAEEFOIAIPKABGWEKFSCQLQBSEIBC\\FdBLRR@JGACFDDEF@AWB@LJJYNABBA@CUEGPaO_AIE@MYMFIGAEFECHSAAKAO\\[JEDB@E@MMA@@AGBKMGDFFCDDFEDFJF@NPBAFLHFH@EDDHBADDC@DDCDHHCDDFDABDAD@FEFOBCJ[D@HEDDNJBDDHABJIBBvGLBJAH"],"encodeOffsets":[[123901,31695]]}},{"type":"Feature","id":"310118","properties":{"name":"青浦区","cp":[121.1751,31.1909],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@RUNKdOFDJCbRFMLAHPLDN@JGL@@APBWYCKN@TU@SHGCEJIDIJKVIZVNM`iNY@CIE@CA@KBOEGEUFCCSADEIEFCDDDIDDHC@CKIeDCG@IG@DHWFEEGCH@@GO@@O]CNpeEQDBFME[JC]DGF@CKOA@QSB@GB@@GW@@ED@AQIJIAAFE@@DO@CFI@KNG@CDACAFEGKGBEGBDCCAIFCCLIECFI@MBCLDHGNAHSF@DMB@EEKBA@@C]DEICFG@ADBHGFKCDAKKHKD@@FHGAANGEEFCHKCECBCKG@ADKCNE\\[A[I@@mGBDQQEO@BCE@AI[AML@JGACLOAFKEMM@EQKC@CUCBCCBCHEA@FF@@FM@GEAJK@GNF@EXPH@FD@M^@HIADJCFDBER@DK@@DE@CAKFOCCBDHIBCNSB@GFC@GQEEOWFICGDUAEJIDBTAHJHEB@DIF@NE@H|HBDBEH@DKBAHEF@HEEUB@FGFGCCCE@AHOB@NH@PRLVNNFBX@RC€PbAvMtBfH@DJF@ELBFA@EH@HNED@FFB@HLC@CJ@@DJ@PIRf@HE@CFF@GPHD@DKE@FFBEFFD@DEFCA@DD@IjCRFBAHFDKD@HF@@PM@H@BlbDJDBFEF@DLXB@HCD@@IFCBIFEJD@FDC@FBALLF@PAACJERACAJCBD@EL@JD"],"encodeOffsets":[[124061,32028]]}},{"type":"Feature","id":"310117","properties":{"name":"松江区","cp":[121.1984,31.0268],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@@DLDFRN@FNELPBDKHB@INK\\BBJF@ADP@RFCRHA@nJ@B\\[\\MFLDBCH@DLDADFGLEDFFMHBBGH@EC@GLLLCBLDHEAGBCH@DEFJ^C@DB@LAFFA@CNE@GTMBGHKCAD@NEJFDKJDDJEDBCDHAAFLHFHBEBDDCH@LMJ@DEP@@CF@BEJBJIBRC@@FX@@HA@@HTA@RPBDLE@CHD^\\INFAERCfFMo^D@PP@@HG@HDFFXECGH@@JDHfCLJ@DGDCCCJCCEDJFCFTBDDVEHFPFLAB@NBFCFKFC@CHIACNOHWHCAAFIDD@CDAGEI@ACFMF@R@R_@GQED@EGFEQEDE_IAHKAEXCQUOQCUDEN@ZI\\DDmAMHCICDSOC@EG@BKHIGMIBCGOCSF[CUHCGEBCTKA@cE@@IGDEEEDI@@HMDBHiHCRCBCLMB@DMCGH[UqI[AMLOAAQIB@BQFBFGBAKFE@SW@CDI@QIEBNXB@FRUFKAGJYWDENCCADBBEMGKDGAAD{EU@@DAEE@CB@HQFJt@JDBE@@FC@"],"encodeOffsets":[[123933,31687]]}},{"type":"Feature","id":"310114","properties":{"name":"嘉定区","cp":[121.2437,31.3625],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@F@LI@IDKJADKIEJICADGACFECCJ@HKCAFOHAJI@aCBEE@ICAEB[GFGCKL@FGEIFADMLCAEJM@ELQECEIG@BE^QKKLQCA@EHBIGQ[GEHOMGGDHKH@JOECFCjCBEFDNCACMBCILGTABDLEEOEIG@GFIMM@CGKFBFCDE@@GEAGEEACIcGaHMFITIHDN[AKF@FS@OA@BK@IHM@KCGOKBENaQIDECcPMLQVFHFB@BFBKLGD@FAJOVGIACQ@A`LPCB@JEF@RU@ANS@@RCL\\HIFpRBFRBBDKLLDADJDGBFDABHBEDNF@DGBBBADKDAHC@\\JJFBDEH[DEFDH\\LX@XLBLbT@DNJLDCEL@VJABJNDHB@HBHYFBAA@GNFB@@AFB@AFABFLFBHFCL@HJBAFBLC@DN@HN"],"encodeOffsets":[[124213,32254]]}},{"type":"Feature","id":"310113","properties":{"name":"宝山区","cp":[121.4346,31.4051],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ˆmÖoÖiƒ½[s[YEUJU`SCIEBCCWJY_LIICDWU@@FaBCJIB[ICH[@@CDKEE@MK@@IMCAEBCH@AMFI@SMGEFGB@FK@BHCAIFJNQD@FEBDFMBKGACG@ECWH@@CDDTOEEBGEK@GC@EE@GPHFR\\JHGA@FDBKRLL]RAFH@FJFDKR@FINBFKDCNEBFJEHK@DLEH\\HFADB@JFFDA@bIJGBEPDBGLI@DDEFBDCHDBIJJFCLIBCL@JKJE@ADHDBHJ@HIBBDFHBBAEIJ@BJFAVL¢ˆ"],"encodeOffsets":[[124300,32302]]}},{"type":"Feature","id":"310112","properties":{"name":"闵行区","cp":[121.4992,31.0838],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@T@@ELE\\BCMJGJSNEbGdHDJFBJAFIEIFCEWG@@gMENSFCVJFAxR~B@IH@AIiI@GE@FGEAFQPDRiV[\\DFSGMHAXHDOMCJCDETBBNVJJI@DD@ANNNH@FILDDMFBDHNDHKL@XDFGLD@EHGFD@DDB@CDDHCDAEAHG@ABOJ@BIaC@CECLKPFNCDCJBiQEIF@@@OGBMIAEEBMTHF@NKEC@QFEGA@EBCKAACHCLJHEFHHB@AFCAIEACIC@HG@KCCDC[ECEED@KC@KJMAAFQ@GHG@BHIJYIGE@EI@A`KDWCaKcCiY}I}S[CYJM@CFDVPRRVWDFžLBBG`JCFRFEFFHC@RF@HQ`Q@E@ENBDJ@HFCB@DCCEJBBGDGXMPBDGJ@DEDELEDMA@DJF@DMZ_jMNYUUJILCJIJDFGH@TSVM@DLXZ"],"encodeOffsets":[[124165,32010]]}},{"type":"Feature","id":"310110","properties":{"name":"杨浦区","cp":[121.528,31.2966],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@V@CXJDKJZ`XIDDFADJvSRMDM@mFQHM@KCMKMuaOCU@BDAJSX@HKJGD@PNJCJWAGT@R"],"encodeOffsets":[[124402,32064]]}},{"type":"Feature","id":"310107","properties":{"name":"普陀区","cp":[121.3879,31.2602],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@F@@FHDL@HFFAPFCSDC@@XGFDH@BDLHNACEFA@ERCIMJEDBAGL@@EHAFENHHJ\\ONQBQCIBC[MKACKI@GGGH@I_G@CW@[DMHCDIBMTDHN@JNHEH@FJFPKFACSBKHDJNABDMDECAFiDEDFDIPG@GLHCNH"],"encodeOffsets":[[124248,32045]]}},{"type":"Feature","id":"310104","properties":{"name":"徐汇区","cp":[121.4333,31.1607],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@RADL\\NCPHFfLJaJ@FWLGMGIK@IFMDOYYFOTSBI@IMSAMSACFIDNDCPWGGBHNET[CU\\QjOCERFBEHF@@HjJBJG@@J"],"encodeOffsets":[[124327,31941]]}},{"type":"Feature","id":"310105","properties":{"name":"长宁区","cp":[121.3852,31.2115],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@HFFB@HF@DCAELENSJADCNG\\CX@@D`H@JHGHHJ@BINBFUGEDO[MCKQB}AwQEBUIEDMTNF@hH@FXEDFJEJIB"],"encodeOffsets":[[124250,31987]]}},{"type":"Feature","id":"310108","properties":{"name":"闸北区","cp":[121.4511,31.2794],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@CSG@BQGODUPWTOBQAAFMECKBGEMFKEOHADDJARMR[PGI@TEJBNG@ADBFND@JL@@NFFCL@D\\@DG\\JJADI"],"encodeOffsets":[[124385,32068]]}},{"type":"Feature","id":"310109","properties":{"name":"虹口区","cp":[121.4882,31.2788],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@bA@E@QHSXBDIMI@OHCLI@GTWBIACQAYIOFGCENBBARSPOXCVHPARH@DT"],"encodeOffsets":[[124385,32068]]}},{"type":"Feature","id":"310101","properties":{"name":"黄浦区","cp":[121.4868,31.219],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@NEHFLAFDHDPEAMZUHQQ]IMKJG@EPERABHBGRUCCNGV"],"encodeOffsets":[[124379,31992]]}},{"type":"Feature","id":"310103","properties":{"name":"卢湾区","cp":[121.4758,31.2074],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VDHQGABAFQFOH@LIiKKHEXI@IbAFZB"],"encodeOffsets":[[124385,31974]]}},{"type":"Feature","id":"310106","properties":{"name":"静安区","cp":[121.4484,31.2286],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@DLLB\\NPGLFHUDMYABEeKEVMAAJ"],"encodeOffsets":[[124343,31979]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/shan_dong_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"3706","properties":{"name":"烟台市","cp":[120.7397,37.5128],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@ŤLšLllVń²è°xżĢĠÆl҄šŤbœ„V¤ĊXnŽlĢVĊ„Òš„È°ĊŰÞè˜L„±@џn»VUźċ²»ÆkôVɆkĊŃ²kŤVVwUUVmUaƒ@KkU@ƒmUmmk@UwUkmW@UVIXa@ƒmw@a™KULƒaƒx@Uk@UbWU@yULmK¯@kXƒVUwm@@JUUknWKUVƒLUbU@™wWykIƒa@w@mUI@ašUVynIWa„k„@@W„bl@@knmƒK@wnIl™°Kna@V¥ğ@ġUķ»™¥@UōJƒX¯¤k@™wmI¯‚k@mwƒak@@šlX@bUJ@VƒbknWxkLkxlŽšLVlkLmŽšb@bU@ƒbU@VbU`Vb@n„L@Žmb—U@˜VnUVmnU@mm™@kIUWVIUK›VkkUJUnmL@VmLUaVWaXamU@™™U@KUUmVƒU—JƒU™VÇwğn™mƒ@mXĉV@l¯xnô"],"encodeOffsets":[[122446,38042]]}},{"type":"Feature","id":"3713","properties":{"name":"临沂市","cp":[118.3118,35.2936],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@˜bXlƒl@zlV@lXXmŽkbVVlš„U@Vn@@Vmb@XšKšVX„WJ@XXl@„‚ŽÈbVLšUl`„@XXV@VVUxVbUxVbš¦„@‚WnXVJ@bnVUzl@„°Æx„U„KlU@mUUnUlUVWVUnVV@XX°V@Všll@Vk„aXVl@Ux@bmbXLlKlb@b@bUJn@@„„b@n°x°K@an@@UlLVKVbXb@bVVnK°LVa@UVa@™Xw‚KVxnLšU°@naV@UWUkWƒULmV—wÝKUUla@aó_@mƒK@aUU@ƒWUkwVm@aVI°W„@@IUw@a±¯@¥kUVUm@a‚wkw™@ƒK@kVKk@maXalI@alL„WXblaVLVU„V@LnKš@„l@w˜aXašLlnUl„LšmV@n°J@_VmnIVym£UKmI@WnIVm@anUVmÇ_kġIÅWUXÇm@U@ݯÅ@ƒ™@naWƒ™IVW@IkK@klKn@naWIƒmk@ƒaƒbkKkLWn™WkLWmk_ƒ@UaVƒUKmLUw@mn£WwUmU™ƒaóV@UkUm@UKULUwmJUX@WW@XҙzVblJXŽWXk@UVWK—X‚¤UL@xU@ƒ@ƒVUaU@@XmVkLmWkXUyÝLmKXnVŽ@n@l™x@bWLnVVn™`knULmxUl„„WLXŽVb@VƒK@z¯x¯¼Wx™KUn@bk@ƒlƒVVVz"],"encodeOffsets":[[120241,36119]]}},{"type":"Feature","id":"3707","properties":{"name":"潍坊市","cp":[119.0918,36.524],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@l@@UšK@Ž@L@bX@@VlL@JƒLUVnX@`ÜXn`V²mJ@bU@@n„b@l°xnnĸVƚ°@„ƒĊ£Þ@lWnÑnkʶJmó°w@kk»V@»ƒ¥k@V@kw@wVm„a˜Å„mšaô£ŎƒXI@mln„Kla@mV_UKƒ@kUkw@alW™IU»™mƒ—@WUIl±UUÅU›bkJƒ@a@wUKUaVIÆmXIWaka@m@Ul£XKVw@ƒUIƒJUkmJ™ƒVkU@a„ƒWK—ImVƒ@UxmL@bX`WXU@U`ÇkUak@@°UblXk‚mLUKmL@VULóƒƒVk@@Vlbn@Ub@ċaUJUbƒIUlVLUVVbVKX„VlVXU@mb¯@™VmKUwLWx@šUb@VUb¯KmLUU@aWaUaULkK@Vm@@b¯L¯w@mƒa@ƒm@UUU@U¦lJUXƒVƒmkb@nm„XVWŽkb™IVxUV@VUbWLXVƒLW`Ux@nk@Vn@x@VkJ@œV`mXkŽ@V„xV@lVššI@VULš˜VU„IV`°bVXXx„V@VWVnL@xV„Ub"],"encodeOffsets":[[121332,37840]]}},{"type":"Feature","id":"3702","properties":{"name":"青岛市","cp":[120.4651,36.3373],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@„@nU˜JXLƒ„@blVU‚š„nIVl„IVJ@„UxWLk¤@V@nlbXbWJÅnUJVbVL@x@b„ŽlIœaÆVVVk²VJ@X„˜šnV¼šJkX@blxlV„@VLU`@nkbƒLkm@nWJō„ó¤™bƒn—ƃbUn@xlxU@l@„¦@¼UŽl¼ĊUnW„@šnĠmÈxšU„V˜I„VnUVV@LšV@šnVWbXb‚UVbnK@UnKVmVIllœUVLUJVXlJš@nnV@nmVUUm@—˜Vna@ƒK@mUaV_UaV@„aV@@a™anlKUk™KklwlKXwlm„a@UVI@akW@™l@„bnxl@°nJšxl@°£„WŎIUÑn»lašmô¹Ŏ¥VaUUkƒmkġWɱIUUŹ`›@kk@ĉƨřV¥_Ç@™Ĭƒ¤ÝL¯m¯£ƽóķwUW±ī¯kōaĉĕ™kğmó°ƒbW@UKkLUaƒVmz@V@ŽUxVn"],"encodeOffsets":[[122389,36580]]}},{"type":"Feature","id":"3717","properties":{"name":"菏泽市","cp":[115.6201,35.2057],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@@¥šIVUÈmÞ»@UlU@Un@VW@UVmkk@aVUUKVÝ@UVknK@UV@VVnIVƒ@wnƒmwmKXaWaXI@UV@Vy²blkVKkam™U@kb@Um@VmUkmƒKmkXKWwkU@Ulƒ@UnK@UVUUm‚KXwšUVL„w‚K„U„@@Wl@@wUkV¥—@@I@W@_V@VWUw@UUa@aƒaWa—@@_mKUw™l¯amzmV—@WK™nU@kƒWLķaUKbÝVmV@UWÇbÛ@ƒX™°UbW@XŽm„Vlk²UJUbmLÇxÅWUzl‚¯Ll„@VkK™XUbWJ@bU@¯@™ƒkbƒLmKka™„@l™_WšXºVbUz@J‚n²V@¤lX„Ž„nV°šLn`WbXLôVlKVUšxXn˜lXLlU@bVV@„XJWLUVnVV@„„@n‚l„°nn‚V„KÈbVXÆJU°VnXV„kV@@xVL„@šWlb"],"encodeOffsets":[[118654,36726]]}},{"type":"Feature","id":"3708","properties":{"name":"济宁市","cp":[116.8286,35.3375],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@nam_nKlVLXa„Il`š_@KVVXI@m@w‚ƒ„@@k@Kšnô@n`VbV@@L„L@KVVn@VX@‚VL„Jl„š@VUUƒU@Uam@Uk„wšKWaXamkJmIUVUÈblašUnV@kVKl@@lXL°kVJ@VÈnVJUX@V‚LXl@xVLnU‚@VK„V@a„IUaV@„bĊU„x„K‚kVJXUlV„ƒ„UVašI@WUI@KlUnw„mWk@WXIWƒ™U™L@Wna@Um@@UƒVk™UUlanWW@kkU@y„kWk—aWVUlÝbUU@kƒJUIU@@ƒ™JmaókƒLKǃUUkKWLk@WbkUUaƒbmKn¯°¥V@XwV@VanaVaU_@Wlk@WÈ@VUÈVVۂm„aklKȯlLVUX@lK@aX@@kV@VmV@VwnJV_UWUwƒX™am@kW@wVUkKVIUUVmU@UV@IVK@aUL@aƒV@Lm„UKmx@ŽômLkUWJ@šnXmlUxUL@Vkn›VUšU„@V™L™`Ub±LkV@kUKÇbÛ@ƒU™Wó_mJƒ@Wk@@Xƒ@ƒVLƒxUK™VWxLVnUV@VmL@Vk„@VlVXxWLnl‚Ln„VlUnn@@VlaV@nšlbULkl±aUzU@@VWJXbWbnLnxm„@xU„mJUUU@@VmLUl@VUÞVLUV@bllUn@VUXm@@VkV@VݼÇnUV™J@¦nnƒlnVlL@„Þb°KVV"],"encodeOffsets":[[118834,36844]]}},{"type":"Feature","id":"3714","properties":{"name":"德州市","cp":[116.6858,37.2107],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@„¤@VmbVXnVVbVJššX@Žll@z„lVInl@„@bVxUbĠ‚l@Èbla„IšxXVWb@L™@n‚ULWVXXšWWLnL@`@LUVVL@lVn„JšU@UUk‚a„™nš‚Vôô„b°¼V‚ސXš˜‚œIÜbČa˜bôW„XÞWÈzÆmnLVJ°ÈnlV²lbnW@™@UƒUV™šmnwmkkKWƒkla@mVIUKUa™aUwmn™JU@@amIk@@bVlkX@mmUklUUƒƒa@_UaUUƒV@wƒw™WkXmW@I@WUaÝU@UXaWUU@UUVW@UUUWUn¥nUVa@m@k@alU@wk™LWa@UUm@@wnmU™wla@anKn_@alK@ݙ_ƒ@@WUUUmlkaƒIƒyU@UwU_Wa¯yU_mWUwkImm@InWWUk@@UVWV—kW¯U@VƒL@b¯b@l±¦@šVV@lUbV„@škxVnUšl¼XV@b@lV@nIWxnbƒ‚™@UU™LƒxÅxm¯ƒaUƒ™wU@mUÅVÝKULm@bmKUXó@"],"encodeOffsets":[[118542,37801]]}},{"type":"Feature","id":"3716","properties":{"name":"滨州市","cp":[117.8174,37.4963],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@Vb@`„bV„kVlnV@nlWUk@al@nJ@bV@šInmVxšbVbVLUJ@nkb‚lX„lLnlmx™nUš„V@V@šmXn˜lbĸ@nnVx‚b@lnXV@UJ@nVxšxnxVbÆVn¯ƒĕ‚@@wÈçUÇlķVIœb‚@„Çmk@¥k@UkUK@aWakUóJW_UW@wkkWK@U@Kš@XUƒƒUkmUUalKXala@U@kkWlkÈl@kšV„mVIVmU_‚a„ƒƒwnwVW@wƒwUƒ@wU£ƒwkJWIyUI±bk‚VUJ@nmV™Ukl„Xmx@lnbW„kVƒUkLWŽƒxkKUUmUkb™J±—LÇxUKmkUmkkW™™a„mUaVkšJÆ_²KĠ@U„W@w„U‚¥nUWwK@aÝUkÅVaVK@akLWƒƒƒ¯I@bnbVx¯JW„ñšWbUL@šƒŽnV@VmbkUUV@IÇak@@bWak@WJUœJWL@bXV@„‚@„V„Jlb@zUlUŽUImšnbV‚mz@°UV@V™bV@@V@L@xLmKUnmJVX„J@VkLW@UVUL@b"],"encodeOffsets":[[120083,38442]]}},{"type":"Feature","id":"3715","properties":{"name":"聊城市","cp":[115.9167,36.4032],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@ô@VWnL‚an@VKÞLÆUnVV@šxV„„bn°Æw„wšKVVš@„maXwmJU@@k@aWUk»V™Umlw@™UƒVa@kUU@™²¥@k°a@a„K@U›ƒU@mmm@ów—ѱ¥¯@@w™Kmw—I›¥kU¯UmakJmIUaƒVkKUkm@VUUa™Uƒ@UaƒKUK¯@™w™UVŽUIUKVw™k™¥™wƒbVŽ@xn„@lWnXxlL@`„XlJX¦l°XxW¦@¦Ul™n@Ž™@@Um@@VXVmx@¯bllUnUJ@VULVn@b„xV‚VL@b„„VlnVVblV„ÈnVlIVJœLô„lJ@xl²„"],"encodeOffsets":[[118542,37801]]}},{"type":"Feature","id":"3705","properties":{"name":"东营市","cp":[118.7073,37.5513],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@ͬUǪlô@°Uœw°ōĠ¯š»Ģ炻XÇ@w™wƑa™ÇƒkwVƑ¯@řķUmm¯w@kƒa@mV@@anIU±m_ÛW@_mWVU„K@IkK@UW@@a@K@™L@Vk@±U@UV@lm@mUU@kLm„„xV¤@xV„„x@xUXmx„xƒ„bV`UnUJƒn™U@lÇkkllX@l@VkbWbkLVbnVVl„„WV™@@L@VXLll@xVXX`ôIlVXb@bVLVll@@¦nlƒÈ@›aUJkĸVÈÇè@x"],"encodeOffsets":[[121005,39066]]}},{"type":"Feature","id":"3701","properties":{"name":"济南市","cp":[117.1582,36.8701],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@²¦˜Òôxn@nn‚@V‚œ„°VlXU˜UX@Vl@XVmX@JnnlJVxnXV`°zXbV`VxV@„z„JlbkŽVnVV@X„@š`@ÞkL@bm`mL@bkbšxnVm@xn@VV‚@XbšKl@xkV@b@l@nUbmVm¦XVVV@VUXVVV@XVWb@VÞVVb@X@JnXlWšX„x@x„UVV@aVKVUX@lK@UƒIUWnIVmnL‚K@w@K@UU@ša@UVU@¯nyUman™VJVVk@ykaƒIƒU@@ƒWU@aXK‚IV›XIl@Xb@al@Èb@JVUlVna@UmU„@™VKXaò™Xƒ°IUwma@aU@UU@wVW@фw@a™I±`kbƒUkw™UmJ@UkmÇUUkmKknUVƒ@mJUkaWkƒa@KmKkUƒLmyXa¯_@WmImmbƒLmUkVUbUVƒJ™bƒUkkWJkUƒl™IUm™k™Lƒ›„lK@knaVmkI@mWaƒLUK™UU@@VmLUVLWK@UUUƒWUkkVmx@„Vl™¦"],"encodeOffsets":[[119014,37041]]}},{"type":"Feature","id":"3709","properties":{"name":"泰安市","cp":[117.0264,36.0516],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@n¼šŽW„nxšL@x°@š¥Uk@ƒnwlUVl„XVV@VXL‚KVUnK@UV@šVVL„KXb@nlJUnmb@lkLƒ‚„œšKšlVnšJ„klVXIll„Vša„IVUValUnV„K‚annnJ@X°`Wbnz„KlVnL‚Ž@L„bXl‚bVlnI„@VUU@UmVƒ@U@Uš¥@VmV@@_Ua@m°@@ƒ„kmUUm@UVmn@nX‚@@a„anJVUVL„mlIVJn@nkVLVa@KVmVLXVVLš@@U°bn@VaV@@K@aVkœbWaXUVymU@aUImWXƒ@™¥UaVwUaVwUUU@WWƒ@k_™VUKÇa@ƒƒnmxkV@LVJ@X™JUbƒVƒ„kUWVUIlƒLƒwĉVƒaU@VbƒJ@bƒUUL@mVUK@wWkK@UVWUIÇm@UUI¯lWK@kk@UL@lmU™VkbÇaUVVnJlIn‚WbXb™LƒxVln@VbV@V„UV™@kƒƒIUK@UWm@UU@LƒK@KU@Uam_ó@™m@L@lƒ@„@x@nWJUU@L™`k_ƒJWbUKkmLn`mb"],"encodeOffsets":[[118834,36844]]}},{"type":"Feature","id":"3710","properties":{"name":"威海市","cp":[121.9482,37.1393],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@VbUnVVUxĊ¼š¼ô@Þф¯‚WǬLŎUÆW„¹Uǃō¯ÑƒÝkţ™™ţóġ™óL™ł̥U™wm¥kÝmkkKóbÝ@U¦@‚mb¯LkšmJ@x„Lmn@lk@ƒa@Xƒ@ƒlXbmJUz™V@bVJ@n@x„blJXzšxV@Va„KVUXLlmVV@In@Vx„UlW°@nLVK@zXVVal@@V„w„bVKšL@bnx@„WbUJ@VnXVlVxl@nnnV@„lV@L„‚"],"encodeOffsets":[[124842,38312]]}},{"type":"Feature","id":"3711","properties":{"name":"日照市","cp":[119.2786,35.5023],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@UaVUUKVk„JVaVIČb@Vam@ka@Ul@„Uô„VK@UnKVLnKlkWVa@¯l@VbÈlV_V@XWW_@anKVwUmVw@@Uny„UVblKVLX@„aô¯ó¥mÛĊÿÈ¥š™Þ¹lUīƒ¯Kĉ¼ʟbÇV™U™ŽUŽ™XmakJUnmV@bUnmJ@XnJVLn¤UzmJUn@`¯ImŽU@™nƒKVkkm™KWb—b@xƒk™@mL@KƒUUVUKkbWaƒXkK@bkJWbnbl@UL@l„Lš@lxx@b‚nUVlV@¦²°@bVx@Jƒ@¯XUJ@bUnlxVŽ„X@‚VV@b„L@nô`@bkbVVÞL˜xnU"],"encodeOffsets":[[121883,36895]]}},{"type":"Feature","id":"3703","properties":{"name":"淄博市","cp":[118.0371,36.6064],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@nƒlKV@nVn@@kVU‚@²VVaUƒ@wmKXU@UƒUWwUW¯aU_ƒJUV™—VK@U™JU™@kUƒw@UlnWU_@›lI@U@wUml@@mVwX_„KWUXKVa@UVUUwšJlaXWUnƒ@mla„n„UVWkIV¥V@VVVI@a@akakLWKna@aVwk@WUƒbUlk@™k@U¯UWWU@mUUVUXkVmVVV@nkVƒLƒVÅwƒ¯k@WVXb›aUl@bV@@b@xkVVXVxkJ@nk@@ŽVLUlVb‚VXUVVUzV‚™LVbUbV„VWVkLmškJ@n±@UxU„VVkV@bƒx@ÒUX@xVVV@°J„„X„lK@bULUblÆÞV@b‚LXxmV¦ƒV@xƒXVŽğ@±LÅ`™IUlVbƒnšbXšllVnnlVLÈw˜K²ŽšIlanVVVlL„wXlK„VlUXƒma@knwƒWlkšVnU@mVIUl²aVJ‚zXJlI"],"encodeOffsets":[[121129,37891]]}},{"type":"Feature","id":"3704","properties":{"name":"枣庄市","cp":[117.323,34.8926],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@‚yUU„U„kl@@aVmšLXw°»°w@y„L@UUaWXKƒƒVknwVKlmš_UmmUXK@ašw@k@mUWmUL@ƒ@™@£@KƒbÝV@akw™aULmƒƒbUK™LUU@lm@—°mL@nUJVxVXU`mIUxU@UnU@@lW@@bkLW@UVkKÇ°kLlŽƒbnUÜÇUUVÇ@@Xkl@XV`UbmbUbU@WxU@¯¦m°nL„aVblVXal@XKlLVVȄ‚L„KôlnbšI@„V@VJ„I@lVVÞaVkXU"],"encodeOffsets":[[120241,36119]]}},{"type":"Feature","id":"3712","properties":{"name":"莱芜市","cp":[117.6526,36.2714],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@lmnLVlÈVln@VnIšVlx„Vla²_šJlUUUVƒVw²@@mlIn™lKXU‚UUƒVaUašKUVyUUWVUUaVkUK@l@@mlIUwUWlU@w@aU@@LU@Ubm@¯a@V™@UKWUUKUn@LUbUKmlm@UIkJƒnUKUVmIƒb@b@mWm@Un@VVnnVƒl@„¯@@nVb@`U@Un@Ž™¦@V@VU„VnV@"],"encodeOffsets":[[120173,37334]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/shan_xi_1_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"6108","properties":{"name":"榆林市","cp":[109.8743,38.205],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@™ýVƒnIW»ƒW@»kUÇL—݃U¯¥ÇIUWWїUWwX¯mƒ@»n@ÜÈķô™@a±kȱƒw„ÑmwçċmU»ÆkkVyIm™ĉÿ@ƒÝ¹ƒWnwÇVš™Åaƒzmmĉ¦ó™kVmx™xU¼VškVm_UlVlk„°IV‚kmJa›¦k™™LmmV@XmKnšlUô›VXbƒbƒ@UaÇLğܙ™Åwƒ£mKnmċwÅ@UkƒbmaVƒƒƒn@m¯aU™Jm_k˜@kWXyl@@kÅamw™LU™Þ™ƒ™mWÅzUKƒš™Uk±@™b@nnK‚bX¤mzVšŽVxÇn„‚¯„@ÒknWƒƒVUbkķÈÑWkk@Va™™U@„mUkbƒÝÅ@Ý¥ÇbkĬ™XV`kLǍVmalUUa™nV±nwmkƒJ@Inƒ°KVw¯UnÅ@¥™ƒ™U±bUU˜±œmWbÛKWnUm`UƒVK@bmnœm‚Èż@V„L@xƒxmš„Ť°nŽ@VmK™²VlšlKk„ô@„êÜV@VXLlmš¦UššV°Ș¯²ÿ@¥š@ƁĊ˜²IšmĶnnb°b„KVƒĸLl„Þ@UȮš™Ü°IVƒÞÝސlŽœx@ŽķĀWŽ„Ux„èƐ@š°ŽXnšlĊĖ°m„nƒšV„²V°ÒƦ„aބ„˜@zll@bÞĀšlš¼nKĊ¼óȂb²±šIǪÒ¯ĖV@„lxnVlk„JlaXwŌĉ„„@VnŽššlÆĕ„UÆLœèŌŤôxȚlUœ@šxlaUċĕXm„IWmnkšVVƒ„VW_@aÈWUUmk@ƒ¯çVm»™±W¯n¥V™mkXw±ÇVwƒ"],"encodeOffsets":[[113592,39645]]}},{"type":"Feature","id":"6106","properties":{"name":"延安市","cp":[109.1052,36.4252],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@@kkÇmIšmUwVkUƒƒU²WmšVkm@m`mIĢĕUƒVa@™mXƒƒÿVVkyUýšĕ@l_UmnƒW„KVkţ™™¥™aƒwğ@™@aôƒ„ƒWa„kUmƒa¯¯™a±£kx™mmxUwÝ@xmU™b¯K™wó„Ý@kmm¹Ub@lklVbmnnVUV@x›UknƧJUX@ŽƒLÇWkw™LķƧÅwWJk„ƒLkþĉxWz™JUnǚkš@Ɛk¼ÜÔÈKšè@°lșÆk¦l„n@l¼@l¯L™°UU™VÇ°ƒ¹—`m¼mXk‚™bUaƒV@U¯x@¦™Ç™„UUmlmUVm„nnmlkw™@@šƒ¦Å‚ÇLmx¯Iklš„@¦mÆ°VUx¯Lm„@J„InlmxU²šmVbkV‚bUnȎlKU_šWlīÈaÞ¦Æ@„ÞlanV@ƒšVšUbl@XlÇÒĸlŽVa„UX„lm@Ñ°ƒƒÈmUw‚U™nyW£amL@mša²@lšV„™VLÆynX„šÝšVššKnxÆb@lk@WzXŽ@ll—n`šIV‚°b@n„m„„‚Unb„aVlÆ@ČxmnnL„¤ÆxššĠÛÈKVb„@„aWaœU‚ókVm™nL@W‚UnnšKlšœ¥‚bnIlU¯JlƒUkVkn`lUU™V»šwnwlUôšĊ¥nn„yÆb"],"encodeOffsets":[[113074,37862]]}},{"type":"Feature","id":"6107","properties":{"name":"汉中市","cp":[106.886,33.0139],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@lKnb@n„lWb°bkxĸwVb@ł„nlŽ„ƒĊ¥šL@XŽl™ÈƒVblÈK‚b„akVwôml²`‚nœ@‚nVKœl˜k²xŎƒ°¦VU„JĊw@çnWçރVkUóÛ@¥kwš™šUmƒX¯WšÑkƒ@UymIUwlUn¥‚mUk²a°¯V»@™ÝVș„ÝċÅÅVl»@l@a°±@_kammÅb™a@ƒƒm@ż™KknõĠ—@mšƒ„¯LÅw›‚—LVxmb@¼kV™@mw¯wVakKW»X±¼¯Vkxƒb„¼WŽ@nx@x±bóakbƒ@ÝmU™@ķÓÛL™kƒVUm™k¯¤ÝLUlÝ@Ýz™š„x@x™°™™™bƒmƒX¯aUJW¯—k@bÇWƒwÛwWxƒ@XWlb@Žƒ„VŽÈUlwšLnl°VlUô¦œU°¤VšUxVXUxlbkVVlƒI„°„ÅVlU°m@k„ÇU¯xUlƒLUlVL@b™°ĠInĠ°ÈnK‚„@xÞa²n‚aUyšXUKVkšWô¼Èa‚z°JXUVÇV_„JVƒšz@Žnb"],"encodeOffsets":[[109137,34392]]}},{"type":"Feature","id":"6109","properties":{"name":"安康市","cp":[109.1162,32.7722],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@„bĊaƨèšwôô„¼šb°ašXVƒÞVUÞ@‚aXƒm¥kImx¯¯ƒV@anU@UÇéğL@ƒ¯¥V£mƒ@ÝÈb„K‚™„X°wČÿ˜ƒ„b@xÈblxȯĊ„„mÆUVƒ„nÈ@ƨÜLĢ¥ƒŹnƒ°Vnn˜K„aô_ȃšwU‚aXmnW‚¯kl›LXƒÇ™ō¦ÝaÅVmbğUn¥±wÅéVƒan¥ƒ„U„»°am¥„£ƒÝ@ƒ„wVw™¥nU„уUmmVwmķIÅaóVWxkblb@ból@œğÒĉ¤ċXƒ˜¯X™xk„Ç@óÆÅx@š™xķ_kmݎǣkblb@`¯²@bk‚‚@k¼ÆUČƃÞǚÞU@šU¼¯°±bVlnm¦kVVxnJVz@‚l„™ÒXW°n„™V™šlx@¦ôÜVUl݄Xèm@è"],"encodeOffsets":[[110644,34521]]}},{"type":"Feature","id":"6110","properties":{"name":"商洛市","cp":[109.8083,33.761],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@²nl‚ôbš„°aVwnKÞIš`°wšXôw°VĊ°@ŽÅš„ÞÆV„zÞK@xšŽ@a‚LŚ@b@ŽnLlƒ@šln„mnLVw„a„bVƒ‚VnbU¼„Vƒ°„bl„šbÈ@ĶŦb˜@nÇ@amIyUI@ĠVmôƒU™ƒVwkwlanJ„¯lwó¥@an°Jš_„‚@š™nóƒó@£l¥UwmašÑ@ƒUm±V_ƒJ—£›J—UW¥¯@ƒ_k¯¼mUƒVUè¯b@wmL™»ğVmağI¯¤ċIUW™XƒKĵ¦ķaƒJUb™IƒlUóVmk@WÅÅÇ@ƒmU„ÅVƒnĉƒÇ°kwÇa@wƒa—„ċĀ¯xƒWšƒLÇa@Þn„U¤°¦@„ĠKÈê@VmV@b„U°°nwlJn¦W„bÝ@VŽ"],"encodeOffsets":[[111454,34628]]}},{"type":"Feature","id":"6103","properties":{"name":"宝鸡市","cp":[107.1826,34.3433],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@@ƒ„£@›°Išb@¯°ynŹƒaUƒlƒU£„Umšĵĉ@@ylUÞ@@£kWU¯WaU£¯ÇV¥ƒ@kb¯wƒn™¥ÇkUÇnUƒ@¯±›kULm›@m±_kŽónUxlŽƒbaÇLkŽUaDŽkšW@™Kĉ¦ƒ„kƒm@ŁUaķxlw¯aXaƒk@mmakL@šmšÛŽ@¼m„@l„XV`ƒn™KUš°°@²š¤UÈ@VxmôƒxKl„VV²aVw„Xla„Vlx@UVnŽÇnk°ƒVVL™lkI™šƒJÇk¯V@šknƘn@lznmlVkzVŽ„VVxš@Ux„z@x±¼VxxU„l‚kb˜@„¼Čk˜VXlĠkôV²w‚LUKlwœJ@a‚IV¥Þƒn¯Ün„‚„@nk˜l²kÆ@š°„aVbnI@™š‚Ťn"],"encodeOffsets":[[110408,35815]]}},{"type":"Feature","id":"6105","properties":{"name":"渭南市","cp":[109.7864,35.0299],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@@ÈôL„xUŽ°„Þ@mŽÈnl¤nUôL‚wX`@ÞÝL™ŽUšmLô„„ŽôbVbnºlnÞ@ôƒšx°LšanV‚wÞ@Vxnwšnlw²¤šb°°„bVnƒlXbƒ„ó„@bš‚Ġ@„xšbš¦ŤšV™Xġ„£W¥ƽɽƒó@ýóƝÝ»„£X™mƅšĊkUƒ„@™™šó„kťaĵŽÇ@™akƒƒa„¯ƒUV»maUU„ƒaƒbUxmKƒnkm@™k„mK@ƒxó@¯n¯KǦ@ôÅèlxkx°nƒƾ¯KU¯WķL@VÝIUb™yWbX¼Ç°"],"encodeOffsets":[[111589,35657]]}},{"type":"Feature","id":"6104","properties":{"name":"咸阳市","cp":[108.4131,34.8706],"childNum":14},"geometry":{"type":"Polygon","coordinates":["@@šIXyĊwlý„KlƒXIVaķƒ™»a›£„¯aVU@a™‚wÈō‚ašL²»‚VœUln°WȯW»XašzVaÞJ@Uƒ»@¯Ýbğwly@£kÑţ±Wу@ka™IUƒƒnƒ@¯ƒómţU™b™U¯lÇIÝb@¤Ý@kV@zĊ@™ĶnƒVV¤k„V„„bmź¯z@°™a¯J@œƒ¤@„„bUx™bƒ„@`™xUÔ±ºVXœW‚„UnUJ‚LĢ¯ÈKlblmÈXŎ°šU„°LšŽlkÞKš@Èxl_°ĶUÒkblš"],"encodeOffsets":[[111229,36394]]}},{"type":"Feature","id":"6101","properties":{"name":"西安市","cp":[109.1162,34.2004],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@°²@‚„mVVÈÈlš¦„m°xla„@U¦°ÈV¤XbV°lXÞaÈJ°kšVšaŤVôn°„„@„mV„šJlb„@XÒŤ²lÒ@¤kzĠxÞa@°„¼ĸK°XV‚°L„ƽ¯mlwkwÆç@óÈ¥°L°mô@„w@aƙK@b™@wÝLƒyÅUƒÝƙ@ĉ¯¯Uóx™W¯x™_ÝJmLUx¯b™ƒóak±mÝUU„™W¯b™aƒ»óó™xƧçĉbƒaĉxƒIUV¯¥ō„±w—l"],"encodeOffsets":[[110206,34532]]}},{"type":"Feature","id":"6102","properties":{"name":"铜川市","cp":[109.0393,35.1947],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@ÆxĸƨšKlxÈX„K@VWƨIlmœV@wVUmUnmUalk@kVaUaóaƒóƒnKV™šÞK@ÝW_xóKmVk£ÇmnÝ@¯ƒVƒwóK@ǯXkm›VU±¼™KbÇŎx‚š@bUV°bƒœ¤‚bš¼ĸ„Ub"],"encodeOffsets":[[111477,36192]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/shan_xi_2_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"1409","properties":{"name":"忻州市","cp":[112.4561,38.8971],"childNum":14},"geometry":{"type":"Polygon","coordinates":["@@Vx@lnbn¦WlnnUšmš°š²VšV‚VVVnUn„ºlz@l„„@Jƒ@kXWVXl@Lƒa@„ƒKUL„ŽlbnKlLnK‚LnKÆXn°šbVV@bUVl°Un@LnaVJUbW@UX²l‚@ČwlVVIšWnkÆa°„„anV‚Kn°™UW¯@™aVUVk@Un@„aV@ValwUanmWU„k@WVUUanaVwnLVl°@nk@mVU@UVK@w„LVKVU@ƒ„K@UUKVUV@@bnL„a‚V„aôšlIXmlKX_°KVV@bVV„@šzV`kblI„V„Ul‚šL@bnV@V„Ċll„„VlIXW@k„a‚U²blKšVnIlJ„albXXlWVn°JnšnL@l@XlJlaX@„X˜W²@l_VmnKšU„blU@mnkVK„¯@U@ƒma@kX¥VƒmakkƒLƒa@aƒ@WIUUVXWWnk@a°a@kkm@kUUmJm@WUUUIk`m@V—kaWWkX™KmƒXk¯ƒ@WKƒLkak@±bƒw@ƒaƒa@akaƒ@ma¯@ƒL—KÇÅkKWbkmġ™±ÅUƒLUK™VVkƒm¯LUVVbƒ„UwUW¯bm„ƒULƒxWJ—@ƒklmkUm@@KnwVkVK@akwƒ@@a¯bƒKkn›VUI™b¯mmbk@UbmKUL@xUUƒ@klmLUŽlVXI‚VVVUVUœU`mLXVWbXnW`Ų°xmŽxU@mĉƒƒwU@mbU@UƒmbkVW¦kJ™@ƒX@`¯Im@UlUVVnb@bWJXnmbƒJUU™UUaƒ@UamIkaƒxƒ@@x@b"],"encodeOffsets":[[113614,39657]]}},{"type":"Feature","id":"1411","properties":{"name":"吕梁市","cp":[111.3574,37.7325],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@@a@w„@„wlbnJVb„@VbšVVV„InaWmXI@a‚aUmVUVkn@°J@_„Wš@lIX¥lUnaV„V@naV@„xĊ„n‚V@‚wn¯wƱX_WmXaWUnKV_V›VUUUUWJkUVnKlk¯™@@kmKUaŁ±KkU@WmI@WUIlUUmVwXƒ‚w@ƒUlUVwœV‚@„Lnb‚W@anU@UšaVkô@l»n@na˜JnUÈLVaƃUUVm„VKVƒ²L@mU_lK@UVWkU‚a@a@U¯aUaƒÑóÑUb™„ƒKk@@aƒk¯mVaUwVƒÑkWUmK@UUKmXUWÝwUa™LUU@aWJUUU@Ua݄U@WL@VKVaVI@WnU@alIVKƒƒ@kIƒmIkJ@™m@ƒ™@@_™K@xƒ@kaW@U„@Vmn@ŽUK@mIƒJUXV¤XXWlkKƒkkK@XmJVakImJU@ó™¯LWKUV@nUVƒLkxmKkLma@kXKmmƒLƒab™LmK@V@mXVÆUxƒX@`nL„aV@@VmLUVnLlLš˜„b@„šŽ°²nx@b‚VUxlb@V¯bUV@zV‚XVĊXVx@lVn@VnnmŽUš@LlJXVƒz¯VWVXbšV@bmn™VUVk„Çþń@XVxmbUlV„Uln„W„@„Xl‚@VLXÒ@bÞJ°¦„L˜ò„@nU‚b@°„X@ŽXbmVU„V„nb@x‚x"],"encodeOffsets":[[113614,39657]]}},{"type":"Feature","id":"1410","properties":{"name":"临汾市","cp":[111.4783,36.1615],"childNum":17},"geometry":{"type":"Polygon","coordinates":["@@nW‚@@UnLšK‚a„b„KnnWL@lnblKnLlw„KVU@mVUXL°KôšV@nIlJUbnI@WlL„llLXkWWU£VW„InJ‚@VL@nm@UVƒX@lb„@@wšL@`‚@„šn@V@lw„@n„VmVX„WmwnUlƒœa@_lK„wVlUn°xVKVXXWlUšVVI@K@K„n°KœwlVlU@kna@V_„Wn‚m„UVm@kXml_@m„LlKXw°m@_ôJVUV@X™l@UaV@Va°I„lk»VwUkVmwUmmVn@V¯@KƒU—wmK@U¯wUVÝ@mJƒU—nWK™@@UnKVa„_lykUmKÛnm@™x@ƒUUlwVk™ƒXW@ƒa@Uƒ@@K@ƒkIV™nammVakUlƒ@wX@@kƒ™¯@ƒVVbml@„„°UbULmlVbnbÅK±VƒKVXUJWa@ULWaUU@@U@aWK@UkxUKƒLUUUJ±UkL@V±kk@kam@UV@l@LWl@n@VVUx„LlUUx@VUV™U@aƒIUl™L@°mLU‚ƒbkUUaWUUaUU@aWK—LWJ@bUL@VUVVbU@m@a@kmKmnĉlUK™XƒWUblb—xmIkƒƒU@xWb@lkšVx™LXŽmzVV@bklVVUzm˜@bk„@Vx@xlŽU„@lUbVnl@„Wxnl@n@ŽUbV„mL‚mƒb@`X@lUX@@xlnkLWaUJnnWV™Vn@l„@bULVV@l™V@XnJVX"],"encodeOffsets":[[113063,37784]]}},{"type":"Feature","id":"1407","properties":{"name":"晋中市","cp":[112.7747,37.37],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@@šlInJ„lJ„@‚„ULkJ@bmV@XUJUb‚L@UXKV@ރVbV@VVXI@bVVšKVbÞxVXnWVL@VnLV‚lX„ÒUŽVxUb°n„l@bl@„LšƒVaô҄ÒVb°b@VnLnnV@lmn@lb„U„V@„‚JœUVV‚Xkl@lUzmJ@xšXkl‚bUn„JVšUb„nU‚lb„V@nlLX@lakšV`Ub°š@XVJnU‚L²KlxnI@KV@lbUbVV„KnVl@„zlm@Uš@nŽšI@WUaVl@@mVU„@XkW@ƒnkVKVƒ„_Vw„y@knwVa‚@XalU„@šVnml@„X@V„L‚KVaÞbnnlJšI„mVKn„VVVInVlU„@„m@™mXK@UmyUI@mWUUakamw@wUwmLkakwVƒmK™w@wUam£y@am_ƒW@™UU@knmm„amU@WUa@knw@ƒUUUUV@nƒJm@mVUkKVUUUkKmwƒKULƒKUImV@lUn™nŽm@mbUK@°™bUnmbUmkkƒWUb@am@UXkK@a±@™V™@ĉř„V‚UXVxUVkLWl¯@@bULUlm@@nm`—XƒlWakIkm›VUbUL@Vm@kIƒ@@Kšm@—VaX‚I@W@aU@kUƒVU_™KƒbƒJkkǎ™b@nkKmL™wÅW@kVUUƒVU@WUIƒJmIXmma@_kyVaUUlkUm@ƒkU›x¯Lƒm@L@LUJ™UkVWXUWUL¯wVmUkƒxkL@`›bk„mVnxƒXUWUnmƒƒ@kxU@"],"encodeOffsets":[[114087,37682]]}},{"type":"Feature","id":"1408","properties":{"name":"运城市","cp":[111.1487,35.2002],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@„Vl„nJ˜wkaVa„XšWVLĊknmnL‚l@@bn‚V@UaVU@UVK@aXI˜KXL@bVVVbXVVblV„aVnK@¯šKVk„J@bšVVU@UVwkVƒKVwUUm@@Xk@K@kVUn@lbl@²l@UlK²VVIVV„KVLlw@VXL@b@VV@VŽXbVK‚@XbVIUW„L‚U²ÆLmaUankVKVaƒ¯@ƒnkUa„U°@„š‚n@@kWa„UVaXUW@IXKVw@U™ƒ„™WU@W@@UUƒU@mn@ƒ`m@UUULkUmJ™IUƒ@@UƒK@U@›anƒ™ak_@wmKUwmakV™kmK™V™k¯b™wƒ`kwUIÇx¯»ÇaŃmn@@™mƒmUkV@wkKW@kxmL™UkĉLÝk™xÝw¯lóVU„mV@ĀVVX¦W¤kz@`Vx°„²ĸ‚š@„Ul@x„êĸNJ°¤V„VlXLWnXxmV@nUl@„"],"encodeOffsets":[[113232,36597]]}},{"type":"Feature","id":"1402","properties":{"name":"大同市","cp":[113.7854,39.8035],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@²£šyl@Ȑ˜Ė@bĸŽĢbĸ„˜X„a‚KŤnn@ŎôllÈx„nVnÞDŽV@b‚nXllL°KšbVb@J@b—„‚„@ŽU„„xlKXLlKlXk„@Ulk„JlkUƒVKXUƒÇVIVm@_nǚLšašl‚w„VnU@UUwma@aƒaÝaLmUk@@Wƒ@U@@X™wVWÝUUUk@@VmLƒKV»nwUw™aUL@`mzƒJUIVƒUaUw™KUaVIlJôanÑlLVUn@ša„@VV„@@UUwVK°Vn_lJÆLœéW@UUUÅ@»lm@aÞIVwXW˜UUkkm@U@aƒU@mwU£VWU_kWmƒXwW_°yUkkK@UÇK@kkUVymóK—U@KWIƒbUak@mJ@bkbmLkŽ™UmƒkVU„W¦@lnb@„@Vƒ°ULml@nkVƒa™VmLUnk`±@—XƒWW@kbǦXŽ¯„WxI@xmbmxXlWV„„@bŎUz@J‚b@bÞb™ŽU@Wbk@ƒxk@WX¯VۙƒWÝbÝUkVUU@alI@a@akLWa™m@U¯UUmÇL@K@aU@¯VUkƒKmX@`@œkJ@nV‚Ub@lbVÆXVW„ULU`VbkLUV@XWl@bXJ˜@VbV@Vl"],"encodeOffsets":[[115335,41209]]}},{"type":"Feature","id":"1404","properties":{"name":"长治市","cp":[112.8625,36.4746],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@Uk™Lky@I‚JVa@mÞaWšy@_W@_WƒXVlUVwš@nw°K@m„UƒVaƒmVkU@mmmnLVUmKXa™U@IlKVUnK@UmWkX@WV_Vƒ@akU@a„KWIXyƒIUVmUn™Ua@WaXUVKVmkUWVkUƒLU@@VƒbƒKbƒIUmƒ@mbVL—x›WUUkn±V¯wƒbÅJUbmLkbmKÅKƒbVnUbƒV™KUb™KUbmLKmƒb™aƒKkUm@UŽnn‚VnxUVlUxl¼ƒk¯JUbU@Vbk@WšU@UVóI@`¯nWxkLƒK@nk`Wn@lUnƒVnm‚ƒXU`@mb@lkV@„VnklVVUblz@`nbWnnJ„IVJ@XUVV„UV@lÆXšxnKlL@mšaȍll„I„ašLV`„UlVV@@b@XJWUb@˜™n@L„@lJn@@UVKVaœUlnlJXb„k˜Wn_@mn@VkVK@a°@XklKVUUwVWUšƒĊƚ@šU²@@blLVWn@@bVa„XllVnnaVmša@¯VLnan@‚šmVm@knUVJ"],"encodeOffsets":[[116269,37637]]}},{"type":"Feature","id":"1406","properties":{"name":"朔州市","cp":[113.0713,39.6991],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@XXWVXVWnnlnn@èƼ@„„xlš„ŽV„nblšššVŽÈUVl‚š@„blnœL܃ĊmUkU@Ua‚—@WI@aXk@WVUlKUaV_VKXƒWUUÅka@VaU@mlI@›@_nW„LVl°UV@@b@LÈKVn°V@VšnXblK@b@bkJ@bVVlUÞVÞa„Xܚ°UXWl@„wl@XaV@šÝa@aa@IVyƍ@aƒƒXUWknwna@w‚JXw°ƒWÈ¥kI@W@kmKm™¯IUmkXWWkaƒbkImJ™UkL±aVƒb@lWXkJƒUkƒĉkƒ@UmU@a™KkƒVƒUkJlaU_™yƒ@UU@aUU¯LW`kLWnkJó™ƒbUƒbmK@aU@UVVL@VƒL@„UVULƒK@xUL@VUV@nml¯@UkmKUxmbVbUV@XƒlXVmnVbkxUbU@ƒbm@@VUlUVšb°@VX¯šm‚"],"encodeOffsets":[[114615,40562]]}},{"type":"Feature","id":"1405","properties":{"name":"晋城市","cp":[112.7856,35.6342],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@lV„Lšb„an‚LnKVašLVašL„UVaUm„aÆLnLlanKVaÆI„a°x²UlmVVœX˜wUKna„@Vn„J‚a„L„a@UV@@alUkKVKnkmmVwUk„w@ƒ™@kxWUXƒW@@mƒk@aUa@a¯aƒLkKmwkUm@kL@K@aWIXmƒVƒXƒWkUVakL@UVKƒw@aUK@UUKmLU@¯n™KUwVƒUIWJUWmka™@UXƒJƒk@UkmW@kLWKVƒx@bmI@VUaVU@a¯@UUmVKmX@±`kÝKVxUL±akL@V™bƒLkKmVƒ@XWVUbƒVXb@lm@@lW@@xk„lVUbnnmbUšlJ@„@L„@@V„b@‚WXš„UlkxVV@„šwn@ÜmnLlVkzƒ`UbmL@Vš@XL˜m„VnIÞ@VU°x@VnL˜x„V@LU°"],"encodeOffsets":[[115223,36895]]}},{"type":"Feature","id":"1401","properties":{"name":"太原市","cp":[112.3352,37.9413],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@„@VV@wVKnLVal@na°nšaVJœUlm„L°a@b„@lx@bULUlmx@Ln@lVkn„l˜@XI„w‚K„Vnƒ°aVXVx„ƒUaVU°K„nUlšUVL„KÆVš²Ģ‚lnXalLÈƘL„KUaVkUanmWU™a@WwkUWU¯y¯Ñ@anIl@@aVU„m„I„ymUƒLUUVakaU@@LmJkw±LKmVUI@W¯™VaU_l™kbW@kK@mƒUkaVƒmVaU™ƒIVmalk™W@wnIVy@klkWUU›VI@ƒƒUƒVkam@knU@mmmK@bblVUX@VkLV`@n±KU„ULƒ‚UnVVńUbÇKmV—Imbm@k¼ó@Ul™b@VmV@bXmaƒK@›UUxkV‚V@„xW„UxVnkVVJ@XnJ@XlV²LƂVbnL@lš@°"],"encodeOffsets":[[114503,39134]]}},{"type":"Feature","id":"1403","properties":{"name":"阳泉市","cp":[113.4778,38.0951],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@°@nb„@lb@b„b„b‚@„x²al@lb„KXU@m‚kUWkkmUUƒVwV@XUW@™naVklKXblKnL‚ƒnLVanImaXKlL„ašV@U@KUKW„alƒXK@£WKXUV@VU„ƒUUVW„_V™@W@@K„@šƒUƒƒIWmXUmƒULƒn™JkImmÝaUbLƒK@UƒWk@mn™Uƒ@kVWb@Ubmx@lƒzUxƒ`U„ULml@„XWlƒ@UV@nk@U‚Vb@X™Jm™@@Vknƒyk@ƒzƒJƒnUV@bk@mJ@b°Ò°zXVlVXx‚@šbXVmnVbUlVb"],"encodeOffsets":[[115864,39336]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/si_chuan_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"5133","properties":{"name":"甘孜藏族自治州","cp":[99.9207,31.0803],"childNum":18},"geometry":{"type":"Polygon","coordinates":["@@ƒaXamƒ¯wm@±°wUwV@UaVw²Kš™„U@UƒU„¥‚a„ƒ@£Þ™ôx‚Knkm™X¥™IUƒÝUwlk°V„@ƒÈ™‚KUwlkUyV¹„mšx²Xll„ÑW»š„l„w°UŎ„nƒ„„˜Jœƒl¯°V@wôIVÇn™nUllšLšVǚLô¼XW£@±„@¥k_ÇJƒkUéƒkšƒƒwXa@ƒšLlw²™Vx„b‚mš¼ÈxlLȃ„VWÞn¯mǙÑUÝlÛkwlĉmƒULmwUJ™ç@wkm@ÑlUX™ƒÑôġƒVa™ƒUф¯@wķÓkbV„mnU@@y¯IķKƒV@¹šaƒé@k„mÞU°¥@a¯@anKlblU„¥@óğç@Çw@wkla„çݱk¯±@ğÝUÛmݯwƒ@kb±¯akXWÜkXUÆÇUš¤X_Ɛw„V@¤ƒXU‚ƒbUƒŽƒIUlÇUkŽġ@™aXČmlUlèUV@„mVk¦Vxš@¦±š¯ƒƒ¯¯anlWš¯nƒƒÅw@w°KVak£m@klƒKknÇU™»óKšīlaUaV£@™™¯@ƙU™VƒÛÝÇXƒÇl—ÓlŹ„»WUğJ¯£mx™Lĵô›ºX„VlUll²bl„„lŽƒxónn°ÝšU¼mJUš¯nƒƒƒV@êĉ°Uĸ™w™@mƒ@¯kmXamѯaUwÝKU¥„mÅn¥Wmn™ƒ¹n±ƑƆÇôXê±NJnšƒ‚UôlĖkȂVÒ¯¼VnƒȮ¯ĀnƆ˜Ģ@Žk°V°¯ĢVlkšVxm¼X²™Ŏ@ŽVxknWÜ°U‚¯n™Æݜ@`„ôݲÒƒ‚Çzn‚mX@x„è°K°Å„UČĬóĖ݄ƒ˜ó¼ÅêƒÒƒbmšk@V„Ž˜„@ҁl@nĉܛê—x@Ėml՛J¯¦óxȭ°ÝmŽ¯Lĵè›Ā@Ɓ„l°żƒ‚šX@xmŽkV@z@‚„°blŽnÞ°J@bn@ƼUVƒUóŽóLƒ°X°ÝLƒxUn„°ƒĬƒn@lnL@ŽÆ@šn„KÆxnUnV˜InĬmÆnxŎ¼ĊIĢóÞ@ĊƒƨbUƒ‚mV¥lkƒ‚wnL„mšÅÆ¥Xƒ˜wU@w‚wUÞ™@alUUŚU™Vkkm°aU—°Ó°w°U„ƒ„b°aš²K˜¯œĕ˜@ÈbޏĊaš»„XVm°In„‚Ĭk¼Vb„ašJšôš£VĊan™‚k„ů™™nƒÜU@anKnĮ‚bÈmƎš»nI‚霣Ġ™"],"encodeOffsets":[[103073,33295]]}},{"type":"Feature","id":"5132","properties":{"name":"阿坝藏族羌族自治州","cp":[102.4805,32.4536],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@l@@þ²I@lƒ„VL°wnJ°Uĸ™Ŏè„Ilw„V°¤nĮ™¤Ý„lè„L@„ƒ„@x„l™è²ôĊ_ĊġVÈôJżīlbXšÆÈVŽkxÇVƒ„n°„¦Üb@è@nn@@°šUÈ¥WDŽ_Uala¯¯UǙkƒ»„mVwk»˜k²°VxlL@¤œ_@x‚`ȍ‚Ėöb˜š@l²alX„a@bnK°¦VK@nnWmx@nUnl@@lƒlĉk°l°UXkmW@Unš`k„ÇL„ŽW„ÛÈVxšVVlVk@l„IXb@ylXÈW˜Į„WŤzœy@šmIƒŽ²šJ‚š@nŽ°@V„„J°a„Å@ƒŎkVǚk™aUw„KVw™™Vƒ„@nkm™@±ôkô™ĊJš¼šInÑm±nIššÞ‚XȃĊxĊUÈbÜyÈ£Vkw@kVUV™„m@ša„»ÜbÈmƒUXwÝxƒUn¥@°ġ™Å‚aœJVk™aW¯Û@W¥—UŏĶ™@¯kUƒŃ@ašI@mmanwސ‚W@œ™mw°»Uřk¹±W„xVx¯¦U°ƒzţW™w@°ÇVÑk¯@„y°aš£š@šmšnl¼„ašÝÝakwUƒ±aĉImlĵn@ƒm@kkVƒ¯Ñm™ĸ™°x„l™œ@˜ƒXVÞmlÛݙĉUÅ¥mwÅ¥VaUw›™XġċaVůÛŹlwU¯U™ó±™xÛV±¯¯n¯mċƒLmnĊm‚™@™_kJWaXmwUƒĉK™»™@mwX݃UDŽkKÇw™»nƒaUw±škx™K@„Wb„x™„„lVê„lÈIl`@¦ƒŽ@²X¤Wó»™KUșŽ™KkkmVmšUÈóJ@x¯Uk°›„—Iƒƒm„ōƒ¯Vƒxƒk™ŽX¼ƒÒkk±W™wƒnUºVzklVxLǚ@„ƒŽ¯UklVxސV„šJW¦nšmlLówݚ@¤ƒ„bƒ¦„V@VƒV™š±LUxVbU@Vx¯x@²n‚°xn„Wb„b"],"encodeOffsets":[[103073,33295]]}},{"type":"Feature","id":"5134","properties":{"name":"凉山彝族自治州","cp":[101.9641,27.6746],"childNum":17},"geometry":{"type":"Polygon","coordinates":["@@ĶóšKnw°¤ĠIXVƒ¼kź˜Ôk‚„ÈWŽÞȄÜUVšÅš°@šš‚@U¤Vbkb™ĬôLš¼ÈVlm„Llkn@l¤Ub¯L@xÆx„„°mX™mk°b„°°„²™@¥‚™Uwl¥nU@ƒVUkçVnkWċšbĢ@lÈVVk„J„‚V„aV„W@£ƒUƏxW`™£ÈVVÅlWXÛlW°b²la„@°xnÞVÜĠÞ²@l°Þ²ƒèkblŽ@xÈx@Ġènal£nU‚Dz@‚ÞK„nn¤@¼˜°U¼„nV‚šXU‚šbn™ĠUVbUlVš°LX„@lV„èÜUnK@_ƒyXVyUwmIU»Vƒ„kÇ¥šÿkkV¯m±n@ƒn¯ÜanVVƄz@Ž‚bœwÜb„m@wša@kƒmk»@™a@VUUó„w˜@nb°mš„XŽmnVbގVôanwšJ‚ak£lw„˜šLšÅnÝ@wl¥IÇӃ@U™™Lƒ¼kVǃÅó¯kVmmw@ƒn_‚Vn»°LÅ»@éÇçŹīVÇÝ@ÝğU™ƒaVݙ™š¯ķlŭġlƒ@óÞۂċ@¯nkUӄ—m±™IVġUwóKUn±¯—K›w»ƒKݐV„nl@„óxUwţ›£ĉƒUmŗÇ݃K™„ÝUlmKƒ£UVŽ@ÞȎW¦„Ò@Ĭšnny‚@nÒmœVŽ—¼@°Vbl@VlnUUwl™°a@„œ„@llnk°lbnKWĀnŽU„VxUŽ‚²Å‚m¦Û›ÇŚƒaU„Vbš@¦m`móX™Umm™xÅ@±Þn虲™U¯»m™ƒV—m@wƒU@wݚÝmLƒa@„™VÇUk„l°¯„VlkVƒ¦UšmxƒaULUèVx@„kIUxmWV¼¯VmȯšU„nl›È—@m»Å™ƒVWxÅbÅğW@kƒm@kVV¦mlnn@‚ō„l¦Åƙxkœ"],"encodeOffsets":[[102466,28756]]}},{"type":"Feature","id":"5107","properties":{"name":"绵阳市","cp":[104.7327,31.8713],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@„ńlV°š@Őĵ˜VX»ÆUĊќJ‚w„@È»m»š£°Kšk@ÇnÑƍš@„w°JUwnw@wšbVbš@VlźLUw„aƒ»„aUklyUUVakwWXwWƒUxkLƒmn¥mšwk™˜UX™lJ„w@aƒIk°X„¥Wƒ²l¥šaU™„IlmkklƒÈL@m°nlWU™aW—š@Vƒ„@UaV¥@ašk@Çk¹ƒK@a™K@kƒKkšÇX@VU@kx±V™èkIWwUVUkkKÇ@ƒa@wkml¯@kUWn£Wa„aVwnaV݃w¯@UaWx—n›JńUxUšma@L@„mbUŽU±VVnkxUƙ„VŽm@kkKW°„X@¤ÇUkÆÇnU¦¯ŽkƒmLVwÅK@UóbÇƁVƒ¦™L@‚±êX¦mVޚkÜÝnWU—„›@kšƒŽ¯wķšnš°ÒU„lln@@„ĶmnkĊJ²bV„lxÞb™Þƒbk»™m™n™@™¤¯bƒz@Žl°UÒ¯È@ŽšxŤX„yV¯°¥Uwƒw²XlºVŚ¯¼nx›š@ŽXݏmxnb@n™J@b"],"encodeOffsets":[[106448,33694]]}},{"type":"Feature","id":"5117","properties":{"name":"达州市","cp":[107.6111,31.333],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@Uxn°‚bnŽlUnÒƃnn@n‚¤„LnxlU„ššV@„Æl„x°XXxl`XœƒVW‚œL˜è—„±nÈbƒŽ°b@š²x°Kܼ°ĉ„V¦lJnU@¦šÞ‚JÞğ„mšLÞ»šxU„lb„VÆann„alŽ„VƍX@lnŎV„mU™maÅXƒa@aWmœ@‚£@wĉJVƒkk‚kkmƒnk@ƒmna@šal„Kš™‚J@Þwm‚ÅŃ@ambkUƒƒ@™™KUġKU@m‚ak¯±ƒ„a@aĉÑÅaVwšXlwƒ±—V¥l@@a™kƒ›@@£šmƒĉÝónWV@ŽnÝÇÇx—UmbƒaVkkk@m„@m°ƒÝýXm›akÅīƒ@@ƒmb@@xmšnbƒ@mxšŽkWL@ƒ¯b@WUXmWœWKkbm@kx™Xmm@LUl„xlêóK™nUš„all™LƒlLó°m¯JVšU„K„„@x˜K²Āô¦l°"],"encodeOffsets":[[109519,31917]]}},{"type":"Feature","id":"5108","properties":{"name":"广元市","cp":[105.6885,32.2284],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@ÆL„Ċx°»Ŧ¦˜W„™šLȄ@xÞKÜ°ÞnVxÅĀlÒnJ°a@w„V¯l@XWknKnw˜VȚ°XXa˜lX°VI°b„W„nšaššš¥@ƒw°™n@šyÆ@nkÞ@°¯lJn„°IÈl‚UšlXÅ@ķlUV¥VUUÝޙUUƒ@UwƒJUkĉm@ýƒƒlk™WUwVwWJk@VUK™lUkaVƒUƒmLk„m@ƒƒ@Uƒ›Ik`@„™UmlUkV¯ÇXKÝ_mm¯@Uƒ`kwmƒl¼±KV¯—¯Vk±Vk±kzma™KUnDZ™bk¦±ŽX„ƒ¦¯Wl„J@bƒxkIWš—Vlš™xnŽm¦„nlKVwX„WxXŽlxUbVVkzVlƒb„¼ƒbVxŹKUk™@Ua™a@xmxVx¯Iƒx™@ŎmÒ@șl¯L™¤n¼"],"encodeOffsets":[[107146,33452]]}},{"type":"Feature","id":"5118","properties":{"name":"雅安市","cp":[102.6672,29.8938],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@ln@xšèVInxVKn„‚ĊklxkÜVޚÒnÈm°nxš@š¼ĊLV„nx‚WXblIš`š@nmĉn‚KȄôÅlUÑmU„K²¹@ÇÅVÓůVýÞW„‚UVmX„ÆbnwšKUÿ‚™@UmmIUb¯¥Uwƒ™¯™Çmš™„çmanUm»UUƒl—kƒ¤ƒa¯bV™U_WĕmÇŚ±ĢUlƒUl™ÛVƒçkUƒ@WŽ¯KU™VkUağVmš™aV™WUƒmV»—¯@»m£ƒmÝLŽ±@ÈmVk¤mb@ôƒ¦kVkamL@b°‚@b¯¦ÝVƒn@l„ê™b@º„UĸL°J@zV@nmUƒlaĸÔ@xƒ°VҚ„Ub„‚óĢ„ÒWškV@Ò"],"encodeOffsets":[[104727,30797]]}},{"type":"Feature","id":"5115","properties":{"name":"宜宾市","cp":[104.6558,28.548],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@VlÈnl‚XnWLX`m„²nV‚@b°xĢçlnšVm‚nn„@@„°‚UzšlV°nޘÒkxl„w„`UnVb„mšL@albÞKÈۚmܼ°@Xǚ@wmW@ńKĊL„lV„šLVŎçÞL²±‚ğkw@Uƒy@¹lKX™lKVa@w™™Č@‚w@a˜ÇU¯n™@@wġak—™aō‚ƒƒK@Å»VakUWmķwkbğ¥mL™akš™@ġރ°¯xVVÞ@VšxVš—VWx„XlxU‚™@k²WVŃULmèULVĊklĠ„VœJVx±nŃ¯¦mwğ@mƒƒlğkkl±@kšUk@¯±Ç™Kƒ—kxl¤b™Imx"],"encodeOffsets":[[106099,29279]]}},{"type":"Feature","id":"5111","properties":{"name":"乐山市","cp":[103.5791,29.1742],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@kšVŽk„ššÆkšV²UlºÈIlxƒLXèÜlU„„XU‚mkƒbVè„x°@„@¼°Knnn@m˜ÆIUbnJ@bVI°b°±@nK@mVakkƒKl¯nbšmĸ„èl@VnÈl‚UUw„wmwnm°¥„L„™lLnU@Va™ImbkƒmK„ƒƒnk@mƒb™ƒƒLV„JVUUƒ„VnkVmb@a¯JUaÆkk¥„IW¥„Klw—ÑmÝU¯™kVy¯@ƒƒ@mmn™Ukmġè¯w@aU±mnƒW_XKWmkÇmUkóbUÝUanmW™ƒ¯nma—@ƒxVôUV@šb@‚l¼„n@l™b@xƒnÛa›xa@ƒyUÅmUÛbm°@„m‚n²U°ll™ĀȦƒlU„V¼nJVxUz‚W„z@`mL"],"encodeOffsets":[[105480,29993]]}},{"type":"Feature","id":"5113","properties":{"name":"南充市","cp":[106.2048,31.1517],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ȲVmšLnblyl²²UUl˜°U°²L‚»„knlx„_VŽ°@nnÞ`WL°ÈUŽVlnkšV@ƒl_œJV„‚@„„n@lƒnKV£™Çšƒ„UV¯šm„@laX˜U„‚UbVx„@VkôJU°Jn™@™‚wUk°wnUƒV_nJmknmm¯Vwk¯ó¥±ÿ—L@wƒƒƒLVU™kU›bX¯mykI@a±Kk¦ULmaXƒƒVm¯ƒK—z±ƒklUIVbÇJšƒkL¯™l™ƒU™ÿ™UƒlUkJƒUmŽUUkVVklKk@@a™U@„™J„²ƒxƒ¦kĬ@¼±ºXnWb—xƒU@xƒx@lšL@b„Llº@șl@bU¦Vbƒ@U„™@X˜‚bVškX¯m@nÇKk„llknƒJVš"],"encodeOffsets":[[107989,32282]]}},{"type":"Feature","id":"5119","properties":{"name":"巴中市","cp":[107.0618,31.9977],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@V„U„lbkVšŽVLUŽl@XI‚ŽUxVxšXkl„„@þĊnVl„IVx„@VVݚVÞUVU¦kV@ĸWÆô²š@VÞnš@Vaôb²W@‚K@XUmÑUW°¯°Ina@y„_lWn¼lLUbô¼„Kla@™nkUyô—Æx°@šn£™Ý@¥mVkIU¥Ċƒ‚¯Û»¯L±w@™¯a„Ça²m˜ƒ—ç›KX„UW›k_Ww¯WƒwÅk@ƒ™Uƒ™kVmwƒK£@mmmńmÑkVmamnnlmIU`V„m¯xVlx@šmš¯IV‚óIUlƒ@UwVaƒ—VW‚kbƒ@™nU°ƒV™„šÈU¤"],"encodeOffsets":[[108957,32569]]}},{"type":"Feature","id":"5105","properties":{"name":"泸州市","cp":[105.4578,28.493],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@VVXwVKn„˜wnVƒn„l@b¯xmKUbVn°°X°@blLšènV„@Vn‚l@U„LnmmUna„VV_ĶV@wnJ„„l@@kkKVólaUwnJm„wUlm@ašUaôKVnJWbޚ@VšwVLX¥VVš_Þ`šw„WƒÞŹmmnIn¥Wƒ@k„WV¯@ƒ°kI™ŽƒLk¼Ç@k¤±Xk˜™nmݯUlÅÛKWV¯kƒlUwkLƒÓ™@U—@ƒ‚w@ġXV„˜WX„š@UbVbšV›š_kÇV™lU°lnwŎ¦ÞaƯnmm¯šU„™m¥nkVmkƒl_ó¥¯UÇl¯@™ƒ™L™kƒ`¯ķLUy¯@mw—¼ķ°ġ_řU°mlšnÇVUޚ„@‚ƒš_ƒJUnV‚UXšbl˜Ģb@x@mšV°—È‚b@‚xċ@šš@xUbkLWškL@º„zV‚@lxĠ±²"],"encodeOffsets":[[107674,29639]]}},{"type":"Feature","id":"5101","properties":{"name":"成都市","cp":[103.9526,30.7617],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@°n°m²°ÜUšw²ŽôVš°ŽVkxÜźUŰČb‚ŽĢlaÈL„»ƒ@k„wVǂ@„ƒnÛƻșUÝ°Kl_„V°Uš`Vbn@VbÈLšaVU@ƨ»V™nIl™šUUa„±lIk±š@VnKmÅ@WaƒK¦™lVōškK™Ý@maXÇmw¯IU‚@kƒVƒwUmVIƒƒƒç—ÿƒU±ŽÅ@¯È@xƒK@wƒLUbÇKō@mÝ£@yóUóóUxkI@WlIUaƒbƒaŽVĀ™LmxÅaWƒUnVƒÝXUþÆ°UÔÈÆ@±ºƒLnVVÒkóÆ"],"encodeOffsets":[[105492,31534]]}},{"type":"Feature","id":"5120","properties":{"name":"资阳市","cp":[104.9744,30.1575],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@„è„„UJVn„x„U@lV°JnxWÈnbÞ@šŽlLŎ™Ušk‚¥„LXbÆ@nŽmLU‚@zlbXmlnVynL„çšJVb‚UnómUnamU„an¥lKV_²aValWô„n@nƒ‚bVœK°¯VblW@kkƒlUnlV£°W@w„UXk°KVwƒmVkwVyVI@wkmƒVÅ_Umm@Uÿmbk£™xUaVw±V¼V¤kLWxU@Uk™bƒyƒXšómƒ°V@@zÝÒkKƒn™±U@@_VVkƒÇaVwnLWalm@@kkVVl™¦kIV`±n@w„Kƒƒk²™aƒVUUV¤™nkxmUkVWVnLUbVbƒ`kUU„mLU‚mX@`ÅbǚXbWLXŽ›n"],"encodeOffsets":[[106695,31062]]}},{"type":"Feature","id":"5104","properties":{"name":"攀枝花市","cp":[101.6895,26.7133],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@„b‚KÞnޙ@x„V@x˜n„Unš°¼šVš±mç²ÝÆ@šwnnšVWŽnôn_@¥‚™UaVƒ„bƙœÈ܎n¥Æ±VUwVƒmXÿmLkal¯km@k›ƒ@ƒ¯bkšVxmVUkk@Ua@¯˜»Un›mс@mz™m@īƒÑX¥Ç@ݙxU¦ƒšÅŽÇUkx@šlb„UWVX„mV@xĵĖ±@@Ž¯xUšÆLnÆm„šx@nXL±lUUVwKWak@WxkbšÞƒŽĉbUn@‚ƒ@@xó¦„Ŏ"],"encodeOffsets":[[103602,27816]]}},{"type":"Feature","id":"5114","properties":{"name":"眉山市","cp":[103.8098,30.0146],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@„šVx°¦VanJVnš@„b„aVbkJ@XlJVwôôôV@zÞ¤@nƎÈLVa„K@x„L@w°ÇÆ@²„V˜ĀœmWXKWașÆa@_nWVnKVƒlV„_UaVamKXUWwnmmwœÑm£@ynUƒkWƒĉUkWVkkV±çkJmkKƒšƒK¯¦mnnxƒxVxVÇkUmk@ƒçķ™nmak°„LllUb@nmL@‚¯²¯aUJ@amIVaÅJn—m@mm¯L@»ƒŽ¯@ƒwUç„anlVƒWVƒÛkWç„KkwÇJk¹±V™UÅl™™ġV™²ÈƂnXĖV`Uš°a„b„£˜l„kVVn¼mVnbƒè™šÈn°š"],"encodeOffsets":[[105683,30685]]}},{"type":"Feature","id":"5116","properties":{"name":"广安市","cp":[106.6333,30.4376],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@„VlIV‚„kšVšĀ„Vkš°šlK™„ÈIUaVJlk²„˜y„Ln°„UW„nbVKl¥²L@blJnzW°œalV°Inô¯‚K„kšKkkƒbV™šmôLkéƒwVk@KnnšWlwn@laXL›ŽnXVW@X°a@„XKl™nw„@man™@w‚@na@„„@ƒw™ĕġġ™wUkUWb@mk@™¦ƒ¥mUÛb±yÅn@bml@kV@„ƒlknVbmVnlmš—bÇk¯bWyk@V_UamJ@I—@WaƒVXamIVWkUkbVaƒUUxƒ@VnkVU¼›bkKUxmK™„@WšƒxnV@n"],"encodeOffsets":[[108518,31208]]}},{"type":"Feature","id":"5106","properties":{"name":"德阳市","cp":[104.48,31.1133],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@nUW¥²é@šK„¥‚UÈÅôa@VÆLUxnKl„°V¥ÈmlÅÈV@£ƒWX¯lLln@UšƒVÅlwUm²U‚VVna@ƒ@KnbV™VwƃœI˜mXwWƒkIVwÝĕVUa™IƒèmKUzkmWnka@y™@l²kJƒ²Vb™VkšmJUšƧ¼@UV™bÇKUam@Ua™_¯VƒUk`¯LVÞǚżm܃„@Uȃx@l„ƒ¼ÇKkbWŽœšVxUbƦnxƦĊV"],"encodeOffsets":[[106594,32457]]}},{"type":"Feature","id":"5110","properties":{"name":"内江市","cp":[104.8535,29.6136],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@²èlUUllXĊVX„„lmV@zn¤›ÒnxmnXxlUnVlwšmU£VV„Ušbl±„„ƒL@x²mU_lJš¥UklU@ln@‚kXbmKUxÈbl„UU@`V@š²„mlLÞÑ@yU@„¯ôn‚™„W„zšaVlV@XwlKU£‚»—aVaUwm@mwUVUwkƒlVDzLlƒ„KV™m_@ykUmƒ@mU™çkKmxkIU‚Ý„@LUJ@n±„kº‚LXb™¼@mmIXa™@mamnkW™ƒKUƒƒxƒ_U`UklwUw™mUbƒV™²ƒakbƒmkn@`„UmҙšVxUb™I™`UƒaÝÈ"],"encodeOffsets":[[106774,30342]]}},{"type":"Feature","id":"5109","properties":{"name":"遂宁市","cp":[105.5347,30.6683],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@ÞĖUxlJX„Vb°@„xUÞmbUxƒbXbm¤VX@lk°ln@x„bÈ@lLVlVUXxlJšç²UlwV@@UÈWl™„L„w@w„V˜wXaWm²¹@»lī„¥„wƒ±šI@ƒšV@bl@kLUllUVVn@mmU„wX™ċbVb@VUkbmamšW@kƒa@™™k@ƒlaUa™@¯b@šmmwó@@lkXUa¯°›LU‚am„m@óƒkXUb±bU`kLm¦ƒbnVmbnVmô"],"encodeOffsets":[[107595,31270]]}},{"type":"Feature","id":"5103","properties":{"name":"自贡市","cp":[104.6667,29.2786],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@lIÞDŽbVŽš_šJVaUwš™nуV@_lm„nla„bš±„UVašnVxkxVlV_„`„wV„„LšlXnmnbš@WbnJ@nš»WaKl¹²ƒ@mVI@KރVlJnw@aW¯¯¯UmVanL°w@aƒk„mmU—xmƒULWxUUÝKōèU™KUƒƒkĉKƒL@ÆnX@x™‚Wȯ@Û»™nÇÜÝLka@b™KƒnUaVmƒ_ƒxkƒLX¦ƒJl¦ÅlVb°I@bnaUŽmlƒUV„UVƒIUŽ„Kš„„a@nml„„ƒŽnLl„našJUbV@"],"encodeOffsets":[[106752,30347]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/tai_wan_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"7100","properties":{"name":"台湾","cp":[121.0295,23.6082],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@\\sŽ@pS}aekgKSu™SsMß`¡CqZ·be@Q^o@‹gieMp‹‰]}•}Ľc_Kk…{™ù“A¡r‰[uom@эĥJiq©mʼnq¯Bq]ÙYgSåk_gwU­isTE…“‘ĕiqiUEkue_‰OSsZ‹aWKo¡­q“ycY£w}‹ĩ™ĕS§Z©S™N¥SyLÑ¡±Ks^IY‰PdƒY[Uo†Fp}´\\¬\\j]ˆe܍ò‹¤¡–ā a\\bn™U㺹Ìs¼j®[cíȈEŽĝĆ`ļf¶Š®K|VØDdKGpVnU‚FjpH—F`†B’[pMºxÖjbpÎxp€¬‚|ΟÜÒCŠ²®‚ÜAp„ZG~€Šd˜ÞàV¨|¸€`|Œ²tx~\\~|dFf^zG€ĄŚhœdL\\hĸž¼†ŠOªP®lV`p\\]Xpll˜æ¤œCpQ|oF}fMRi†NSon_²qämœM„NM‹\\•"],"encodeOffsets":[[124853,25650]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/tian_jin_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"120225","properties":{"name":"蓟县","cp":[117.4672,40.004],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@EUDAEI@WNMNCBFAHFFNACDJDPBD@@GD@DIFFHEFGDBDEQOFG@EI_KG@OcJQM]RMEKBGPG@[LaCIICBWKCEEG@WBQHCDFD@HSLEJI@IHWECFGAAEKCGDBFCBSBIDCKKHEADMJMFABKOKEQAA@IEEG@GIQAEK@OZEESMOL“lu@SLUTYFQCMG@@SQUAYKAACA@IB@BDB@B@DC@@BGAEFAA@BEGKJCC@AGAIHA@@JC@QEIP@@A@EGIDC@O@C@@@@CJCWKABFLBBEBSQGBAAMIEM@AKBcJEN@BEBCFMAEFEF@J@BG@BFABECKFG@AFQ@@F@BEB@@A@@AAAKAE@GFGDECEFEECBKIKDELDFEDYH@EIACDCHKBEB@BAAC@ADBHABKJIAIJICEDGDCD@@A@A@DHCHJHDFEFGBKRKBGIK@GIMHSBCH_BOJECCJCFKKMD@DNJEDEGC@OJCJHRUL@HRJ@H[DCNKDZHCTFDHCFFKR`TANVDFZRDLFARB@HPAPG`ILAR@TERNDFNHDLCLDDCXDYbHF@FEB@LDDVE@JPNfXPINCVDJJD@NJPAJHLXHDNANHhB@DPNLRMTBFRBHHr@`NBFEBOCCBIAQJDHCHLHFA@HSDCRLFTB@HEFLNF@PELBDJALFLTC@EPFLLP@tUHQJDfIHGTB^JTCPDLKAIBATFPADIEGECEMJ@JIAIHGECFEAGDI\\SPOXAFCL@BQTQBBTMZECYGAHA@GJAE@HCAEME@IECFKJADDBABLTHHG@ILEAMNDJCDHEBF@@JNFJELDFKTOT@JETBFFHBHEHKI@@IJEJ@XKEOUMS@AF@CEB"],"encodeOffsets":[[120575,41009]]}},{"type":"Feature","id":"120114","properties":{"name":"武清区","cp":[117.0621,39.4121],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@FWôµ@IFCLIB@EHNBp]AGEAKAEDMGZKFGBGME@ILGP@HEFB@BXMEAHUGC@IHCLOD@X[NWHWPKAEF[@EKIOL@EKGBNMJ@EIEHKBIC@BAKMIACCFQZCF]DB@ERAKADIHGEIBCGIIECFaGLZO@EFCNGAGDGAKL@BMG@IE@ADSDEH[JGC@CGA@BMDeK@EIACFE@@GG@FIAMM@CCGC@EM@ADE@CFMAAGHBDKIEAJG@DOGCDEKAGIS@KFCHKAEHIE]BeKNO[IFIOELC@A]GMBKVYCDDgGAICARc@MW@AQE@DGI@@AQ@@BKBAIQQYEFW@CEADIGGBCEIiMEMF_LGEKMBBDWEBGRC@E_CHYGCH_IAED@FFBQh@FGJaJ}AHRAREF@bE\\C@CT`FHC@\\BBF@BID@HGDDJ@@FAHKBARECKDAZBJIVNHCTA@EREAMLHDAFFBVFFC@RNRETHD@FOJMACH@CAB@P@DF@@FGDWE@FFSIEMKQDYCCHKb^JADOCIDGNDBdBCFJB@EC\\A@BJEA@JAAAD@HHD@LFBCFF@BERDHNhZQHMBGHOACCEBWEGD@PSJKCGEUD@CINLFGHE@AJK@HDABBHTB@F`DBFLBBHEDARCFG@ABJBAPVFE^FBGLGCFG_BMLEXGAAFE@@JNRVJHFALFBEHQJCTbNDHCF@PlFLJSXCHFHfVBTNJ\\BPJXC^FAVNFCHFB@FFH@JF@\\ABCFD\\BDMCAAJKQBGAILOEGHILECQLWFENJHADC@QxNHFJNLDFA@CBA@D˜UÂmR@FBL@BD"],"encodeOffsets":[[119959,40574]]}},{"type":"Feature","id":"120115","properties":{"name":"宝坻区","cp":[117.4274,39.5913],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@TZbB@JHD@DODCLM@AP@LL@BNH@ETFN@`E@DNG@CHLBCJA@AICFKDDBKA@\\N@AFNAGRBFjFFFL@DHLBLFQPcXAZMJ]GAVHAIZJFNE@JpDRRDCLFDGXA@EFF@CFFPDfEBDB@DCHCFCJDJIJBLI@I@CB@@ADBB@FALADGDC@@H@BB@FZGFCCE@@FMLALJDAFFFEFDFCB@@AHCF@L@@BBB@BB@FC@E@@R@BEL@HEFD@G@AH@AIB@@@FEFEBALDDEFAFO^IF@JCBBFPNJJ@D@PRDCEKBAXL@BIFD@T@JE@BHHJORFDI@@B@JGH@@B@BDDLIFFHCD@D@DEE@BAAAB@DAF@B@H@NGLJLMRDNMfGIEPMI@GDAKK@KIDIJ@GE@CFDN@FE@GFEPGV@TCDFKHBBF@RW@DD@@ID@TJFKIKLI@EP@IGBCLAEKLEN@KSHIGYACSD@SEAMBBMGEBMQBCMIGKFB[D@HDLPHDBC@IFITDLG@IIIFGVBNJDLN@VIRI@YIAIHIC@CLKZCBEE@JECEIHEAKGDGECBGEEM@@DA@CCCBBEGA[GEDBBoNAAH]MKiIAWKQoIIPMFQAEEDMH@FMSUYIeF@EK@BIOEKJEBICFKaKPFAFSE@LWCCFMHDDEKESBOGBKIEIODLG@CCDEQCEDWEMDIEIB@EHGEEDAEAa@@HqDEJGF[AECCFa@WCEIKAAEQB@FCAE^YDERDDJBLNABD@AJGLJF@FNIAMLH@FPKLJ@FE\\BFOLGXMXW\\C@KPGD@JHDGVFBWN@AEAGFO@KH@JNFAHEHYLNHFCLBFBBHo^MAFGA@KJED@Jó¶EX"],"encodeOffsets":[[119959,40574]]}},{"type":"Feature","id":"120223","properties":{"name":"静海县","cp":[116.9824,38.8312],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@NGFMDATCNDR@CCbINEHNJA@C\\EEGVE@IhE–[˜w”epc¢·²›^QEKIEKIgiQDkehY£uSDBMkUDOJDHC@GF@CAFBFEN@C‹Q@BeP@@G@HD@@MHQKi@[IGCOCESE@GMA_OcCGDu`aˆ@VZzKDkJBLNXGDqKEWE@cFEFA@ƒISIi@@KMABJGBcMuFEzGVH\\ATSEUBeALCEMG@CEBUHUCGXaBPtUBBFIBFTDFF@DDKBFNGBJPHXDDMDCLJ^mBIHIL@LR\\@LCR[@@z@NFD@LLBNb@RHDBNTPT\\F@BJF@BXCFBHHBDLFB@HODADE@@JHVXCPDHCFTLBBFNCDCCCU@@GAABEHHZHBCAEdEjFDD@GfD@DXFCHF@ERFDLBH@"],"encodeOffsets":[[119688,40010]]}},{"type":"Feature","id":"120221","properties":{"name":"宁河县","cp":[117.6801,39.3853],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@BFLBFJXDb@DEFD\\BHEFIrC@Gb@FBCBFFGH@FJAJFNCXFFCRDCFDDH@CKJPJFALPHTALFCFGCENDDKXF@ETEBO‚bLELJDFALIPFAJL@@FfEZJTVENG@CNFFRBNEJOpJLRBXjJNLG^BBpMAAFC\\HHBAFDADDB@@CN@FFAHFDCHLHFBJGFCFUNKJJTD\\XUXF\\^F@DDDQXXBRLRCBDFEVCDLVDpUl@LEDJHAPRFGL@CETGPBTCDDVI@CFF@GFDCCVGLKEK[Y@MECISG@BKNSCGCKWEAaEBEKNGFSECO@GGM@GYI@DÅCMLHPTF@DJHAVVNKEGDETJ^[TJNNd@NOAMFYJ@@GFANDPEJB^aOadSTQSI@MHBDIEOKCG@EEFCKCqXO@@DMFENCDDHCCGJ]AKFoDaGGHYFDHKJiCMFGC@EQ@AEHGAC@IEAATKOHGIC@IXIFEoƒGE[JCFCDHNmRADFZMF[EEBMO{GU@AOW@@]ZeHBDEHBKEfQkuIWBs‡@EC@d[@[^EDMTKCEEcI@cDAB@FCBCACmOCG{PYHeBgPwPFDDALFFFCHQGSD@BHFAR[TaFYXMASUiGFL@DQNCJI@@D@PLDN`ETEFIGMCGBCE‘~CAIFDPEHGEQPHJADFJGHCJLB"],"encodeOffsets":[[120145,40295]]}},{"type":"Feature","id":"120109","properties":{"name":"大港区","cp":[117.3875,38.757],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@JFFL°_`ONJKDDFIFZN xlb~yFVNRŒrdJGzDPVFBCTNND\\UR@E`F@@Ip@IWGUoawOEE@ÏDgK{İEEMFëC—b…™@—KwOCDHHKBDJCDEEEAGHOABFABMCgDLSQ@CFEB‰MgYIDQINE@AUSwSAdYEHQMEyK[KI@GRMLE@@OqOoBOnpJ@BmEAFHL^FDB[C@BBDVFAHFJENB@sNEjQAMYsUgCSBGDJH@\\LjGR@NC@@G@HO@AfR@DŒM@EFEADBE@@HGDICCPlVANTC¤vgZlfRChjLJ"],"encodeOffsets":[[120065,39771]]}},{"type":"Feature","id":"120107","properties":{"name":"塘沽区","cp":[117.6801,38.9987],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@|ODHnPBDADEDA@CB@ddJFFLDNSFC\\]\\@@cFDˆ@nACOMW@M@ITURBRZNHNWRQšoO•j½f‡cqŸAqeiDÿÍyÓįFL|Ch@ÐFFxPpbHVJXo@@JCTR^BPABQA]^MB@bE@@FQBFVJRH@FXtPNZSBAja@@NƒDTŽLJrQTHFXZFB`"],"encodeOffsets":[[120391,40118]]}},{"type":"Feature","id":"120111","properties":{"name":"西青区","cp":[117.1829,39.0022],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@@LHAHRHATh`LHNHDG`HDGZ`D@FQDAHXFACNAFLVRTBFOfHDCVBFQH@HSXHEPFB@LDBF[bDbLFKJBFLADBDjLvCPEI]FGEIGCBEUSjcFiBIVWfaHCjN^HtwBBFGPBJGjFBEGECGDONMFAP]TDHQOWCMGAMHKIJEIGQ]aDlUG]VGEGDC„{PEbBZmE@@GH@BCA@FMQCFMYMJECELCMI_P¯`]R±œ¡¸od“f—x•\\gF@JUFFH[F@DIBGMMFaJDDQ@MCSDCBENMH"],"encodeOffsets":[[119688,40010]]}},{"type":"Feature","id":"120113","properties":{"name":"北辰区","cp":[117.1761,39.2548],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ROHFFGCOJEDB’}DFHANDJHFEFSM_KC@O@CJ@DIRM@CEKKA…L…FKACHoLSJSIBETDJaEIIE]E]K[MYUYQILC@GF[MGNKEK@A@BCWECAIFEFYAGFOMI[OFuDiKACBCEKIAELaKaCE\\CA@KEAFOWGGTG@ERUACDeGEPSAUQKHE`FNjNFJADHHCJFB@DEXZFRRBJLA@AR@@BJ@CHF@BRX@@NQdDBBJhHCCZDLUNA^H@BKDPFEJ\\JMPfL^AJFFGLBDGLET@HJLBCFHDCPH@BIJFCLGABHNBDEF@BCN@@FHDDDN@BNEJH@@HF@DEJB@FfLNC@AHB@DHD\\IFGTCBCF@@JNH@ALKHBHCHBDMFEP@KYbHDEJF"],"encodeOffsets":[[120139,40273]]}},{"type":"Feature","id":"120110","properties":{"name":"东丽区","cp":[117.4013,39.1223],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ZV\\N^L^FJFFJIbSCAFTJTIpKDGLB†E†KLBjHTVNBZWbE\\SBQGE@ATCRHDGEEKECBECxOhOfAZGA_YEEWSGqRKIS„C@Mb@BiTAMYsOEWG@IQEURA@EF@@acUOXQRYCUDCHDTEF[SUEgAYDcVGJM`iAWDWLQRMHUHgDsDBLHJFCFDFGHBFFVEAGHCJN@RJF‡PIhBD\\FENCPWA@LFBAFHBEJUEARCDIAEDQBRNa^"],"encodeOffsets":[[120048,40134]]}},{"type":"Feature","id":"120108","properties":{"name":"汉沽区","cp":[117.8888,39.2191],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@LMEI\\MTABKN@FCDMH@COAcH[AoēA™M¡Wa[Meq™pQRMXMGQYQASV@J@NNXDPmBAtJXlveRLFGACFGAYf@^X@BPV@|HNPFA\\FNEEYBCnQGMDCDE\\IHFp„EFWJ@JJDGHLPBSFB@JBDGHBFR@@FHDNEjDLICGZEHGbHpCLE^BHIDDCGDCFMNE@CP@rWLDEDFFH@"],"encodeOffsets":[[120859,40235]]}},{"type":"Feature","id":"120112","properties":{"name":"津南区","cp":[117.3958,38.9603],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@TLv@CNHFFBHGZFETNPhCVGNGRQXKXCjBN_HIdUZChBVF\\TFECSDGVCZDRQPWdVNA^]RBBAAOQ]DSE@F_Q@[VMCSMADUECOHycI‹qMQEU}zkaŸwENRDENB@ADG@@HF@YnaAOFƒ|CDFHUHH^kVbCR^JHIFLJNGHBDNPXGRSCO^EBMNCPDHHFAFiEIHOAEH"],"encodeOffsets":[[120045,39982]]}},{"type":"Feature","id":"120103","properties":{"name":"河西区","cp":[117.2365,39.0804],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@d@hZNFdcLYXKRCtCMOFSYEGHEAGEDMu@SKAAsx]GMTGt"],"encodeOffsets":[[119992,40041]]}},{"type":"Feature","id":"120102","properties":{"name":"河东区","cp":[117.2571,39.1209],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ZBVFFIGABEEA@KXBDOFM[EACJgˆOIE@QIMGDBHUFEEGAEHECEDGIAKQDWLKZcdQPEP@FOFBJTJ@HNORJf@DBCN"],"encodeOffsets":[[120063,40098]]}},{"type":"Feature","id":"120104","properties":{"name":"南开区","cp":[117.1527,39.1065],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@NMVDCG\\E^B@HlB@YEDS@C…HsNSiMGDebUXAJEjidVTAFHDFJ"],"encodeOffsets":[[119940,40093]]}},{"type":"Feature","id":"120105","properties":{"name":"河北区","cp":[117.2145,39.1615],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@DBXFADB@L@LFHM\\NHED@JKZRb]QMRAFCJBDCBQYADMCAe@QIMP@GSIAIPE@E[EGH@ZEF]^HJAXK@KF"],"encodeOffsets":[[119980,40125]]}},{"type":"Feature","id":"120106","properties":{"name":"红桥区","cp":[117.1596,39.1663],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@J\\PNHEZBFEJELEL@BWGI^]FEkA@G]A[FDHUCMNEHJ^"],"encodeOffsets":[[119942,40112]]}},{"type":"Feature","id":"120101","properties":{"name":"和平区","cp":[117.2008,39.1189],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@D†T@FCHG\\FFOROMEgYc@"],"encodeOffsets":[[119992,40041]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/world_geo',[],function() { return {"type":"FeatureCollection","offset":{"x":170,"y":90},"features":[{"type":"Feature","id":"AFG","properties":{"name":"Afghanistan"},"geometry":{"type":"Polygon","coordinates":["@@ࡪ͇وŐǬϠڐŶӂʮǚڦ۾njƀ̚ІɣʪҴMوǯʲĹ،˒˰Nj˖ϪԈiżŬĘͺβ̈Ҕȏĝʱʪ¡ý۷ͪ˟̊ǰώĊԼϖׂ×ࢀAƬʋӧĥяƹ७ĭࣗǭӫλȤΣĪллΛ–͑ɳ̡ߛ€ͦ։՗ɅΥԕ²ԋ͡ɿ̳þٝŋğɻسDҵӇ‡܍થΓבôǝȁԇņ࠿űටіހހåզُƚßՔ˟ڢάҢιŮɲؒ΂ਸ"],"encodeOffsets":[[62680,36506]]}},{"type":"Feature","id":"AGO","properties":{"name":"Angola"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ȸصʌԋȘ˕͐ѯ֊æˤŠҬşŲɀɂӨԶ®ƤіHñ̡৴RfՉǞ͕ūԑÖԫ˪̷­ৃȼüκsԴŴϦ¹ĘʹĩСƨϿů̿î́ყZᦵ֤ۋպԽ໳΁᎝Š׋Ж₭—ŵÏԃϞկ~ԉƝЙDžÿՈŜ݊̂ޒªΰ˚ݶȨΆӘռːϐĘج«ӊʣ̜ɡԚȵԎ®Ǩʶͬʭ߼ǣ֚сՐĄǎΌŔʒg̎ĸៜ["],["@@ɉėɣلͼδʪƘ̀˽̩ǯƍɍλ"]],"encodeOffsets":[[[16719,-6018]],[[12736,-5820]]]}},{"type":"Feature","id":"ALB","properties":{"name":"Albania"},"geometry":{"type":"Polygon","coordinates":["@@Ń˷ŢέΒȳiə˗ŧ»˙ϷСƛÐgȂү˰ñАîֶŖʼƗƂÉˌθаÂƿɨôǴɥȪďȨ̂"],"encodeOffsets":[[21085,42860]]}},{"type":"Feature","id":"ARE","properties":{"name":"United Arab Emirates"},"geometry":{"type":"Polygon","coordinates":["@@Ƭ¤ŒɱڂƂ۞uԖ{ֺ֪ظՠՎԮdž˹ŖڑѕGçճƪŝϝǑE΅ʓΏuͷǝDZᡋъ͏࡚Ț"],"encodeOffsets":[[52818,24828]]}},{"type":"Feature","id":"ARG","properties":{"name":"Argentina"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ߗ§ѓ̔ԑx࣑@Aሞ͒ϵрؿનԋ୲ȿϙп"],["@@Ӵ؇͠ڰॠ“ƊǷ໶ോۊŷਆاࡾ͡Ŧχࠡ౧ࡒɭ़ŷڔƈނ٢ƎݐжLjфӝiڣۻҩ֟΁ॅࠃ૭ଧȽڥɣࡹT࠷ǽȇÝիËѫ੨ܙŗ׃Հν§Ч߯ઁఛ҉။ǩउĎǰԅǣػƺщԋ̏ࡱř̪͕߱ɗŜ࠳֨ʧҠˆʢѧޛʻڭԹūࡋȣ҇ߏEڃљʋؿؙࠞߦǝ˿ݭ঳Ӄձটލͧ΅Ͽ˔ࢍ֔ӡΟ¨ީƀ᎓ŒΑӪhؾ֓Ą̃̏óࢺ٤φˈՒĭьѾܔ̬૘ěӲξDŽę̈́ϵǚˢΜϛ͈ȝॺ͸Ǣƙ਀ȠࡲɤݢԊ̨ʭࠐEޚَոo۰ӒࠎDޜɓƶϭฐԬࡺÿࠀ̜ބռ߂צԺʥ͢Ǭ˔ඔࣶд̀ࢎĹɂ۬ݺશȱ"]],"encodeOffsets":[[[-67072,-56524]],[[-66524,-22605]]]}},{"type":"Feature","id":"ARM","properties":{"name":"Armenia"},"geometry":{"type":"Polygon","coordinates":["@@୞ƀǨə͌ƣǛɁ҄˽ʁˋΦɫϘƏl׋̣}΃ӢHżχCʝɤǩuͧʖرȼĄФƛ̒"],"encodeOffsets":[[44629,42079]]}},{"type":"Feature","id":"ATF","properties":{"name":"French Southern and Antarctic Lands"},"geometry":{"type":"Polygon","coordinates":["@@ը˃ߐĿˆDžɽϣಇÃq҂ŮΎÊǢ"],"encodeOffsets":[[70590,-49792]]}},{"type":"Feature","id":"AUS","properties":{"name":"Australia"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ߺ́ҜŘپNJԎÉÐঽ˽́ēگ̉ɰ׍בǧ®ԫ€ԭܘŗֈӝܸtϬռõ"],["@@̢ڇբ̈́˦ΡЖ͟đϋǴܛŸнɄĹɬܕąѥ˖֭࣬ѭצЋ֞λŋȯӔՃࣧ͜ͲȂ;ηȴźƢࢹ׬ԩϸ͋ڀڹʀڭtӏËԳА܋µݓơϵɩݡjӕǕ׻χއثЭ̫ٱ˫гʝܧ͕нɅػʼnׁªˇӕ̇व‰ޡ·ϫ͙ԕέ۟ψԥƪżѬҝǃ݁؉ܩɪӉƄӑÔ߿ʐիԮƻْțьЭ;߱ĸˢРȯزЧ׉ݝƷѮҬŶӞ͘ЬãجہܑԿ˽͏ڛٽΊ~ҀԿ،ѹ̀ǂȘઃԚןz߯Цຓāછ̝ख़˫ߡÈࢻљܯȗljѱ̳Ϳ܉qՅõݑƶ׿ğֽԁ҃ʕœуʁЗˋؕ֛Bࢽ՜ҋDŽlӖкŘƚȒ‡̠ĺאģӼѻࡖƏӒ˜ӎͭնsʚϋͰĽڄӓڔřΪτε˳ެиʑʞ͗aјеڎă˄țʦĠӠǢȸŘрęӮΎ؀Úٕ΢׀ۀˬЦΪٜ̰ϤàɴĻڎ̺ԚĤŶȀɞüҬoࢨʖҚώɊ҆ӲѐœͲvҘט܎ΠܩΦǚ̗Ј˂ТψǻĸٖҠаȮͨцƜ`ɼτĭdɂτŦОŔبϫҲӽՂMՖÿDZҦДڪϜɘſȾκӒԘ̒јıۺǂeі؛ˢ҂Ū֎ȻҀ·ۼɋʈĐԶʵӬʊ͂ñȠNJϬеɡ͉҇ͻ˿ƒĮͱʙп̗ЭÔʁڜҫ٨ˏѠ́؈ӻʂBѰɍŶʷߤ˵ֈ˼ǐҊǠόľҤʰڞŝОÔʔīӔŌنLjǠŽˬȮѾdžҦtʈ̸̾ʂЩÎՃȾķ˜Λ̨ёÚӇ‡̥"]],"encodeOffsets":[[[148888,-41771]],[[147008,-14093]]]}},{"type":"Feature","id":"AUT","properties":{"name":"Austria"},"geometry":{"type":"Polygon","coordinates":["@@Û΃ӁCǎǻ˧էLJƗܽsщȏۛÞயɐȉ̊ࠧƣĭDžԗŢѕxϝƶźȴƬʪ²ьɹŤɜݎ•׸ƮЖ}ˀǣþƜšո̠ń̒ϰز˓ӀΆ̐ÚٶʱЂªϰǁãŃČ̅"],"encodeOffsets":[[17388,49279]]}},{"type":"Feature","id":"AZE","properties":{"name":"Azerbaijan"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ʞɣψDGŻ΄ӡֽŒщϰƃ͆Ǫv"],["@@ϊËƞɈԈͺѴѵђ׭ϺŸʸɧۗãƣٵƟ̭̍ȝvзȽ¥ԻѲ̂дʝʚ̿×যإk׌ϗƐΥɬʂˌ҃˾ǜɂ͋ƤǧɚȶƎضʍҐ¹ŘIJбҔɔŚʀ…׀ԙ"]],"encodeOffsets":[[[46083,40694]],[[48511,42210]]]}},{"type":"Feature","id":"BDI","properties":{"name":"Burundi"},"geometry":{"type":"Polygon","coordinates":["@@Á০ɃϢԜßʲӎҀŸͧǸȏT˗ȹǭ͛ѫ̧̥΍Ÿ"],"encodeOffsets":[[30045,-4607]]}},{"type":"Feature","id":"BEL","properties":{"name":"Belgium"},"geometry":{"type":"Polygon","coordinates":["@@؜áުǪՐοҦȝħ֧ɕĝһܿϦћßדІϷͶϷ`ũ̒ڪǔ"],"encodeOffsets":[[3395,52579]]}},{"type":"Feature","id":"BEN","properties":{"name":"Benin"},"geometry":{"type":"Polygon","coordinates":["@@ۛįȹ׆žኞǛǦЮ̇̌ʱʞņѶ̀ĨǠξЪĀȀʤˮʘ̠F٘ә˩ȎӽǓͷĘɧСԳʵʳǁՉt՗µണ"],"encodeOffsets":[[2757,6410]]}},{"type":"Feature","id":"BFA","properties":{"name":"Burkina Faso"},"geometry":{"type":"Polygon","coordinates":["@@ֹɐϽ‹̍Ƀϗǰƥ˦ϙǾÅӦɮΤo˴ښۢŬּɲȴОœΚǢŘɎٴϖdžˀ޼ΒҦŢɀLJՠJáСŔϣӀչ€НॺȏmֻǿʣЩÿǟν˿ħ݁lϳâ˓ƉωÖร¡qӉŘم"],"encodeOffsets":[[-2895,9874]]}},{"type":"Feature","id":"BGD","properties":{"name":"Bangladesh"},"geometry":{"type":"Polygon","coordinates":["@@i׽̉ŶÆگʉѬµєDžКΕӨޟ’ü΋˃ҳΧǠũƵʃĠ͗øŽۖ̅لƜԒԫɤȆ̪Հ̼؅Ѽ֮̔ږεВ£ô׏ߞřު^Ӟƛϯ܅ϕµʷӍҢѥƎ՞ɶFѶ೯"],"encodeOffsets":[[94897,22571]]}},{"type":"Feature","id":"BGR","properties":{"name":"Bulgaria"},"geometry":{"type":"Polygon","coordinates":["@@ʎΉ͚Ö٦ſ௾«иɌবȜ̩ؒӴĕѥΏ̫׹˔ӏܣŒࡥ˃Uлޅÿס̊ڧɱة|Ñ֊сːƒŢĝĴƘˌ͌ˀСδ÷̬ȸȐ"],"encodeOffsets":[[23201,45297]]}},{"type":"Feature","id":"BHS","properties":{"name":"The Bahamas"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ȵ£ɇӜ̿ʐǾՔʨ‘ۣ̎Jӥ"],["@@ࣷƅÏ̴Ђäֈ{~ɕ"],["@@ƟׯƷņ`ѮϓͪCĪڐϗ"]],"encodeOffsets":[[[-79395,24330]],[[-79687,27218]],[[-78848,27229]]]}},{"type":"Feature","id":"BIH","properties":{"name":"Bosnia and Herzegovina"},"geometry":{"type":"Polygon","coordinates":["@@̦FȿσМ͓ūЃȡ™ƽû˙țūҥݓ͈ͅΘ͋Ȅϭ̾ǻʺЩϾǬΒ̞ȕǼǨϾnܠƓ׈\\Ϟȅ"],"encodeOffsets":[[19462,45937]]}},{"type":"Feature","id":"BLR","properties":{"name":"Belarus"},"geometry":{"type":"Polygon","coordinates":["@@߼Mࣰ̈́ȚӄېːÿϔԜƚ͖ࣘࢮɁŢȻѲĴࠒȧĊЁǷɧՄս΂Ƴ»Ʊ֦Ʃʎɡ͝ǿڳˆljÿȠ˧ȸ՝ܝ¹ʵȁÃхͭĆݷ¡əȞ̿ƥ́ŨڍjफȬࡕàٱmҡɩГeϐʷϴԌǢLͰɷ͌™ϊ"],"encodeOffsets":[[24048,55207]]}},{"type":"Feature","id":"BLZ","properties":{"name":"Belize"},"geometry":{"type":"Polygon","coordinates":["@@OŮĸžƴı̞ԔDŽZHūDŽGaɭƋεôŻĕ̝ÀăīщǓɟƱǓ̅ʣ@àॆPژ"],"encodeOffsets":[[-91282,18236]]}},{"type":"Feature","id":"BMU","properties":{"name":"Bermuda"},"geometry":{"type":"Polygon","coordinates":["@@OEMA]NOGNG\\Q^McMOI_OK@CQSGa@WNLVWHFLJXVFGJ`ZRTDLeeWKIHGIK@@[MQNi`]VDTBHCJAPBJLVFjT^LV\\RJZRn^RH`TfJjZHHOTTFJP_NOX[EYQQKMEJOLANJH@HQHAARF@ZEPS[U_IcRQXE@EEKKOCGGCQCOGISKYGUC"],"encodeOffsets":[[-66334,33083]]}},{"type":"Feature","id":"BOL","properties":{"name":"Bolivia"},"geometry":{"type":"Polygon","coordinates":["@@य़”͟گӳ؈વȲ۫ݹ؅ŗ͡୆ҋऺˆ߾ѳ΢ŏ؆ЫֲՌ࣢αۺȖ˰ƭ̶͠рh܎¤נǸ˶ܩഠزíѠnȈʪ݀;Ѷ͂સƚęؽļ͓ãࣰ֛ݫऴƑ̻ͦ֨ǕΐʑՈTӦʟšӟǐʕZγʓa͒এྖ“ūӟĜͧҞɽȤԹƫڋɯρĄӏʿǥaʶ޳јޭ^ัʓЕ݋sҋͥ৕ƉǸ"],"encodeOffsets":[[-64354,-22563]]}},{"type":"Feature","id":"BRA","properties":{"name":"Brazil"},"geometry":{"type":"Polygon","coordinates":["@@૮ନॆࠄ֠΂ۼҪjڤуӞеLJǒӜŖӼBҦ̡ƴ̿Ƌ̻œį͔ýޔƿʤ֥ɪ΃ǏࢱLjÈଜʝҴˀǦăӐɰςƬڌȣԺҝɾěͨŬӠྕ”͑ঐʔbYδǏʖ™ӠӥʠՇSΏʒ֧ǖ̼ͥळƒ࣯ݬä֜Ļ͔Ěؾષƙѵ́ܿͽȇʩџmرîӃƟϡĪÈ౨ۏӷݏv҄ͅ֏¶DzΰұԞΓݴɜƶA΢ԖʎċҔɊ̈Ôϼ०ֲێNJŔŴݴŸϚᘰpθſӔύ̬LؐӀƒǚē†͐ӯĔYՀ࿖k˦̂ɸˉǐӷǂļҨѻٸÆnjʲشȞΊƐĮΤ׸ʆ¯Ǯ܅ðśՊ’֞ϓɒǀþجŅڜȿʐȤ؀žल̮͎̾ŏʂѪšȜȗʼnσ̀ŵȖϷɷ̏ƅ܏ɌыÔϳԬϿЮ¥Ģǒˆ˜ϠƦ˚ɢҬíȲŠҚçøǢƗǘĎʐͺõЈĒӔDZξǥʺɪȊ•ŘɿДÒ͒͊ʴؤӼޒ˺¢ȺҫҼ฽҈Ƒxׅمەʾʩ๤ƁŠࡃٔր੐̟ඊԡШӱƏҫ঎ʶ࿐ѹఴŽఔ۝੸व٪ʏܖ‘̦˅˸੭Ɣԗͯ൹ёշஅୡՙोثܯȿgɻءÒ༽ɹಓęօˇͧƫ૱࡛઱ƛࢁڹηȟԋ࣯Fೕ͓סύवʗ঩ڝ܅࠯ũطƔҫƽࡓȏЧחҥट๕݉ڗ֯Ͻϥߛ։ӑɷӈψЊӟֲڇҬࡹՠ̹{ࡅٰձę"],"encodeOffsets":[[-59008,-30941]]}},{"type":"Feature","id":"BRN","properties":{"name":"Brunei"},"geometry":{"type":"Polygon","coordinates":["@@ͬ̾܎Ң›Я·՛Б€ǭ˹ϥѦ"],"encodeOffsets":[[116945,4635]]}},{"type":"Feature","id":"BTN","properties":{"name":"Bhutan"},"geometry":{"type":"Polygon","coordinates":["@@΂ˍÏԩۇ{ۿÈՇſޅ͊kǚ֌زҒɈ׸șѺqπɥ"],"encodeOffsets":[[93898,28439]]}},{"type":"Feature","id":"BWA","properties":{"name":"Botswana"},"geometry":{"type":"Polygon","coordinates":["@@ǜƭ˄ӡॎइήĝD̑ʚՑٰŹ՚ϝ஑أݭع˩֓ʧ́ҙãƧГďʽ՝țہ¤БɾΟĸХșȵГЉʧпϑ׻đȇ̐üԠӽߚɧŲAរࠤˆ|Ჾش„ಖ͎̎΍՜ͤʮDӂȎưÙ͔ڣ"],"encodeOffsets":[[26265,-18980]]}},{"type":"Feature","id":"CAF","properties":{"name":"Central African Republic"},"geometry":{"type":"Polygon","coordinates":["@@ۜÚƺɎƔgȾȏ੔͐Τ͠Ѭ̌ĉ̐ʂüߺ½߆ϴ؊ࣺю;ՐƜĪΫӜԿF΃ƋΓÄʻ̆ʍٖοҢͻT˗֠ѫΖεɆԋغͩƊˉˣęաpكĘ̹ïųȱ˕}ͧDzधнϥĎŗÝʥԕطǐؙĊ՗̴ۓ˸҉˓͛яùדգ²֩Ƙԅѻѯޱėʐ›Ϧϧ˔̳Ѡï̠ЇѮæʢċΞÞٴȬƴц࡜"],"encodeOffsets":[[15647,7601]]}},{"type":"Feature","id":"CAN","properties":{"name":"Canada"},"geometry":{"type":"MultiPolygon","coordinates":[["@@؎œުxЯ΅̵Å੥Φȿˬ͆ʸ̎С"],["@@Хcઝ˂ޯІ̄î૆Ɂ࡮Η|Ʒ"],["@@хŝൡϢʥ̘ݩ̌Ưʈࡻư͕ҜðȚࢨǿԨŵ߄ė˺̃дЋ࠼΍Όҩ"],["@@։ܿո˴֠ǵ̏̉ݚɱϰȴ࠼ʵʹ؛טƞņѿʼԷΝ݉ϝ‹փǂǾیɻńইܯԅ†צЂ߫Ȳࣙ¹࿅~ŹʠԼ̐λɬ۸Ԓࢄ೾Զӎܲ̂϶™Njɫ҅Չ"],["@@@@@@@@߰äʥ॓ܶگͯDԑϪ̵ϮчʾƻτºˎЂŋ"],["@@͡ѳχîəʢ Î͖ʦΆkɈǣ"],["@@ঝҧץnǿɪزϲ଼SiǍ"],["@@ƼυјżӨɗं˽४ʽöЍؤÞ׶˥ݙ˃ಳȬҽϚ࠭ҁ஡ѣ˿Ӯଗăܴдņڌ˺ޔ؈å"],["@@ष¥ȿЪΦҼޖŜپɷXέħřձʛ"],["@@Է̍ଉʬۃğଫϘ݊ʼטζࢼʃԎƯʦDžԠ͍"],["@@G࡭૰ڄ৐եʡح߾֥࢚؈ؖܨ°ईஞÝఔūૼй¼зس҃פ҇ŃУ࿩חୡŻࢃʨʣуߵ۽ʓοই֩ளÇڏΡÇձ঍Ŀਉڻ࣭ु͙ڏ±উంƕϜ޻ϼّ୲ǔ༞εࡀ͋׺Ѕ੆ɳࢸΟ൶µࣴąƍܫʼࡋ،ळనߗ٨˚ҔࡺѭೢףѶഎЀ॒לҮהç֭֘܌৷لলࢤνݾ˫ಾגȘ෸ɫࡸć۠ɚ޴˵ਚӣʮ͙ຄÛ}۷˪ਜ਼ގſ،ӵ௖Ұߦऔ֌ϸٺݣબੳघ৙͵Յ૤Ӂݰӓംɏբˍͬ܃ټŏͶͅÖऻ؍́׽̏൯̗੏ۑ෇ƋᅛǮుPࢇÍ۱׽ੳω௉૗ॵޡ܌Ɛഘૄᄈ۪సČݔЫߍ֟ˊࣟ˜هતп൸ŨࡆीÎ؍ժ̥ਣսᇷԁ࠯ͽय؁ٓ֍܆ฤ۞഍ƒणĹջӆBନύʐ֛ƛ˧ɚٙىʱٹ̕ϡΥŽˏ¥čȹ໽A౥MϛƷࢵ؃Ŀßˍ͝ޗBࠛGϛƅƊǑøʯeďષлࡽſউ҅Ɂ@˷ƂĥŦnĔȂ̎ЂҦʘӺǙܴǵނ࢕ЂľƬūĺɳ@ǛƆ¥ȤǍēɥ€¾ĊȡĊćɚٵːڹ˪ࠑ͘߁̨ݧʃ˝Sਕɔڻʼnࠁʺ࡫Ɔו¾ʻƜƫҤ˳IE͓჏BᮝA᭯@ᡃ@ᠿ@៙@ᢡ@ࠛ@᠁@ᛷ@őF྽ࠜ׵δຽΐҳݖŤԨ੻ΨƧڴ৭؎iѠҲКwՌෙ՘࡭ॠՁ׾ޑϚ֣ΈѿѢࡇ˕ࠇҹݛւדπࠋɸࠟ|JⷎNᷲ༬ȭ೘Й࢘û݆ΖৰˀఢĹ఼τ൘Ⱦ־ΑظȠȊЄ׈ęෆݫ૦֬ŖّਔƐ͆ʖৰ·౼Λዸ̭ୄƛࠖÄଊэ஁зຶǷᗘIJܒƦࣆԋࣴьࡩΦժ˼৾žڦĎڴȩࡊҗरä๢ϛಬƄ௬oĭԺݞƦದ˵KߑՖڠڰuϞࡊ࣑԰কͺäघশ؎ૌƇࡘχଞॅݗЭ༠ǝ"],["@@нϿሎʬୠщॊіސ˟یࠛфΒ׭ࡰ݊Ŭ࠲Ƈश͹ՆࠉʼץථеະЉĝσൡã՚͓˱ູ̯Ƃฃɪঋ»ཅ˷ᒃű๻āҕІଫɮݙģਛږ֔ĚಘƜஈ›રƦྷȞᅗã஗jѷ̴ዎͲಗ[ืɚ۶ـגͮᖬԠ࡬Nj"],["@@݉ևಹך˸Ş૸’ٔȁ"],["@@öɵࢿ|ࣟjࣿőʑ¼ऍѾ˜̠ИÈነěชң"],["@@ڎԽޤڴᒆΈ෺ࢅůջဒʒߒͮሀыୄЏŊν༚Ȑ࢘՗᎐ܸͩ͹ߐ޻໯ϹጘչೲȁீޙೖÇʽכ้ঋਗά೓߲ઙĿŁӕࢪӥଜϯΌɟմࠩ́׿੕ɪᑏڨஎܣ࢔ԕƎ̉ᗱͲᅩӤ৳Ц̌ʂయќ௥Т`ʑᝡƅ܃˾ֆؤ཈dႸņ˫̜̊оચࠊɳϊ͕˾౿Рၳ˺՞ɆࢷԺ݋´ڏ˸҇ʛ຿ŅᵝȈᄫʚഹŴۥ̐࢞Ϧ஝Hˉ࡚٦ݨࡺ΄ᓪɢأի"],["@@৊ǯຄńɖʑ޷Е౜αƱݳ൝͗߳ê׉͎ᐡٮjˎ႖ĽएռসР"],["@@࣓عय़ŒԽ݆`кѮΨ࠰ɮც‡ྈȱళݟ৉Ǎ"],["@@ᕍЙѷςኹѺήΤ׌ؘܰւࠑԦᭊƀ஬ǧᒰ±ࠄʑࣖΝ੍ɃᏝןਫי@ν"],["@@ҙ͙௝Øৱɖ҂Ϛீɨܼ̬̍ˇ"],["@@ٞϵ€љϣس൱đࣗƈjӬ൝ÝÁٮࣜౌ˺ஂµÜŎ"],["@@̙͢ݠƘࢢ™ƪЩԝЋ᭗Žᑯη౩mŅ˜პϊ④ij୯Ʈପࠐ߈ɾᛄ˳๶ӻฺÛறߨޔ̪ࢄĭ˲Џ"],["@@ढ˓ကFܨˡȑ́८ȍՔȧଊ™௬ë೸ǼႊðീÏ࣒ͅȊ΍ԽɟభǷ੽ĸᜱŻႫcഫļᖁ˔̃ҦĹжࡇξ჋ĺঅʼ͂ΈႾÁ"],["@@ŗ٣٩̇޹£༝Ϋ഍ŹଗǼ@@ුؼႮծಆ[ସŬ"],["@@ϣy༽Âɡɼၜ]מƻĵĩ"],["@@༩ʋఝ˔ڼˎ௮Đஈſ˩ʥ"],["@@৽ǏඉBbŤࡴʦҌદǝ"],["@@కǥۃȚέ͂áΎજ‘ӪÅ৐̇ɫ̣"],["@@͜Ε൏Ĥ൩˘ሏŒߺʠ৫ȮÕ͐࿶ŕᗢ̫ٞЍ"],["@@০˕ଽʟ༇ك๥Óდņࣗ΄^̦ڔɢ໡Oए˨ՑϠ׌ώ׊ʲࡴÎοȖዜ¨੶҅මǵ൞ǃڒև"],["@@ᖢßᅮŅ໤ɫ™ɡᏅη᎙ǟݻȉᆬJጡԙേʃ෯ۇႿƓՙǡᡷěୈĿׇƭ۞бߙ˽ಛʃЋ͡୫ʣŞȏ෬lȳᖟԋᔧɴឿŻధĸཟªĿЖ༊Ȑб؆ԢÐᖤγ଩բഹLjڼ͘๰Ȩʄ̊஋͠ΥѠᘞ—ڒĝ಼̪ቃĬ᰽Á๣˸۩ͼগʘȁ˺దLjঘ‚࿲ƌం̺ਬ©ࣤɽٔҒૐƈບĢᢲ–Ҁĝ᝚ƚᆔÁᆒÁ"]],"encodeOffsets":[[[-65192,47668]],[[-63289,50284]],[[-126474,49675]],[[-57481,51904]],[[-135895,55337]],[[-81168,63651]],[[-83863,64216]],[[-87205,67234]],[[-77686,68761]],[[-97943,70767]],[[-92720,71166]],[[-116907,74877]],[[-107008,75183]],[[-78172,74858]],[[-88639,74914]],[[-102764,75617]],[[-95433,74519]],[[-123351,73097]],[[-95859,76780]],[[-100864,78562]],[[-110808,78031]],[[-96956,78949]],[[-118987,79509]],[[-96092,79381]],[[-112831,79562]],[[-112295,80489]],[[-98130,79931]],[[-102461,80205]],[[-89108,81572]],[[-70144,85101]]]}},{"type":"Feature","id":"CHE","properties":{"name":"Switzerland"},"geometry":{"type":"Polygon","coordinates":["@@ƫŹȳϞƵіwá΅χƙةŀǻ͹ЏơƄһ˵Л¡αǶ˽ςБſ^ϠؚҾɈϤûɲƞ܎MǦǼ࣒ʱ"],"encodeOffsets":[[9825,48666]]}},{"type":"Feature","id":"CHL","properties":{"name":"Chile"},"geometry":{"type":"MultiPolygon","coordinates":[["@@Bም࣒@Ԓw˧ͻܛʻЭ‚ӻä؏ʨ࢟ŨੑҸ࡫Ҏୃशۘǭ୼֗૜̟ѢϬ˘ֺޠΎװı"],["@@͢୅؆ŘĺɁ˿ࢍࣵг€ඓǫ˓ʦ͡ץԹջ߁̛ރĀ߿ԫࡹϮฏɔƵCޛӑࠍpۯٍշFޙʮࠏԉ̧ɣݡȟࡱƚ৿ͷǡȞॹϜ͇ˡΛ϶ǙĚ̓νǃĜӱ̫૗ѽܓĮыˇՑ٣υôࢹ̧̐֔ÄgؽΒө᎔őުſݝPЙȷݷ̣Ɖ޹Σoॅ˚१ג@@ਲ਼ӔˁՒʄӰх֒Ņ෤Φ߰ࢴٰౣʔߞݒ˸ඊत̏Ѯგ֝ɠʿ਻ՉŠ˂ல˺༒ϮָʍࠎéूΠ„Ԩപ׈എΤబȗ఼ʤۚĵਞӮਆưྺ˒ნˀሤÕ൘ǩ஄ќɌɦњЬֱŐ؅ѴΡ˅߽Ҍह"]],"encodeOffsets":[[[-70281,-53899]],[[-69857,-22010]]]}},{"type":"Feature","id":"CHN","properties":{"name":"China"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ԑഓΫۏѷ܂ĩخӶࠜڦَϨʡƣԓ","@@ܩЗۏʺyܢаϠࣾɾӚoȊ͍σσșӟ"],["@@ฬˍ঺ׯͼ߃౨Cܰͨ൸ʜѳݱ͙̭˽ः֡ࠇ৵ƪܝ̑ɜܙť঳ѕwLяթӺͯһಙαƀѹܩŒЍ˂ֽ׭ऑҋۃա୭ʑأϽࣝɭ҂ϴǭ͞ږ֠ѹѲܷ̓ॉ׏ԫթ࠙¡ѓϻѸ֩یƏ„ϕڔʕस׶ݚ͝լuƌѱஓɻϻҏࠇућיࣜҥͦࠝԞޓ֮٥_دՅɯȪ҃ӶʻŻۃɇڗҷ÷ؗࣧڹિޭোିޡୟۻृĩԣύ̃˘Ӈй୭сࢵŹ˻ࢱҭ·ə؎Ȧ͘ૻːЇƍࡍɔЏ΀ƄӜޏƶЙܑ̀҃ࠇīڡJ҉ȳѥūŶ॥҃x÷Ȣ}Ύ؝ʓεƸر͂ʔۤՏǎȧޜࢱƓĴাߔۮ”ۚ{٠νȨ˭ӶӭÙࣟŲ˴ΜϿԺ׳Ν۵ȸॷ՗އسڳĿοɦѹr׷Țґɇ֋رëڌԟǭওĈोȖڿτٵǔ˯ЖҽŦࡓոکʴΑȩଢ଼טࠛՒɽऐ׾ő‚іͭјĐۆࣙঠ൧ͼʝ٦ةϼƫʌųӎˆ͜ԛȔ˟ďɇިʈȔśȠߤЈ׈ǐࢸő͆՜ંIJͮ̚೜ҔŠȐãӐּɔݱฦဘͲјȈ؆ຒဠˡҲϞ¢ࡆۦĀٖ֔͢èɚו۸ѽப̿׆ڱ͕ঙ̢ηূƝଆŝ৪ԻԲġϤޟӲӿऒnჄȉ૤Ŝࠦůఔԛ৮BόʽঐҌബ̈ాŒঘ̒׾҈ך˰Ƌˤˍ͔ѴըӀùࡺǝ࠸Ѿ౲͚؞֊נʆ௠ŐڐĥĠ̘ݿזګː٥̳ࠣžӇŃɏΆר࠾Цو৚̓ஆՎQτݸࢾҲːWҪңȦۜмਰƲ૜vసʡ݈̱԰ࡏ̀α̊ԩ̶ࠕ"]],"encodeOffsets":[[[124701,24980],[112988,19127]],[[130722,50955]]]}},{"type":"Feature","id":"CIV","properties":{"name":"Ivory Coast"},"geometry":{"type":"Polygon","coordinates":["@@ϣUוǒ՟Wহƥ׍ʍ̯ࠫNjvÞۖĄŀ}ͨΣΚˉÈʕɲǾώčО ʔƄB¸ξÝnjĄŜ̸ĶȹڨȗΎæ˸ǘÞŊúɸųٮOƸʖƢgʎĦžΫȞłΌŰϚǽƦ˥Ϙǯ̎ɄϾŒֺɏɠ஡Ο۷ɕेθܣ›ͧ"],"encodeOffsets":[[-2924,5115]]}},{"type":"Feature","id":"CMR","properties":{"name":"Cameroon"},"geometry":{"type":"Polygon","coordinates":["@@Ľ°ӻŇԝŒЋÅ൅nŬڒ͟֊ϧƚǟϖɋŦXɶɎתЎ߸ʒRԄӮ͈bҾΉ־˲ĀΔȌͺžь҆ΊǞךDzȊŢѨɜ՚۾ٲ¬˨ĠƲͫͰ‚ˌʂ¶ͮ՟Ê֏‹֏ҜޅҷTʁÏϥČǻЅӸөμƛŠΏˆ׃ſɩх࡛ȫƳÝٳČΝåʡЈѭð̴̟џϨ˓œϥĘʏÓґڛȤڷɜ੗"],"encodeOffsets":[[13390,2322]]}},{"type":"Feature","id":"COD","properties":{"name":"Democratic Republic of the Congo"},"geometry":{"type":"Polygon","coordinates":["@@»ঙͶŕˑ̗͓ɟ͍ѫǯϷ±ګț͍Oهʍɹ‹ԃŗÝýҟɄϡÂ৥ưޝċѧǘӣӤҹҒ੕ͥĒ૿ƙɣĵʇՙȊχƫষĻࡇɨƫט͝ɲƴìٟࣟR·Ҧ̳ΨٟŠȋѰԣ˅ڧŞ˫ϢՕüϽqµʾ́rϥºԳųιtȻû®ৄ˩̸ÕԬŬԒǝ͖eՊ৳Qò̢ѕG­ƣԵɁӧűȿҫŠˣş։å͏Ѱȗ˖ʋԌȷض៛\\̍ķʑh΋œşʼɊʀμƎɎ̪ǰɚđ˼͐ҜSÄʃ̼ƩӶՄӨШɆːƒ۔θࠆϬўքМĪˌt̰Ǝ̆«ӊŀݖǐԾʦ҈¸Ԕúה͜ѐҊ˔۔˷՘ؚ̳ĉظǏʦԖŘÞϦčनоͨDZ˖~ŴȲ̺ðلėբoˤĚԘۙϘķɤƖϲÅҶDzȦΫ݊֏"],"encodeOffsets":[[31574,3594]]}},{"type":"Feature","id":"COG","properties":{"name":"Republic of the Congo"},"geometry":{"type":"Polygon","coordinates":["@@̿˾ʩƗͻγۏࢸٖҪ̓֌˾ɂ֦ĺäό҆Зݐ•ʴЈł֒ĝڀЉӺζ঄ȽǘسçɻѢÔξ੘ڸɛڜȣÔҒѰ޲ԆѼ֪Ɨդ±·ԓʥ҇ǏԽĿݕ¬Ӊƍ̅s̯ĩˋփЛϫѝηࠅ„ۓɅˏӧЧӵՃ̻ƪÃʄқT˻͏əĒ"],"encodeOffsets":[[13308,-4895]]}},{"type":"Feature","id":"COL","properties":{"name":"Colombia"},"geometry":{"type":"Polygon","coordinates":["@@ΫȤЭ˨ʅƅ܉Ŝȱΰƽ_࠿Ӓŕʺ̼ڛтȢ̦иÊΞՆ͐Ѵ̳ȦDŽӦȏސǸɚƃ܄ͻ҄ņТ˔ÑǂʠțӶĺŬѢـהΌĚT˦ƺ܂ӖϸՊfäǪڂéڌъ͞ȊОК̖»ɚɛǍ˱գƕɇп͗ʋʓ̷Ĺ׵ɷӭѢÇņϭȄȁâ͹ij̵ˆǫȸéȨ̉ઊĄӦŃעܡͼĚ؂­ӐĪ̔ƟƱҍȇ˯ß׻ǜ֑ʆʟ†ȉэл̨ȃɠ̋ʰ࠹ǁĻǏӸɷˊ˥́࿕lZԿӰē…͏ǙĔҿƑK؏ώ̫ƀӓoηϙᘯп҂ʣpժࡤٟϾԍị̈ƤҧɝصŀӵࢤϳɐˍІ֑Њɡā"],"encodeOffsets":[[-77182,-155]]}},{"type":"Feature","id":"CRI","properties":{"name":"Costa Rica"},"geometry":{"type":"Polygon","coordinates":["@@җȆǟǮĬƤ‰ȄɷȪͥǔ́ņÅʖəƮÄʑǗȩȓɸˑĊŗǞLʮŎˆʁŠȖnjŴňֆɝȖŊˊéƔǥʜÇȪDzɈҙ͖ͷЂΩ͗õLͷǪűűıƱëǟ©Ǖ"],"encodeOffsets":[[-84956,8423]]}},{"type":"Feature","id":"CUB","properties":{"name":"Cuba"},"geometry":{"type":"Polygon","coordinates":["@@ܨÑڊW߄˹̭ͮ޺Ĩ̔ȡ܈ԳԺϛˢ\\ԆǟÕʁئ“ٌ΅ıȟ֑Ń֡¥׃âளą֜Ҷ΁ɔէÈ̃ʐȥӎӃ޵ɦʥǬભž̋ǐ̀ɀࠗ¨׿ѧΏ[ťȳеğΫĂѺʸǼ̤ϞȈіǎَĄȰĢ"],"encodeOffsets":[[-84242,23746]]}},{"type":"Feature","id":"-99","properties":{"name":"Northern Cyprus"},"geometry":{"type":"Polygon","coordinates":["@@ÐJŨȮ؄Yކʢ֧ΧÔƿęˆLJÙűj¥iĎѾNjVɫïƿ¬"],"encodeOffsets":[[33518,35984]]}},{"type":"Feature","id":"CYP","properties":{"name":"Cyprus"},"geometry":{"type":"Polygon","coordinates":["@@€ãࡱͿЩŊȟͶЎŒǀ«ɬðnjUÒ½j覎ŲiLjÚ̇"],"encodeOffsets":[[34789,35900]]}},{"type":"Feature","id":"CZE","properties":{"name":"Czech Republic"},"geometry":{"type":"Polygon","coordinates":["@@ϯǂЁ©ٵʲ̏Ùҿ΅ر˔ӃΰѕȬėΠƧʠؒǾ̸Ⱦ׾ǎɂdžɜīϒĖЊ˓ؼñ¿ɳҘǧŲɒּĥĄʿز»ϮЯʡCŽƯȕ—ÅȑLJ¡wý˹ēϋbšȁ"],"encodeOffsets":[[17368,49764]]}},{"type":"Feature","id":"DEU","properties":{"name":"Germany"},"geometry":{"type":"Polygon","coordinates":["@@d͗ࡔțS̗ࡢǂҾɰॊͧІˋȞёɹɣ̨̙Ⱥ҅ß́Έ՛ϑĕɛĬɁDž׽Ǎ̷ȽؑǽƨʟĘΟіȫӄί̑ϯ̟ŃŢշýƛʿǤЕ~׷ƭݍ–ţɛыɺʩ±࣑ʲǥǻ܍Nń״ьֺ௅ƸЇɘ´ςǗȐĨ֨ƗࢢԎ@Ɉ͂Ⱦޔƿ˴ǐDz۰°Ƽȃ֮вȓ̀ӈٌōՠŸ"],"encodeOffsets":[[10161,56303]]}},{"type":"Feature","id":"DJI","properties":{"name":"Djibouti"},"geometry":{"type":"Polygon","coordinates":["@@ȤʹΑӏȩήɯ̱҇ȅƬȭÏҷb_ʮßɶ˴Ѐ̐ϊήñʪȴ"],"encodeOffsets":[[44116,13005]]}},{"type":"Feature","id":"DNK","properties":{"name":"Denmark"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ԋڹ࢟ӄŝΒ௼˨ˎу"],["@@ȵ̓ʡĞ؁؁ɮХ՟ŷًŎͽҲ}࡬Ɣɪʌʦ݌À̐ɴڮʂƒѝʟ˙ĶɽҘŵ"]],"encodeOffsets":[[[12995,56945]],[[11175,57814]]]}},{"type":"Feature","id":"DOM","properties":{"name":"Dominican Republic"},"geometry":{"type":"Polygon","coordinates":["@@ŀƞپIӾɏɜtƴ̕Ҡhʡϐ‰Ю̷̯ͿЍǼϫ•ˡ¢ƱƵ͑½ŷȲˣťͳֻɏƆ§ʎjɬɍʦȲƚÞ͒óҜ"],"encodeOffsets":[[-73433,20188]]}},{"type":"Feature","id":"DZA","properties":{"name":"Algeria"},"geometry":{"type":"Polygon","coordinates":["@@ᮩཽᝩ࿷இϑटćU՘ϵƌԹʊȧЀᬻᆴᬻᆴṕᎠfnj@ÊQ঺ബب࠼Ÿێɦ͎тচͪ˜جӢòϞ̶સƚƸ͜ɛDz̃ࢲ¹Ԟ́ՠ߰ҠࣦƢՌΎ߶ʰ෎Ƭർæшůߊͨ࣌P΀ȝֺ¾ǟћƄߟȡۙԭҵôمۊԃRȯԮ͹Ϊຝ˖ݏ°ϵƧۇÔϥŃҟòՇͫΗӺؓŽέ̘ҵϼƸڒϷςՃ"],"encodeOffsets":[[12288,24035]]}},{"type":"Feature","id":"ECU","properties":{"name":"Ecuador"},"geometry":{"type":"Polygon","coordinates":["@@҂غǻξ͍ϵԉςǞʀƙބ̎ŴƺԼ͆զÍ΄ҢǸ׀Ͱࡀӑƾ`Ȳί܊śʆƆЮ˧άȣŞٓʽճࣷ࢟য়ͧԥܵǃ֣Ӆ΋ΙъͻĞ΍áw̮ʈȨıΔ"],"encodeOffsets":[[-82229,-3486]]}},{"type":"Feature","id":"EGY","properties":{"name":"Egypt"},"geometry":{"type":"Polygon","coordinates":["@@ɽͷǹىɫѩȝƥ˩˔ϛϒ׵ஸđùΐࢯԪࡋٌವ̴ҙ˒ӃݮछǗƣ‚ճ঒ݭƨǣΏ@Ὁ@⁩@@ᶶ@Ჴʥڲɐ԰Żά̤Ж૦b߲ɝ࠲ʛϴſ٨ˊΌʊݎêװŃɮеȜ˜ڨȣټ³аɄւ෽"],"encodeOffsets":[[35761,30210]]}},{"type":"Feature","id":"ERI","properties":{"name":"Eritrea"},"geometry":{"type":"Polygon","coordinates":["@@˻˖ΉӰϋ˒ɏܷ̄ͶֻXȭǬӯȡԛϢʽط঑ǬęʹβఀĊ֒ˆʴؤƐьӒӦঃɴޗҢУବߏҲӍҖӝˀ˿аʧʩȳέò"],"encodeOffsets":[[43368,12844]]}},{"type":"Feature","id":"ESP","properties":{"name":"Spain"},"geometry":{"type":"Polygon","coordinates":["@@¦״΃θஒ؆ਊƱ૾NࣂƝۦªമƒͰ͛໺ϡ̨ǺीϝআŊ®ӥߓ֓ઁǯõ˱ԩү͕ہ͞ӑӟϑǹճىǗש٥੧_ߟhՃ͍̓ͅЩê̵˴ʃӚ޷žé˦̶̀Śɬ̃ʢɶրͳԌδè’ЈƎŬZپϲɪɻфөˆƝŁӹCɁЬ΃ū̥ɇ"],"encodeOffsets":[[-9251,42886]]}},{"type":"Feature","id":"EST","properties":{"name":"Estonia"},"geometry":{"type":"Polygon","coordinates":["@@ĮӸ̱ŁՓ̘ñӘਫ਼ɼ੔Ũ࣮Ƒࢂ|Ŵƣׯӝʞ޵ΫˉۙDܡ̸ρļ܏Ʃ"],"encodeOffsets":[[24897,59181]]}},{"type":"Feature","id":"ETH","properties":{"name":"Ethiopia"},"geometry":{"type":"Polygon","coordinates":["@@ԜϡӰȢȮǫּWܸ͵ɐ̃όˑΊӯ˼˕̏ω˳Ͽàɵ`ʭҸaȮÐȆƫǽ̴̕ҧ̴Й̛͎ᩨঽۺNᛛᡃફ™ݟףաeɯ˅ַB͹˴ލΙʝΓ֕àȃĬȟwˇT੟܌ב@˹ˢ@ҾѧƘӻࣴϥȚƧʹэЦԧÒ˸ӐҀrŲʰ[ݲʞࢠЊɾĎ΄ήٜԔи΀ࠠƆܠ঒ǫʾظ"],"encodeOffsets":[[38816,15319]]}},{"type":"Feature","id":"FIN","properties":{"name":"Finland"},"geometry":{"type":"Polygon","coordinates":["@@ūיಀ֓ޡى঎ख़֡ܛݴس΅յఘֻ́ѓޭӟᅡੵໃá๑̯ൃǯӡҞ߿ˠȈࠢСݶАӪނՆ኎࣮֖Ǭē΢ୟЈ˳͜uಒ಻ֲ૩ЪԊɞतѻલ¦ࣘȭߠϊЬ؞ಬ˶઄ͯΡכ"],"encodeOffsets":[[29279,70723]]}},{"type":"Feature","id":"FJI","properties":{"name":"Fiji"},"geometry":{"type":"MultiPolygon","coordinates":[["@@̂ʍƓѭԳŗҩļąτ͖̀ϤĻȼƐ"],["@@՛ǯŅ̼оǤˊ°Ӱˀ@ЧՕȷ"],["@@é­@ШǨžĽЗ"]],"encodeOffsets":[[[182655,-17756]],[[183669,-17204]],[[-184235,-16897]]]}},{"type":"Feature","id":"FLK","properties":{"name":"Falkland Islands"},"geometry":{"type":"Polygon","coordinates":["@@৘Ԍ܎ȿԌʹڦϙʥ̋ଋʥϙ̌܋ϙпϚ"],"encodeOffsets":[[-62668,-53094]]}},{"type":"Feature","id":"FRA","properties":{"name":"France"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ˣ٭ϡǠș֢ǜ̺ը͎Ɯܛ"],["@@הЅќà݀ϥȊñʎjЈɗெƷыֹŃ׳ɱƝϣü‚ɇؙҽ]ϟВƀ˾ρ“ʁʚ̿̅ʯɐٱҖŃĩηݿӅစɬ௧˗ĩԑঅʼnिϞ̧ǹ໹Ϣͯ͜ѢԎdžူࢁࢤإю౹͒čؖઠǾථɏˇॎߌέዠپʨێܾǞŪ̑ϸ_ϸ͵"]],"encodeOffsets":[[[9790,43165]],[[3675,51589]]]}},{"type":"Feature","id":"GAB","properties":{"name":"Gabon"},"geometry":{"type":"Polygon","coordinates":["@@ࡹࡔ։ۚԙࢄ‚˨ǾˎȲؔǜخ˴¶௢SOৠЌÆԞőӼňľ¯ÓνɼѡشèȾǗεঃЊӹĞٿŁ֑ʳЇݏ–҅Иãϋ֥Ĺ˽Ɂ̈́֋ٕҩ"],"encodeOffsets":[[11361,-4074]]}},{"type":"Feature","id":"GBR","properties":{"name":"United Kingdom"},"geometry":{"type":"MultiPolygon","coordinates":[["@@҉ֽًǦԱ[ǦҊǥ҈۴–ࣔԳ"],["@@࣋ࣧࡦŘऄIɕۅݯݩࢄÃäĕݠ঱ֺƇԬढ़ʈͧৰDžķ՝ѓʗͲѣݱѯ૳Rෝɱϻǒ։ϿޥĪם͍ҁǘ௼ࢨݪǺOBಽƔʃͰ࢜ʺҡҐdžռఢ÷D@ŮӤ֛Ԯ_\\৵ƨȧɬ̨ϒˡɴҍЇ·߶щє̨ࢆٶھڤá০ì"]],"encodeOffsets":[[[-5797,55864]],[[-3077,60043]]]}},{"type":"Feature","id":"GEO","properties":{"name":"Georgia"},"geometry":{"type":"Polygon","coordinates":["@@Ųάȿִӟ̲ҭĬ̯ʴĺIJ܄ƝఆƋଦЕƦƻԚƂ޶ǭʴ·Նșɓřвғŗıҏºصʎȵƍଢ଼ſ߳Юࣅ¡"],"encodeOffsets":[[42552,42533]]}},{"type":"Feature","id":"GHA","properties":{"name":"Ghana"},"geometry":{"type":"Polygon","coordinates":["@@೉ӯҳ˽ݳʑݡʆœͨηܤɖैΠ۸ɟ஢ŗنrӊฤ¢ϊÕ˔ƊϴáÕʿΖџC؍Ąڍɂ̫ȅݳäйɢՓȈ̍"],"encodeOffsets":[[1086,6072]]}},{"type":"Feature","id":"GIN","properties":{"name":"Guinea"},"geometry":{"type":"Polygon","coordinates":["@@ʃtǡͷʁJǏǴÈͶΗԨɕħǵmɳ³V̮Ƈɘ‚ʔǻΜɹ̜ڥDțǁɵoƝǷīɹ҅σρӼ͛͢ɋŊȿǖħϊūȂʓƐώЦʮeɖƘȄDƄŎï˨ĢĖd˶МU؀ȱȄlÚĤҜáŨ´¶̭ƆBɖŒƔƒɸɇάãɲǺ˖ŒȬŠǚuȈȁĴɳΆΙǣɏ˙ǴĊŀį«ʡʲʍǗÝå˷Ș΍Ⱥڧ̷ĵăśÞNj·νƃA"],"encodeOffsets":[[-8641,7871]]}},{"type":"Feature","id":"GMB","properties":{"name":"Gambia"},"geometry":{"type":"Polygon","coordinates":["@@ņόࣶzȎȦˊ`ͨȷʼIˢƚǞʏεȋιdέǰ̷ȗƭQȫŝއl"],"encodeOffsets":[[-17245,13468]]}},{"type":"Feature","id":"GNB","properties":{"name":"Guinea Bissau"},"geometry":{"type":"Polygon","coordinates":["@@҅ΘΝÈȕʀLŸʯǴÁǶѼƌ˦ɦĨ༈•c˵ġĕð˧ƃōȃCɕƗʭfύХ"],"encodeOffsets":[[-15493,11306]]}},{"type":"Feature","id":"GNQ","properties":{"name":"Equatorial Guinea"},"geometry":{"type":"Polygon","coordinates":["@@ƿŴ़̀െmPয়௡T˳µ"],"encodeOffsets":[[9721,1035]]}},{"type":"Feature","id":"GRC","properties":{"name":"Greece"},"geometry":{"type":"MultiPolygon","coordinates":[["@@Ҡ˱ٺ¶شÑqƣҜĶĿʛ௃íTƒਁǎƺΦ"],["@@ʹՁȥĥԟ|ѫĀৱɓ׌ҿяƋҳAѻўƿȁȊԅрЁ̓ǿҴϯжʑ^ӅޥɠʜѕՓĕ͈ݏ֏Yۍμ̿ڦƧ֒͝ϮљӐÉʆϸТ¼˚˘Ũjɚռö͌ȀҖgƒƦdž„ت{ڨɲע̉ކĀVмЦɝ"]],"encodeOffsets":[[[24269,36562]],[[27243,42560]]]}},{"type":"Feature","id":"GRL","properties":{"name":"Greenland"},"geometry":{"type":"Polygon","coordinates":["@@ᬜԆ᱒›ੴ̴ᲈĄ䀦Ŀ㉊ڗ༅͕ộ™⭏ćшƫᲐĠᡚ́࿈ʴۦ̝इӧᒞ̺✘͚ᠼNjҾΫ⃝ױӃȕ᧑ơወ¡ছؕگկ€ध৚շಽ“൧ˇ༂ѽȢ܋࣍ýઞܡህÑঈ΁˟̑இŽ୥E੆֩\\Ϗပΐћɣଌȿ઼ԣ͈ڱກlj٫͖ਣӘ˼֭উѵᕖ•୆¯ᖯܵᗿڏឧ́ओIࢅ͓ୟࢱᅵכׅ“૧ȷ஽ȝܛԱ[כыտോڧͺٿϗ۝љࠍஅ½఍ۈဿLࠁҢ֕ࠐฝਲэոŗݮ୓ޢ̢ئ֗̒ࠪচొ̺ͨΘǬڀॡ̕қůݯţਏ˜Éְ͢҂ެ\\႔ɟ෿Քݩ˾࠷ş۫ȼम޴ԝ̺ڗ׈ৡࢼ੯͚XΚᖷӮᄻÖᖟ‘Ꮕ×ইˌวՈᕂ˄ၚ¬≹ɖ቉΄Ś͜ẊИᶎИ̪͘ᗗ̠ܺͰ᯲ז௢ĚΓϘጲɜᣚƂᣖRࣺʽᕺҨፘ̽୺áპ˙ፅҐŘή"],"encodeOffsets":[[-47886,84612]]}},{"type":"Feature","id":"GTM","properties":{"name":"Guatemala"},"geometry":{"type":"Polygon","coordinates":["@@ћƦԻfϩǖҍΌrʖĮȠšƾКۆ઄Ft˸Ƌ¾ġǺ̵Ț̹ˬϜDBӂ޸BަUOڗßॅʤ@˚ƱòŰʘŃϥ͍ЉɻÏljâǑǧɇȟ½¬ıƿġ˽Ƀ}ŭ"],"encodeOffsets":[[-92257,14065]]}},{"type":"Feature","id":"GUF","properties":{"name":"French Guiana"},"geometry":{"type":"Polygon","coordinates":["@@͉͑ГÑŗʀȉ–ʹɩνǦɈΪòϤƢή͛ӸáֺѪܠ˸ğؤȥࢸۿƔ·ӻޑʳأ"],"encodeOffsets":[[-53817,2565]]}},{"type":"Feature","id":"GUY","properties":{"name":"Guyana"},"geometry":{"type":"Polygon","coordinates":["@@ր̯Դյzџ̈́o҈Чͪ̇Ƈݱԛɕ°ȣƹџϊ؏ːAŎӃԢܳȱ‰ҫî˙ɡϟƥ˅—ġǑЭ¦ԫЀÓϴɋьƆܐɸ̐ȕϸ˿ŶŊτțȘѩ™ْ֩ɬɲiϲԬƊȾƾ˽̸ô̬ږӲ"],"encodeOffsets":[[-61192,8568]]}},{"type":"Feature","id":"HND","properties":{"name":"Honduras"},"geometry":{"type":"Polygon","coordinates":["@@ơˀʭòÐʹŗĞǣÒσij‹ŔʩƈǷǚʛìǨɈáǒÐNJЊɼϦ͎ĔȂƨʊ\\þ垦ϸùϲv˒ĢİĦˎ©ȪÉɘnǖòϨśƄkʲƿʐį̏Źɜɳ˽jśŕ̇ŋɃAȅŃǙœƛźĕ{ŇȩăRaǥ̉ɳƹıđĽʛǞǹɣǫPȟqlЭūQĿȓʽ“"],"encodeOffsets":[[-89412,13297]]}},{"type":"Feature","id":"HRV","properties":{"name":"Croatia"},"geometry":{"type":"Polygon","coordinates":["@@Ȳ͗ˊʇ͓̓ϝȆׇ[ܟƔϽmǻǧ̝ȖǫΑЪϽǼʹϮ̽͌ȃ͆Ηݔ͇ġƛ߃̶ӣ̢ޑʠ۹ؤǞØϥΞe˲եƄʱγʝˮn̆Šbג…Ƹƚ˸ƍͤgGɼ̈ĒĈͺڞɠˊĻؼέۜlj̼Ų"],"encodeOffsets":[[19282,47011]]}},{"type":"Feature","id":"HTI","properties":{"name":"Haiti"},"geometry":{"type":"Polygon","coordinates":["@@Ԣ™ܰƁôқÝ͑ȱƙɎʥiɫ֏ƜЅÍԡÔϽƿ҉ʾö˔ޜśيã̢ȈϧθP͎ՋžȌɶ"],"encodeOffsets":[[-74946,20394]]}},{"type":"Feature","id":"HUN","properties":{"name":"Hungary"},"geometry":{"type":"Polygon","coordinates":["@@˨ըǍǼӂDÜ΄ђɋ̲ğ۸ļäǚͮ~ЦžĜÃЂŀȠȢˠ¼࣒ʭǴĒҲɭÎɣԡǭЉ֫ԕ֭کǁԽš١ə̻űۛNJػήˉļǍ˴ƗV"],"encodeOffsets":[[16592,47977]]}},{"type":"Feature","id":"IDN","properties":{"name":"Indonesia"},"geometry":{"type":"MultiPolygon","coordinates":[["@@Λe૝ך޴ǒѴʭ̎ʭ»ɩ"],["@@ܙȁijĶø˸ΰԢࠨͬĐǓfʫշع"],["@@̢ɣԲèȼΥॿǛ׉őҍP̀ӚҤPɤ̖"],["@@ūұ౅ʅૣľE̬ښǪՂʥ֔Üݬ̮"],["@@ྔċȂΌ༘З̪կీƵਐӿय़͋ऍ͸ݻwࢍØ޻ưঅ͎؝ČΓŁ໕ΌƣΰޑØּߤ৶·ڴ͡ΒÛŘ̗"],["@@ѝֱćنƬ̠Ǭ˴ȒʗCЏ"],["@@̿˥ׅƸǏΰࡘ¢Ⱦˣ"],["@@̨ٝۿΌۯìӃÅׇˆȦҦਠ”ऎʕ"],["@@ɼയ࢈ԉ۰ࢼ८ԔݜBܘ̉خ̛ࣘLJbᩑbᩑݟې࡟ǜȷʇ੡}ΦۂՈɺɕࣲЕ۸࿃܆ۗêృަʛУ͑óȏ̮GκٛЮ̢ࣞ״gëɠ௵DͩԄݥƺΡдଈȰњ˜ഘ·Ƃ̹"],["@@ڭ࠭كlj߱ǐඓ¥ܽŧţٍݪݛҒϠ༪˸çϯλŪιӯ͙݉ߒ੿Ƶ˿ݲॻQտ҅ʙ̐͡Мی࠙͗ȻɶŊ͖؅ӲØࠌ֕ʭîও”றՓũίʚʌޜŽ߸ΛPʻֺΎվŤښф౎ǮΎ܎ذپʛ੖śॴ–ࠨ؎Ʀȉ"],["@@©ܽџĈŷԝΌѷɽĵ͹Ւʟ੺ǚڤ˨̨ÔҝӸóĀ΃"],["@@सާহį˫ֵšݿַ߱u࠷͕౻ŭ̚ॕϙͫԤ׳´лːৃ̟̩Оս¯ۗĬŹૺнɺЕܘŝ݀ĮުԂ֐Ɩָ֗ӅըǠ՜ÑӪъЖôߒɽۆǶњୠ͔̈̆क़ॲ@ܰƙӍݷآߓơϭ"],["@@छkۻ۰અۊέԚٍۄзؾٕ୴۪݅ʙܠ̳ڀݵՊѭܘمҺࢗऒóђզ‘ಢNjݔࠓٮ֫ҪΓߔࣙࡢ_ۺֹӠ۳٘ϥͳۉӖ̞̅sƜו̊ҵؠõФՏɁ਱‘ಟ"]],"encodeOffsets":[[[123613,-10485]],[[127423,-10383]],[[120730,-8289]],[[125854,-8288]],[[111231,-6940]],[[137959,-6363]],[[130304,-3542]],[[133603,-3168]],[[137363,-1179]],[[128247,1454]],[[131777,1160]],[[120705,1872]],[[108358,-5992]]]}},{"type":"Feature","id":"IND","properties":{"name":"India"},"geometry":{"type":"Polygon","coordinates":["@@ࣚটďۅͮїѕ׽ŒɾएࠜՑ୞חՑϟ͛޻ࠀͅߊЭરһସʼnӜёٮāৠȝ۪bĪͪŋՖÞβԠǮìڋlǙކ͉Ոƀ܀Çۈ|ÐԪ΁ˎڴŀވشॸ՘۶ȷ״ΞЀԹ˳Λ࣠űÜ͇̍Ʒèԫ׷Ʋછׅ~ӓҩ۵§ХϏۗځȒࢇȏ˹ĚΣгȥѵ೰ɵEƍ՝ҡѦʸӎϖ¶ϰ܆ӝƜީ]ߝŚóאБ¤ڕζ֭̓؆ѻԿ̻ȅ̩Ԭɣƛԑ̆كžەţֱ̫Zਛǩ´ك҃ӻ௃֡ळ঩كՋ࠷ջCϭлȹݳ̝Ͻ«ʥٙǪધ®ۡΣߙI෗ѣ¡ϣٙʰˣދʃ˱֯͵ʍߑ޸ϳ୴͑ࡒ̍Јѿ߰ȻੂơՀޅ଼Α࿀ʣ੾HৰǍ޾௣ԉףĶ઱৲И̤ʝͤড܊֖֔ᇜCǗܞҽюĩ٨ջϘऒࢢঊÙ࢞ࢢՄ࡞ࠄࡈ_״ܒӠڳд֪݂̇̕Ьβ౤ȱपŰߺ۸"],"encodeOffsets":[[79706,36346]]}},{"type":"Feature","id":"IRL","properties":{"name":"Ireland"},"geometry":{"type":"Polygon","coordinates":["@@ƒ׷ًݣ๯ӹ஑Ŷڼ࢚ѭࡢତڄٌϼǦ҇ǥ҉Բ\\ٌǥ"],"encodeOffsets":[[-6346,55161]]}},{"type":"Feature","id":"IRN","properties":{"name":"Iran"},"geometry":{"type":"Polygon","coordinates":["@@݈njװӔ֚{τƾװýघэڤğ।ݓظ‰òۻ΁਷ɱؑκŭΫҡˠڡàՓِƙæեݿݿжѵ͸ԓߦυx݉ДƋêϯ௉ѡ̓উཌྷʪࣷȖेŊΧਐЕƪ٣ƭࡑНਇ˦ࡑ٦߳ʈ֗ߘا૪ҍƋՕ˦̻͝ҭѴS҂ˍ@Ɛ،ѝٔ਍Ң׉ߜȜپц̂ÙӬտʨխ৊ҟڨǐʼʿ६ּʈƄͅъϯ־ő̤~রئ̀Øʞʙ́гԼѱȾ¦ˈإߖǩ׎у஠ƟಾɞĄȞ"],"encodeOffsets":[[55216,38092]]}},{"type":"Feature","id":"IRQ","properties":{"name":"Iraq"},"geometry":{"type":"Polygon","coordinates":["@@րʧÚӫх́țٽ׊ߛ਎ҡўٓƏ؋ˎ@TҁҮѳӿ¤֟ê؝߭༟äᛍၖఫךৡɪ͹৾ᇶ࢔͆৬āؘҢȺјԾΰž঎Ň̐ɉЖƚծ৉"],"encodeOffsets":[[46511,36842]]}},{"type":"Feature","id":"ISL","properties":{"name":"Iceland"},"geometry":{"type":"Polygon","coordinates":["@@șիॊֵથٙᝓֹܣƵૉŮᚑˈࠠψᆧЪ๪ǎ—ʘᄋȜ֨նౠŰಸ֭౨Ҝ੒ʃൌ҄ආÑ"],"encodeOffsets":[[-14856,68051]]}},{"type":"Feature","id":"ISR","properties":{"name":"Israel"},"geometry":{"type":"Polygon","coordinates":["@@ƥ˅̣Ŝǫ֓ɂĥɋř—ɛЄŖp͛нഉց෾ʔˢ˶ɞϼǠيŤɆzVˬCþƦɤ\\`·ŕŵhM"],"encodeOffsets":[[36578,33495]]}},{"type":"Feature","id":"ITA","properties":{"name":"Italy"},"geometry":{"type":"MultiPolygon","coordinates":[["@@̟ڋŲʹǭѝٝ̈́ёĞ୩ѐŞќজûࡪĠْò"],["@@Ԍ׭ş૕ϣÂ΁˫͇ɞ‘২ȓӒҨ¥рʼ"],["@@ரɏĝЯȬΧڝŪہ̗²зĻʇˠё߀чцۛदڱچLȲȃɽǗݪ̥ؠʩܜѫĔƿƽ̛үϼܳƐΝի؈̷ıѫΗ¹҅ܛΕÝHʲǢҊǼǶ͝ӤʱшΑŀʛδգƴεͶثÆٿϜޑմ֯ӜʿࠪйĮہˤϯŕӝϵΓÕĪθҕńɏٲ̆ʰʙ̀”ʂβǵМ¢Ҽ˶ƢƃА€ǼͺتĿψƚâΆԘšĮdžࠨƤȊ̉"]],"encodeOffsets":[[[15893,39149]],[[9432,42200]],[[12674,47890]]]}},{"type":"Feature","id":"JAM","properties":{"name":"Jamaica"},"geometry":{"type":"Polygon","coordinates":["@@֢÷ҀȫƔɯןeʭƗҹƊӑ̪ĶȔΜÎȒƒ"],"encodeOffsets":[[-79431,18935]]}},{"type":"Feature","id":"JOR","properties":{"name":"Jordan"},"geometry":{"type":"Polygon","coordinates":["@@Ʀˆपͫ࿪ࣆͺ৽Džų၅у࠸࠿ˣƛƑ˭ٙřȩ̡εʵधƆƒŨоഊo͜Ůʚ@Ԥ"],"encodeOffsets":[[36399,33172]]}},{"type":"Feature","id":"JPN","properties":{"name":"Japan"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ņ˽ҿԕΉːљțɝӭշʈRЊҬԆӌīΊΜؠǹ"],["@@́ڡƤсѩף੹Ѓ๏½ணॡ͔֡“غษȃষЃঝe࡞أ֗෗իΝН͜ȶݶՏʒͿ־ߐʶѲՈࡌѢ؞ָာʤ࣎ǣࢠ๺֔Б௾ࡀӌ͜ՈਈƟा΢ՎࣀƸҞୗ}ڻޥࡍbࢁ"],["@@נǵרΤȈहఝɯ݁࠱೓ָқँण]ř࠴д٨࣌²ʖ୐ʜټন࢓٤˯"]],"encodeOffsets":[[[137870,34969]],[[144360,38034]],[[147365,45235]]]}},{"type":"Feature","id":"KAZ","properties":{"name":"Kazakhstan"},"geometry":{"type":"Polygon","coordinates":["@@ӕƹ્דο׹̹KɱЊ੫‚ǡێХNÚࡆ৓ؘ෷ßডũߣݶۋ͆ಥ׼ƽðᓗӹᶽљ£יچ֧ɼॕǩχ˧±ȲȶΖDž̊অ˺ϛݮҩɆ…˜ࠊāŽؘ܎ƎܼűƲࠎƭԲ࠿£܍ȴঃσ޵ǭяƌĐўՙ֘دw܉֬ӞِʕǢڢऊࡺӣŀؘჄࣴಾtᇢ׉঺ͻࢼΠ೰j੺ѥʔʠ୼—ɂЊഷ׀߮Цƿɮ߮ɔ؅ֺϬ˼Ḯ̈ШȺᑆ̴ݰΒຢǹ˄ࢉ࢚Ȳઆ˹éҝ߮´ᑌߎ̭ˁ੶٭ሠᒑ҄ѰୄӛீɎҪƯКӟטNjΨΥ઎ŒѾԣٕ֓ۥÿ¡ࡅұϝဟˢ؅ຑїȇဗͱݲลֻɓäӏԭŬу̠ఝĖඃx̧ġ஥ΞӉǧŽӹ൩̂փşȉρ"],"encodeOffsets":[[72666,43281]]}},{"type":"Feature","id":"KEN","properties":{"name":"Kenya"},"geometry":{"type":"Polygon","coordinates":["@@ӾۙיͱȹΕ̿Õšףˑ͹Ǐ֑ͷ˥஻ࡀËӤᵁႌƙĢSࢺʊ;а֌̨ؔσ॰įтЉ׎ԬԈ֬ֆѨƗ@ҽ˺ˡג@੠܋ˈSȠxȄī֖ßʞΔގΚͺ˳ָAܽ॑Xᵣ"],"encodeOffsets":[[41977,-878]]}},{"type":"Feature","id":"KGZ","properties":{"name":"Kyrgyzstan"},"geometry":{"type":"Polygon","coordinates":["@@ȊςքŠ൪́žӺӊǨ஦Ν̨Ģ඄wఞĕф̟Ԯūşȏ೛ғ̙ͭઁıͅ՛ࢷŒׇǏߣЇŜȟʇȓཟŵਡ˘࣫ÝĂӜࣴƕ̮ʸٖĉ੾؂঻ѸױȽإ͂۶ծʟĊ"],"encodeOffsets":[[72666,43281]]}},{"type":"Feature","id":"KHM","properties":{"name":"Cambodia"},"geometry":{"type":"Polygon","coordinates":["@@΁Ѭыࢄȣ২ՠۨઘdž߀ťۚ͡Ϟׄݖ̱Ȝ֕Ļ৕ඳ٧τԙࢥÓܫͷ۱Ū"],"encodeOffsets":[[105982,10888]]}},{"type":"Feature","id":"KOR","properties":{"name":"South Korea"},"geometry":{"type":"Polygon","coordinates":["@@ܨযȺխPॷ̓ҥݽljڥΏݳïĥҚƼـχ࢔ذƚֻܘÂúϒ‡͞Ϝצ¢ΨÈŨȮ"],"encodeOffsets":[[131431,39539]]}},{"type":"Feature","id":"CS-KM","properties":{"name":"Kosovo"},"geometry":{"type":"Polygon","coordinates":["@@›ǣŃPĘ́ȩĐdzɦƾȌȪÒŜ˨ư²Ţşƾ¿ŌƅƒŸǎƻŢLĥȳijij„×ȉӹŻ"],"encodeOffsets":[[21261,43062]]}},{"type":"Feature","id":"KWT","properties":{"name":"Kuwait"},"geometry":{"type":"Polygon","coordinates":["@@Ǭχõȓ˔هשuȽАݟĆ؞߮֠é"],"encodeOffsets":[[49126,30696]]}},{"type":"Feature","id":"LAO","properties":{"name":"Laos"},"geometry":{"type":"Polygon","coordinates":["@@˚Ϝœ܆ڹܸ¿ٕࠦھٍÎǛ̉ӯyʣƨࢯԅoݬȸࢮ֧ž³ԎηʸǴ̲ܐնøȡ҄wŵ०ѦŬӮڏϖޅਚO͚ܹ՝ɗʉ̟৔ԉۦ঳Ռ݋َ׏ɄץƵ࠿ݕ̲ϝ׃ۙ͢"],"encodeOffsets":[[107745,14616]]}},{"type":"Feature","id":"LBN","properties":{"name":"Lebanon"},"geometry":{"type":"Polygon","coordinates":["@@ɣ[ýƥ˫D̘ۄмעfˆϘ§Ɛͣқ̓ȷҟ"],"encodeOffsets":[[36681,34077]]}},{"type":"Feature","id":"LBR","properties":{"name":"Liberia"},"geometry":{"type":"Polygon","coordinates":["@@ɗQࡽАޅٖ܏Ң֣ըȪː¬ʔϜҘϺϺǶnɖĨΘԧÇ͵ǐdzʂIǢ͸ʄsŸʓĎНǽύʖɱˊÇΤΙ~ͧăĿÝە"],"encodeOffsets":[[-7897,4470]]}},{"type":"Feature","id":"LBY","properties":{"name":"Libya"},"geometry":{"type":"Polygon","coordinates":["@@ק̷ҿҤ೧βρՄڑϸϻƷ̗ҶήӹؔͬΘñՈńҠÓϦƨۈ¯϶˕ݐШȜðΠėΒ־͔ʶːЦʌ´٦দ́ΜðۮƓ૞ϓЀݛݮǍஆΙࣆйЦɔЖϮț٠˂Ф؄ЀׂŘ଒ǣ˺ϑ̺Iˌƛ࠴ıȲˣ̣ЕżΫɏԯʦڱ@Ჳ@ᶵ@့ॱGYΙ‧ྐ‧ྒࡓҟ"],"encodeOffsets":[[15208,23412]]}},{"type":"Feature","id":"LKA","properties":{"name":"Sri Lanka"},"geometry":{"type":"Polygon","coordinates":["@@ų࢓ΙʇܵȓЍڜƫீϠ഼׆ұϺסО࢓"],"encodeOffsets":[[83751,7704]]}},{"type":"Feature","id":"LSO","properties":{"name":"Lesotho"},"geometry":{"type":"Polygon","coordinates":["@@̆ʩʳУƛ˛ҳſƹˍ̛ċؿ٨҄ՐҖ͢ϼǠξʵ"],"encodeOffsets":[[29674,-29650]]}},{"type":"Feature","id":"LTU","properties":{"name":"Lithuania"},"geometry":{"type":"Polygon","coordinates":["@@ãɊĚɲχƄࢡƨDZ۸२ʴඬÁࠜĊŞǩ҂Ã߲СĀϓۏˏșӃ࣯̓߻NȫʶљĜ"],"encodeOffsets":[[23277,55632]]}},{"type":"Feature","id":"LUX","properties":{"name":"Luxembourg"},"geometry":{"type":"Polygon","coordinates":["@@ǘȏ³ρʍiȉòĞҼɖŽ"],"encodeOffsets":[[6189,51332]]}},{"type":"Feature","id":"LVA","properties":{"name":"Latvia"},"geometry":{"type":"Polygon","coordinates":["@@†نЮՆߊ˼ڜعڪhNJ٤ܐƪςĻܢ̷ۚCКȕîС˒ӷ͕ࣗԛƙ߱ТҁÄŝǪࠛĉණÂ१ʳ"],"encodeOffsets":[[21562,57376]]}},{"type":"Feature","id":"MAR","properties":{"name":"Morocco"},"geometry":{"type":"Polygon","coordinates":["@@ԒΥߜÎࢊȃκU͂՟ºԝ̄ࢱɜDZƷ͛ષƙϝ̵ӡñ—ثঙ͍ͩсۍɥ࠻ŷഫاRহŷ@@@p҉Ա˓ȑϡ@̥Ŋ۹ě˛ٻʿÕЁ੕ୟ࣡ˣୋ΅ϗĵ̡ቅãaD ϶͒ɮ˞ѪÃ˶̀פҴՖ˲ƊɞӬp҂̤Բ̪֔Ւ࡬f\\ц͔ްĢڎָтɠۮۮȿਸ਼͊ܢŔѶդ֨ࡈϦخΐ֘࢈˄ԪؤI"],"encodeOffsets":[[-5318,36614]]}},{"type":"Feature","id":"MDA","properties":{"name":"Moldova"},"geometry":{"type":"Polygon","coordinates":["@@ȨŮ֒ĊؤʽΊϞɥÑ˵̪ƏŨΗ̊ɇÏűƾčɝ×ӷ|ĉŜǫãÒƭɱˍƥ˽ɁĝƯϦĘΪςӝԂˉΠʹʠʯĈ"],"encodeOffsets":[[27259,49379]]}},{"type":"Feature","id":"MDG","properties":{"name":"Madagascar"},"geometry":{"type":"Polygon","coordinates":["@@ɠΥȺ։Ɗঢ়ɒϽĉЗƩʙ˷ӰǁʝLjثõΥɵȗ¿܅ͧওб୅ԯཧ͑ୟϛইہȣܻΡӛɊڙ̜ɳѺÇݘ̑ڠù؂Ʈ؄ϰƢD˪Дِø՚șЈǃՌãޠ̊ҺŔՒмŒҶǤ̶Ʋτ\\ӐӎۖԮʦцŗάΦĵҪ׎fԐ˦ϔ̊ί"],"encodeOffsets":[[50733,-12769]]}},{"type":"Feature","id":"MEX","properties":{"name":"Mexico"},"geometry":{"type":"Polygon","coordinates":["@@͙݅ƥ؁Õ૷ąЧƤқʺЧǚٳ֎سȞӏ͢бࢾɝΐΙ݄ɾٚĎؼưՊƠՖ΂ȨӬè۸Ƣʖ֬ɚࢶȚݔ‡ԚîȬDZ…ЙҋԁȥԝƸƥűγɁٽɅɎǭcǃY̝ԓƳIJķPŭޥV޷AAӁϛC̺˫̶șĢǹƌ½s˷ઃEЙۅŢƽĭȟqʕ्ࣞџ˘ۇɖҷÓګ́чĉץɜؿDŽ޹ϬؿŠ्ϸ۱ВɃɤҹº࡯ˈΓϦࣗӊсՌȧЦ˪ĈđʈȖɔJ̄˱Ϙùͮ˭ъ݋࠴ࡋڀУԼܝ΄ƷȴŸԲѓȞӹФȽהҍæӣѸϿФ™ˀҍو̓٠^͔؇ͬ˫™ӑɴƇͿƔЕĆف̀΋خׁƒȡŸÓŎ˽Ƭ\\ǜթʮɇǴ̕Նё˨ޯʠρɸϿ²ѷКƒͶϡ̨ϑqƭΝ̱ƫJɛԞջӎ؃РїɈ„ؚŵҖЏʺֿϒŏŇɃɖԭȰӷӦÖÚΊ³̸̼ŽϜ٩׶ӱɶ̱Հ̷վϳڦͿݲॖÞ੪ĞÿǑ౔СኀףဪPژ@DΌผ@̪̕јˇԀσ˨ѭȾҥѢʩۤʥՊڒۊhפͱфֹ̄ӯӸӏȂחɾЃپʹ׮ȁ͞|"],"encodeOffsets":[[-99471,26491]]}},{"type":"Feature","id":"MKD","properties":{"name":"Macedonia"},"geometry":{"type":"Polygon","coordinates":["@@ńOœǤӺżȊ˺¶ϴbтˏÒ։DžƒƑƥҕh͋ǿջõΑȴšήń˸"],"encodeOffsets":[[21085,42860]]}},{"type":"Feature","id":"MLI","properties":{"name":"Mali"},"geometry":{"type":"Polygon","coordinates":["@@˰ƶƘӶˊpזɻӄǖ͖ÇŴȈ⁚^ȈךƣļЛ⋈Л⋆౾dᬼᆳᬼᆳȨϿԺʉ϶ƋV՗ठĈFካҟ֗íԭݛƃ଩ï̳̗ա՟IȿLjҥš޻ΑDžʿٳϕŗɍΙǡНŔɱȳūֻڙۡp˳ɭΣÆӥ΋ůȝŁŽάʍĥơhƷʕ٭PɷŴʼnùʱʎ¬ʢĿİdzĉ˚Ǥɐ΅ΚijɴȇȂǙvȫş˕őɱǹΫäɷɈƓ„ɕőƅAµ̮žʾí̽͘ʀǓӔԺ"],"encodeOffsets":[[-12462,14968]]}},{"type":"Feature","id":"MMR","properties":{"name":"Myanmar"},"geometry":{"type":"Polygon","coordinates":["@@ӫηץ›ϥࣥΟƳО݅ՔؗΈօ̭ܵ̃ƹȪу֖ڙĪҷ_ϵ͠ދң޵Сࡷăذʴ٠˯ӼæࣸͽѤ˛৔Ʊਗ਼εۢօуॕ׳ҽöԳȠ̂ਪǫ޾څॺļ̢ӭņ׭ۆÅڰ̊ŵj׾дȦęΤȐ˺Ž࢈ڂȑϐۘ¨ЦҪ۶}Ӕજ׆׸ƱçԬ̎ƸÛ͈ӮÚˮӵξȧ|ٟ“ۙߓۭijঽࢲƔȨޛՐǍʓۣز́ζƷ؞ʔ~΍܏յdẕӓȗ"],"encodeOffsets":[[101933,20672]]}},{"type":"Feature","id":"MNE","properties":{"name":"Montenegro"},"geometry":{"type":"Polygon","coordinates":["@@ÁǀηЯÊˋǫÞɽ˞εǖĢƜŬҦ˚ȜƾüɠƟŬśˠě͌ǧçïƽȋɧó"],"encodeOffsets":[[20277,43521]]}},{"type":"Feature","id":"MNG","properties":{"name":"Mongolia"},"geometry":{"type":"Polygon","coordinates":["@@ࢮƢ྄ܤ౬Єܴʳ࢚]֘Ͻ࠼‰ௐɁࠈגͿӶࢊࢊश΍ނįনɍLjؿஜΛߐƺਫ਼ŌࡆōࠖЗԚѕެT੒Ƌޜȼૈƒ௸פԌĝѰ˭ৌêХهק࠽ɐ΅ӈńࠤŽ٦̴ڬˏހוğ̗ڏĦ௟ŏןʅ؝։౱͙࠷ѽࡹǞҿúѳէˎ͓ƌˣי˯׽҇গ̑ఽ‹ഫ̇এҋϋʾ৭AఓԜࠥŰૣśჃȊऑmӱԀϣޠԱĢ৩ԼଅŞুƞ̡θ͖চׅڲன̀۷Ѿəז"],"encodeOffsets":[[89858,50481]]}},{"type":"Feature","id":"MOZ","properties":{"name":"Mozambique"},"geometry":{"type":"Polygon","coordinates":["@@لæ৞ʁɖńגt̚ʦԌaऀ͜ڞӤƊϕ“࠷ľ݅ಿƨЫʣ׷͙׍՗Եޏ͉ृСॉ͓ࣕƵוׯ΋ȗí׳ЌُǔӱZʣƪ¦{ࠗƋϷȤƝűΓΗ̗ۗ˳য়ҕρ̳ðΟɊÉíѵّRïϊůϖí̠ƬपɓװГஂࢬ॔ɜ؆ŶúĨӶƉʞ˜غǐ׌E੠ѥ˒ЏÔǹȼϳǰ۫gÅ̼āװᢈۘӚЕɴüͨɅ¸͵ǯϷØסոԱʲ׌ζǰíઊΙ؈̣˖̅]ɽદɾٔ"],"encodeOffsets":[[35390,-11796]]}},{"type":"Feature","id":"MRT","properties":{"name":"Mauritania"},"geometry":{"type":"Polygon","coordinates":["@@և־ԗؤ֍ɞГʚҵUЧǽйð˽ˏïҐɺаŀߊģࠨĵкČмɑЎѵδǾˬᾔMǃ௎ȴќ߀øᒸ᪂©F౞Ṗ᎟౽cМ⋅М⋇ƤĻȇי⁙]ųȇ͕ÈӃǕוɼˉoƗӵ˯Ƶ"],"encodeOffsets":[[-12462,14968]]}},{"type":"Feature","id":"MWI","properties":{"name":"Malawi"},"geometry":{"type":"Polygon","coordinates":["@@ɽٓɾથ̆^̤˕Κ؇îઉεǯʱ׋շԲ×עǰϸ·ͶͧɆɳûәЖѵɔʮޮ˄̈LJۢǚڼƞɪɉ܌Ѕϐ࠘ƽǜɵ˶Ϲɾଡ"],"encodeOffsets":[[35390,-11796]]}},{"type":"Feature","id":"MYS","properties":{"name":"Malaysia"},"geometry":{"type":"MultiPolygon","coordinates":[["@@àћֈĶ˞ΈȘýӸԓΜ֛¶֣ęϡĆ˿Öӻ̒ɵͤݑe˳׫Éߑخ঵ښįђӟ֚ś̡۠ҜĠؔȃΤƤƮۈρ"],["@@أ˹ܯƚॱ@̅ॗ͓̇љୟۅǵߑɾЕóөщ՛Òէǟַӆƕ֘؜˽ٮǀǜ܆άǂ৖Ǻ׾ڔЬՐϦѥǮ˺В¸՜œа٪אшڀͼHќыžιֆɻ۬ʧÑ֝͡¥ƮЧ"]],"encodeOffsets":[[[103502,6354]],[[121466,4586]]]}},{"type":"Feature","id":"NAM","properties":{"name":"Namibia"},"geometry":{"type":"Polygon","coordinates":["@@رٌؖ͡ȃࠊȷ،˯ಒm৒ŅҞ͛Όѡۜѳ৘ǽՆۃࠐ»٢КdžԊƞհ}ԄϝŶÐ₮˜׌Е᎞ş໴΂یȒհµͨȍPéӁȍʭC՛͍ͣΎಕ̍سƒ{Ჽࠣ‡BយA᷋ݣѕҋÕՇDŽϗÔƗάͩɰГг"],"encodeOffsets":[[16738,-29262]]}},{"type":"Feature","id":"NCL","properties":{"name":"New Caledonia"},"geometry":{"type":"Polygon","coordinates":["@@ېԵѨϭ͉ȫҥɪ׹ϚէѼ։פś˶β[Һ˹φ˷ˎɻ"],"encodeOffsets":[[169759,-21585]]}},{"type":"Feature","id":"NER","properties":{"name":"Niger"},"geometry":{"type":"Polygon","coordinates":["@@nּॹȐОҿպœϤâТբ̴̘ପðݜƄîԮҠ֘Eኬஈϒᝪ࿸᮪ཾ೨αӀңר̸ȸಯ̾ɓ`ˋΔ˽ǻί͕ၻ«ધੳߋγૉΔ̵CեբmčЃʁµˋƻm֩ंȟ’ځҷٱʔҍ¸ʏşӯ~ӷΧѓq৯ѢЉȵѓb̿͆ࡅ̼ࣗıɕǻşӗʋ͹ÍݣٗӚ̟E˭ʗ"],"encodeOffsets":[[2207,12227]]}},{"type":"Feature","id":"NGA","properties":{"name":"Nigeria"},"geometry":{"type":"Polygon","coordinates":["@@ࢍ̡͉¬͓ȉڥl҇Ղˡ؊שֆكYݍB¶തs՘ǂՊʶʴТԴėɨǔ͸ȍӾ˪ÎݤʌͺŠӘɖǼࣘIJࡆ̻̀ͅєaЊȶৰѡєrӸΨӰ}ʐŠҎ·ٲʓڂҸȠ‘֪ँƼnͬͯğƱ«˧۽ٱɛՙšѧDZȉǝי҅ΉŽыȋ͹ÿΓֽ˱ҽΊ͇aԃӭʑQЍ߷ɍש"],"encodeOffsets":[[8705,4887]]}},{"type":"Feature","id":"NIC","properties":{"name":"Nicaragua"},"geometry":{"type":"Polygon","coordinates":["@@̃ˆϽͺȁ˲Ο˄сϜĤžƒŵÚÒʾ”ŀȔŬRkЮȠrǬOǺɤʜǝĒľƺIJ̊ɴbǦĄQňȪĖ|ƜŹǚ›ȆńɄB̈ŌŜŖ˾iïă§ȉĐ̫ȗ˹ěͷυ®ɏtϙŹĉýΫÌɛǣɋ ɩźƏȩDZʛÈƓǦˉêȕʼnօɞųŇ"],"encodeOffsets":[[-87769,11355]]}},{"type":"Feature","id":"NLD","properties":{"name":"Netherlands"},"geometry":{"type":"Polygon","coordinates":["@@ۦyǀ˳Ƚޓɇ́ԍ@ƘࢡҥȞՏπީǩ؛âѠɲ݀ఆଲΘ"],"encodeOffsets":[[6220,54795]]}},{"type":"Feature","id":"NOR","properties":{"name":"Norway"},"geometry":{"type":"MultiPolygon","coordinates":[["@@᥆ؙઍɣऄՅෛ͵ڵû΢לઃͰಫ˵Ы؝ߟωࣗȮ઱¥णѼԉɝԷ“ūփནƊɝҵ߭Hևױ࠿झಫ஁̨˹̇ͫ࠯bձ޿¾૟՞э˥ধֻۧυӛ֝Ԫဋঁ૫ȟ୏є̛ࣚˇ኶ޞզᕠ۶ဌࢂ໤୦፺ྴඦلᘼ੊ᇎπ൪­౮ۢ໖›ພǘ"],["@@ም΅๝Ȝ׆ɐԕˎეǚͮ̿ொȍ"],["@@᪖صᑟͥұأ݅ǁЍۡৣᅵԢނ̘ఽʐ࿕܂ٷڄᘎ̜Ң̋஦\\͊˼௾ˆ੖̋"],["@@࿮̏ఝҍ᝱ı៙ƖƫɴஹdँϬᣴɼ௞ȫࡘʤᑺȽ"]],"encodeOffsets":[[[28842,72894]],[[25318,79723]],[[18690,81615]],[[26059,82338]]]}},{"type":"Feature","id":"NPL","properties":{"name":"Nepal"},"geometry":{"type":"Polygon","coordinates":["@@ÝαŌՕĩͩ۩aয়Ȟ٭ĂӛђଷŊયҼ߉Ю߿͆͜޼ՒϠΒȪڪʳࡔշҾť˰ЕٶǓۀσौȕঔć"],"encodeOffsets":[[90236,28546]]}},{"type":"Feature","id":"NZL","properties":{"name":"New Zealand"},"geometry":{"type":"MultiPolygon","coordinates":[["@@Ȓ΋װ;ʐΡBΝ̹ϳչإїͷ̴З٭Yܗ̓ɣջӋࡗڇϓнʇޝlխˢࣱÐƗ̰Ҍذ੐ࠦժǀ׾͌ܜѰԎѦώظ͈ɆŰҶלϴȆΧ"],["@@،ࢫlָϜɯŲًڰ˛֨ãӒ͎юĭȯݗʯӫٛjɡʭþαūƻͅҏзֹ٭ͯƟɘΕŨӞ۔˟ҨࣛͲz̦؈̌ƚ٨Ÿլͻ֜vƪБΎڋݔΗת̸àҚұٺɑʂݡ"]],"encodeOffsets":[[[177173,-41901]],[[178803,-37024]]]}},{"type":"Feature","id":"OMN","properties":{"name":"Oman"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ֹ̻ϟªǩȧƉэļ֗ÿĻϯFԽ̻ćХȓǯԹP͡ɃJͻПɷҩĂ֗˳ϱ³˝טٿ൴ᠾ࠾֖၂ϩתv͸ʔΐFΆϞǒƩŞèմіHϖֵҸ̧؞ŋӼƳϜӕɨ˧̞ŃCȉ̩ԃƅɽΟˏ"],["@@ʼnƳDž˺ʔ˺ľñā΍"]],"encodeOffsets":[[[60274,21621]],[[57745,26518]]]}},{"type":"Feature","id":"PAK","properties":{"name":"Pakistan"},"geometry":{"type":"Polygon","coordinates":["@@تϻʞ٥൨ͻ߹۷ऩůౣȲЫα̖݁̈֩ڴгܑӟ`׳ࠃࡇՃ࡝࢝ࢡউÚऑࢡռϗĪ٧ҾэǘܝᇛD֓֕؛Ɇʣ؀٭٘໻ǁിeஃŝ̈́ঊொѢéϰГƌw݊ߥφͷԔеѶඨѕࡀŲԈŅǞȂגóદĈ܎ҶӈشCĠɼٞŌ̴ý͢ʀ±ԌΦԖ՘Ɇͥ֊ߜɴ̢•͒мΜĩмȣΤӬμࣘǮ८ĮѐƺӨĦ"],"encodeOffsets":[[76962,38025]]}},{"type":"Feature","id":"PAN","properties":{"name":"Panama"},"geometry":{"type":"Polygon","coordinates":["@@˫ʎǵҒȺɢɅÎƿˤлɸοÁǝ̇ͻɁǽ‡ĉǩВҗɯŅŧŭϷ©ơԈŋƛˡ¸ǝ͸·ÈɓİέCǻĩŶªǖìǠƲŲIJǩŲK͸͘ö̠̝iDZͲ›ĀæɴȵЮÔΨɄԜǞ˺ʤҬ·‹ĉҶ…ώơ˜ʧ̈́ɵĹūȜӵǁʟ˓ÒŅС"],"encodeOffsets":[[-79750,7398]]}},{"type":"Feature","id":"PER","properties":{"name":"Peru"},"geometry":{"type":"Polygon","coordinates":["@@ɥљћɋࡅӘñΈရࡊທࣾ٫԰ΏۜƐʎ܅ાࠣ༄ߍီ΅Ϥ˃ؤٷպױͼ˖ϒПߢʼךڢՎIJΓʇȧx̭ΎâͼĝΚщӆΌDŽ֤ԦܶৠͨࣸࢠʾմŝٔɢĂ֒ЉˎЅϴɏӶࢣضĿҨɞ̤ƣԎð٠Ͻթࡣʤoрҁݳ œųۍlj॥ֱÓϻɉ̇ČғԕʍBΡɛƵΔݳҲԝDZί֐µ͆҃ݐuېӸÇ౧ϢĩӄƠܪടǷ˵£ןg܍͟пƮ̵ȕ˯β۹Ջ࣡"],"encodeOffsets":[[-71260,-18001]]}},{"type":"Feature","id":"PHL","properties":{"name":"Philippines"},"geometry":{"type":"MultiPolygon","coordinates":[["@@Đ֏ºҽ˹ޑ̫ࡨϽэˎإʉϿ঩Ӧɿ؊ʰЎՑЈˁΑЃثҵƑʖ͢۾ՌʀҜ̈́̔ϝٔɰƎϒרv·ٰڼЋêхÐ̱"],["@@̟ˡˁՍ˃ʝԫ׈ǦɤɂɾĢԸҨ¸Ɖ֣جߺāߡ"],["@@ૣߕЬט؈԰Ԏ׊Ѱ࠲Ʈۅևҧѳֿ"],["@@Ԏʹ՘BgΗϳΣՕʧ‡ϸÒєŽА"],["@@ʀभ٫ɞj˭ȶԯЍȋ•עʧªƁԘӶãY͈ԣٜ߮mɴ̻"],["@@ɟܩέоѓ٘ܚ‰̡̈"],["@@ԮʉʶɖüɇƍΑ˼׻ɛۥӷ˥ƁڳȊڝѾġϊIJਾүăҙ˜ȫēϯٻЮ̵Ѵɍ̯՗ԊރůлȆ¨ΎˀɊʣȘŇ̡бӚűμߨͺˡĔೄ˜ހԘA"]],"encodeOffsets":[[[129410,8617]],[[126959,10526]],[[121349,9540]],[[124809,12178]],[[128515,12455]],[[124445,13384]],[[124234,18949]]]}},{"type":"Feature","id":"PNG","properties":{"name":"Papua New Guinea"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ɽčε͔ρՔǷ٘ŜĆĜʡʬȏРՑЈ˵ŝɽ"],["@@ѯçƃɽҟȱћȟѽBۏʔӑɺêʺݬũҠàŶЖŦrĆѽӐÜʂ˼Ҹ̚ġӸԌfǜƏgү˯ԡ"],["@@ݤտղࢻӖ„‘ω٬ƛʥǁࣀΝġʏ֋ÏȷɔܟĦࡕŴٷ՚ӉҦѧ݀ભπ܇ʇԡˣńإڇ˿һƖࢅ–aᩒaᩒภ׃༊ӓׄїҴхŸӵඔԱȲѽޛěȄ֕"],["@@ʿɡǁӸȝ͘ϝ˞ӍΪ؇ʚɺȮҒɻ˸ȁΜȫʹΛ͊ˏĶѧ"]],"encodeOffsets":[[[159622,-6983]],[[155631,-5609]],[[150725,-7565]],[[156816,-4607]]]}},{"type":"Feature","id":"POL","properties":{"name":"Poland"},"geometry":{"type":"Polygon","coordinates":["@@·՜à̂ȹ̧҆̚ɺɤȝђָʘ಼ϴ੒˴࠼ƙÚȱ߸Yਚħ໶^њěȬʵšωɸ͋KͯԋǡʸϳfϏцܻěɽзįރۥɒϗǿ¶ߙ͔؁šЇĒӹǵч̖Ήŕ³¼ϭаر¼ăˀֻĦűɑҗǨÀɴػòЉ˔"],"encodeOffsets":[[15378,52334]]}},{"type":"Feature","id":"PRI","properties":{"name":"Puerto Rico"},"geometry":{"type":"Polygon","coordinates":["@@јõưǕɋɃمLӫ‡·άŢŬیK"],"encodeOffsets":[[-67873,18960]]}},{"type":"Feature","id":"PRK","properties":{"name":"North Korea"},"geometry":{"type":"Polygon","coordinates":["@@Şƥ͉ºη˵ʣ˷Ž׽ѣȅƫƧ̓ʝ֓ƏηɥηįġͰƋӈσŧȭΧÇץ¡͝ϛϑˆÁùСdžĵƿʙé‡ǀɑüɥƆɰφȤİõƶɆҒÅƎөĠЇɤۄբऒҌ־׮Ўˁܪ‹ſѺಚβͰҼժӹ"],"encodeOffsets":[[133776,43413]]}},{"type":"Feature","id":"PRT","properties":{"name":"Portugal"},"geometry":{"type":"Polygon","coordinates":["@@̦Ɉ΄ŬɂЫӺDƞłӪ‡ɼуϱɩYٽƍū‘Їγçʹԋɵտ̄ʡřɫ̵̿ê˥ͷɓѷŠџġŸڂÿԬϓþȩ͈äռͰ̨ÒͼǪԎkΤǙ̠™˲"],"encodeOffsets":[[-9251,42886]]}},{"type":"Feature","id":"PRY","properties":{"name":"Paraguay"},"geometry":{"type":"Polygon","coordinates":["@@ͦ৖tҌЖ݌าʔޮ]޴їbʵʞҳÇଛࢲLJ΄ǐ֦ɩǀʣþޓİ͓̼›̀ƌ̢ƳAҥŕӻǑӛƍݏށ١ړƇऻŸࡑɮࠢ౨ťψࡽ͢ਅبۉŸ໵ൌ"],"encodeOffsets":[[-64189,-22783]]}},{"type":"Feature","id":"QAT","properties":{"name":"Qatar"},"geometry":{"type":"Polygon","coordinates":["@@ÇؔɨѲɰĜʬˁdӯǽӳɵÑʫǖ"],"encodeOffsets":[[52030,25349]]}},{"type":"Feature","id":"ROU","properties":{"name":"Romania"},"geometry":{"type":"Polygon","coordinates":["@@δǶԴġՠGϸȳ˺źبĄɄȠΠ@ʰćʺʟˊΟӞԁ€ρėΩưϥϒƹЂƊϠƟpɏПǹʯĀɻ৥ӳĖ̪ؑফțзɋ௽¬٥ƀ͙ÕʍΊƵƦȚƘȷŀ˃ȋөʔßΌԟȢĥˌҕͤڪǂԖ֮Њ֬ԢǮ"],"encodeOffsets":[[23256,49032]]}},{"type":"Feature","id":"RUS","properties":{"name":"Russia"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ࡌ๫కˤԫ்ࠌࡳyוُԒսٱƻ۸Ĥࠊħ࣢Țٌš૴ӯࠜôରަϮͭϴϐŠɔ։̆ߵuࠟΎࡑ"],["@@໵]ਙĨȒτ୊˚ࢢƧψƃęɱäɉ"],["@@֦Ƚțؐᗸű࿨޻࠭λ൛ēsࠑͳǩ޽~ٗ̊ૣʖȉθ࡟Ǝॗʼnҗ̎Ǽ̸৓ȥϚЃӉΣ@„Ꮪٛᔺ࠳ïԷ"],["@@ः©ƭˌੲΖ@ַ"],["@@ળ»@ָň–܈E௒ʉïŗࡽȩ"],["@@ౡMႣĤƧ¬ߘͪੀþஞ͏ĸə"],["@@ॿͩഉø༛ͨȪ˖༨ųᑔɗ"],["@@ډرᶽzඃȣမղҎ׀૎ǂᕞ™ᴬѽ"],["@@ӹóᩣŊɟώູɦūҒ࡮Ƕ…Ҟသܒޙĺ፨݆ɩϢሤѺ᪪բ᫠ǀ෴̸࿐Ŋאͩ֟ʻᲗз᢭Џᤙߝఫࠍ೉߱Ǡۥྎۏ"],["@@ɨгސȲឤYቈЧڬ̿ȽѧङʝᕅүفʟਬşఖɃݴDŽєաτɔഊƂ᧪ƑȴϽ↲ů´ٜᄼƥഄLബѷϮ՝ӹΙੌڋ೔Ϳ߸ࢦഖϙ෢ɦྼʵؤʀൖş؅ޮૐζ䢀ձܐӿᔲٛ₎DŽာƑ۪΍Ĺؙਜʇ૴Ǥ๰vཚǑཪĢะݛਪˎڷ՞ϐώᧆɻფºᝂБ୲ν@”MKઇσઝÖݶҁԄەϲɧĮΏɑɝ༧Ǿ᚝مݛĭ౽ן௛ԧ̱ϣய׊ᔗڇϣ̸ߵΫ૱Ř˓ց৙߽Šͻड़ȋő௣ޭ‹Ϋ۱Δα฽ѕ̅ॡభȳʥ࡟ே޳ׂ̳έ௬ҵለИ୘܀ԆªϾರȊຊ੒คࡺຢڢڮஆ৷ëԍۗᒉइۍਖᓧ˷ᑃටۚԧሙɕಝēÔ؊ಯŶ਩ЭᢵƠ᪏ʟᨩ࿛ủጝ೚ŁаՃࠄȅ՞оईÃௌऍ†܍ځ࠽ë্ϛഉ్௓˯ׇଙ঑ଇॻթӹ૩ӱՉYՇФૻؙſ˩ŝƦKѐіxŦ঴ɛܚܞ̒৶Ʃ֢ࠈ˾ऄ͚̮Ѵݲ൷ʛܯͧ౧Dͻ߄হװหˎ̵ࠖ̉Ԫ̿βԯࡐ̲݇షʢ૛uਯƱۛлҤȥXҩұˑݷࢻRσஅՍ৙̈́োéѯˮԋĞ௷ףેƑޛȻੑƌޫSԙіࠕИࡅŎ੝ŋߏƹ஛ΜLJـধɎށİवΎࢉࢉ΀ӵࠇב௏ɂ࠻Š֗Ͼ࢙^ܳʴ౫Ѓྃܣࢭơ͡çѽԤઍőΧΦחnjЙӠҩưிɍୃӜ҃ѯሟᒒੵٮ̮˂ᑋߍ߭³êҞઅ˺࢙ȱ˃ࢊມǺݯΑᑅ̳Чȹḭ̇ϫ˻؆ֹ߭ɓǀɭ߭ХസֿɁЉ୻˜ʓʟ੹Ѧ೯iࢻΟহͼᇡ׊ಽsჃࣳĿؗࡹӤڡउʖǡӝُ܊֫ذx՚֗ďѝѐƋϥӽ߿Ƒ࠳ࢁކߕĉ֣ࣼফԇ͹ƝɇωÌֿԚɿ†ՅȚʳΈ޵ǮԙƁƥƼଥЖఅƌ܃ƞĹıੱ܂य़̈́ܩӴؒƈۤ۰ҹͪఌ΄uȀݯƉ‚ώѠɼ߼ÖƄ˪ȅҪ΀ѰWʚఉ˚ӭUԯЀ١ƃ੩̐lǒ̗θڟ¤éʼɀǞ՝ӈࢋąʭ¦Ƀȑ̽”ȷ՞ȟ˨NJĀڴ‡͞Ȁʍɢ֥ƪ¼Ʋ΁ƴՃվǸɨĉЂࠑȨѱijšȼࢭɂˑӸíТЙȖάˊʝ޶װӞųƤक़ҬࢡЎᅢ੶ޮӠ͂єగּΆնݳش֢ܜ঍ग़ޢي౿֔ŬךڶüොͶࢀ̈൦ԕᘨȧṺो٤ЋÆ֓टѳ൏ɡ⏷ٔ؟Ńൌ؛ÂϵÆ࡫ઌʯڂɓňРԑΰ՘͈᎖Թ۾Ȳ֣؜ዦࠖޢµ޸̋Ӫ׀۫ԄЪԊءԶᚠˑӔҹ੡ĻNҳڌ˽ಜǼȶ՚ჶАᰪܞي£ࠣԙਬĕ׼˼༾xఢΐफ़ԏॖ֌ࢡӢѪˤ២ʫ୒ʿᴾॣ֚ѰࡡѺ{ǴৣĈˢЌ҅ټ}ː༄ݾրކزǒᕮɛǬұߕڽԺˋ˒חȏଵऒԧέ֕࿫஝०ŭ̢ͮऎɎɞжܮЎөӌϼֈࣿêȫҲڢࡈણۆຒ֦șװмnѴүͧ߷࣐Ƶϥ؄ඤͦლ¬༈ӏݛ۪ċࣆศǞ፾™ᆘŌہѮংւॲx࿎иᕠŐ˪ɲᕂþیȋሴҀ໲aɶδߤΨጤΈ෸˗ଥȷበŹ"],["@@ⵙ͕ໞીےĦقÃᒈӋʟͿ"],["@@૽ōݱÛśƏঙƑ࣫ȦӐʾል~࿞ƶ౨XǢɧӘȬߊƐఞǿ͗ŷ"],["@@ᆳĿᚉʎඅ͎٣׾଩ǔᔆָᆎȎ࿌чኬ߻ȹݯ"]],"encodeOffsets":[[[147096,51966]],[[23277,55632]],[[-179214,68183]],[[184320,72533]],[[-182982,72595]],[[147051,74970]],[[154350,76887]],[[148569,77377]],[[58917,72418]],[[109538,78822]],[[107598,80187]],[[52364,82481]],[[102339,80775]]]}},{"type":"Feature","id":"RWA","properties":{"name":"Rwanda"},"geometry":{"type":"Polygon","coordinates":["@@ͬӃµӵʏŁѿÆʱӍԛàþҠŘތԄʎɺȰďԈʸ"],"encodeOffsets":[[31150,-1161]]}},{"type":"Feature","id":"ESH","properties":{"name":"Western Sahara"},"geometry":{"type":"Polygon","coordinates":["@@oҊŸ@@ÉeNjEౝ᪁ª‚ᒷ޿÷ȳћDŽ்ᾓNǽ˫˜΢bCቆäĶ̢ΆϘˤୌୠ࣢Ђ੖ˀÖ˜ټۺĜ̦ʼnϢ@˔ȒԲ‚"],"encodeOffsets":[[-9005,27772]]}},{"type":"Feature","id":"SAU","properties":{"name":"Saudi Arabia"},"geometry":{"type":"Polygon","coordinates":["@@ʼnΪʩʨÝͲѡ̞҃۴ʁۆׇ׀ϑƐ֋ߠīא–ӾӕञϿ͠ґǨˡӖ°ȎɹѦʕȊ͝زԟڴѓ־лIžҦœ̌ļͲनƅζʶȪ̢ٚŚƒˮˤƜ࠷ࡀ၆фdžŴৢɩబיᛎၕ༠ãݠąȾЏתv͠ܥаȓƠִ̏Λ¼΍ċ˩ł˯ʎɽŐ˟ŲȵʬǕɶÒdž͍Žș࡙͐ᡌщǞDzϪש֕၁ᠽ࠽ᝑ͑޷ϙ׻ࢥϹƕɁˬ͏§߻ĎƷČॹmɫùΉɔɝЭĒΟρˋ"],"encodeOffsets":[[43807,16741]]}},{"type":"Feature","id":"SDN","properties":{"name":"Sudan"},"geometry":{"type":"Polygon","coordinates":["@@śhdмĵ̀џͨĵ؄ĶبϳÌÍȇԍ©Ȭʕðԍңңл؅џđ۹Ӫͅǥđʓџǃ…ǥ࠵@řǦ؃†̡ƝɳîѝӬƟɲ؃ŗɱϵɏݣ˿ǁʳğå ̅ʎÃʼƌΔE΄ӛՀĩάZȰ̱ʜUӦǭ͖̍µĎ̰ɒΖħΐˢʴǫȞɞ԰ϨئܦÏ¥ ZΚॲH@း@Ὂ@ῼ@˔ࠗȁƳŪࡻ্̰͌ȷҠ̳ыӑأƏ˅ʳĉ֑α௿ĚͳƅܟͿࠟԓзέٛč΃Љɽʝ࢟Dij"],"encodeOffsets":[[34779,9692]]}},{"type":"Feature","id":"SDS","properties":{"name":"South Sudan"},"geometry":{"type":"Polygon","coordinates":["@@Xٽűʯѿq˷ӏԨÑюХƨͳϦșӼࣳ֫օԫԇԫϭסFگȟՕȊ΋ɭ݉֐ȥάҵDZϱÆɣƕϗĸԗۚƉˊعͪɅԌΕζ֟ѬS˘ҡͼ֯͠ʴĠ̀ǂɐݤɲ϶؄ŘƠɱўӫɴí̢ƞ؄…Śǥ࠶@†ǦѠDŽĒʔ͆ǦۺөѠĒм؆ҤҤïԎȫʖԎªÎȈϴËĵاĶ؃ѠͧĶ˿cлŜg"],"encodeOffsets":[[34779,9692]]}},{"type":"Feature","id":"SEN","properties":{"name":"Senegal"},"geometry":{"type":"Polygon","coordinates":["@@΍ٺн̚φDŽРמȦќ˾ːкïШǾҶVДʙ֎ɝԘأֈֽžԹǔӓ̾ɿî͗ʽŧ³қâÙģȃk׿ȲЛV༇–ɥħ˥‚ѻƋƏ٢ވkȬŞƮR̸ȘήǯκcζȌǝʐˡƙʻJͧȸˉ_ȍȥࣵy"],"encodeOffsets":[[-17114,13922]]}},{"type":"Feature","id":"SLB","properties":{"name":"Solomon Islands"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ɾ˿חN͉ԬԈȯǜ‰"],["@@͝mԧĎǫżÀͮֈƁ˜ǭƎə"],["@@ųƹحܰǫԈ˺@̠ڥʹЗ"],["@@–ǛڅΦҟ̠̿˪ŰĐϮȫېϭȢˉ"],["@@Ǘ³οȒ·Ί¨ƖԈΡͰ˛"]],"encodeOffsets":[[[166010,-10734]],[[164713,-10109]],[[165561,-9830]],[[163713,-8537]],[[161320,-7524]]]}},{"type":"Feature","id":"SLE","properties":{"name":"Sierra Leone"},"geometry":{"type":"Polygon","coordinates":["@@ɧØ؁ͺѩ҈Ƨ̬Ĺت҆τĬɺƞǸɶpȜǂڦCɺ̛ǼˁʓƈɗṶɴ´ϹϹϛҗ«ʓȩˏ"],"encodeOffsets":[[-11713,6949]]}},{"type":"Feature","id":"SLV","properties":{"name":"El Salvador"},"geometry":{"type":"Polygon","coordinates":["@@ġȡӡ^̡Ą΍ǘұÀʃǶ~Ů˾ɄǀĢ«IJȠ¾ʜëǸǙʪƇŒœτĴǤÑŘĝÏͳ"],"encodeOffsets":[[-89900,13706]]}},{"type":"Feature","id":"-99","properties":{"name":"Somaliland"},"geometry":{"type":"Polygon","coordinates":["@@ϛԩד۫۹Mᩧা͍̜̳К̳ҨǾ̖̲҈˚ƹǒΏϜΗкGߊɌࣴĴ݌ʼиÆ̚ƶӎˆKaE΋Aࡑ@ѫ"],"encodeOffsets":[[50113,9679]]}},{"type":"Feature","id":"SOM","properties":{"name":"Somalia"},"geometry":{"type":"Polygon","coordinates":["@@ѼĎЊ˾͈FpɵýӧHѳǯ̣ʁࣥЙयԱ੷ܝ௷ܓवধ଩ࡁڹష࠯޳ٕँৱȗѷȍȣӽۚWᵤܾ॒ɰˆբfݠפબšᛜᡄה۬ϜԪ@ѬBࡒFΌLbːhϰŰ"],"encodeOffsets":[[50923,11857]]}},{"type":"Feature","id":"SRB","properties":{"name":"Republic of Serbia"},"geometry":{"type":"Polygon","coordinates":["@@Ԡȡà΋Ӫʓ˄ȌȸĿșƗƶƥȷȏø̫Тγ͋ʿƗˋĞijƑšϳa˹µƒØĴĴĦȴšKǍƼƑ ŋƆƽÀšŠƯ±ś˧ȩÑèð͋Ǩ˟ĜūŜɟƠȢšŬЄЛ͔ɀτ̥Ë͔́ˉʈȱ͘٢ɚԾ™ҖͣĦˋ"],"encodeOffsets":[[21376,46507]]}},{"type":"Feature","id":"SUR","properties":{"name":"Suriname"},"geometry":{"type":"Polygon","coordinates":["@@৔ǙĞưڶÔࣚɥѩܟâֹͤӽƥίóϩɉΛӓDzЇđ͹öčʏƘǗ÷ǡҙèԡܴōӄˏBωؐƺѠ¯ȤԜɖƈݲ"],"encodeOffsets":[[-58518,6117]]}},{"type":"Feature","id":"SVK","properties":{"name":"Slovakia"},"geometry":{"type":"Polygon","coordinates":["@@´»ΊŖш̕ӺǶЈđ؂Ţߚ͓ɷɓǏ͹dzđ࣑ʮ˟»ȟȡЁĿěÄХŽͭ}ãǙ۷Ļ̱ĠёɌċ̆äńŢȂόa˺ĔxþLj¢ÆȒȖ˜žưʢD"],"encodeOffsets":[[19306,50685]]}},{"type":"Feature","id":"SVN","properties":{"name":"Slovenia"},"geometry":{"type":"Polygon","coordinates":["@@ۜÝъȐܾtLjƘƘUǎ˳ڝɟć͹̇đHɻͣh˷ƎƷƙב†ȈúȫΨĞа"],"encodeOffsets":[[14138,47626]]}},{"type":"Feature","id":"SWE","properties":{"name":"Sweden"},"geometry":{"type":"Polygon","coordinates":["@@ࠁוƀԥ೹ڭྱܡؓஃײףߦүޗॅ࢑ȝ͍තӋ޿৳ĆӅڗঃˉߐ۳॔ٓஐφӜּۨ˦ন՝ю½ૠղ߀࠰ä̧ͬ˺ಬஂࡀञֈײ߮GɞҶཔƉŬքԸ”૪Щ಼ֱv಑˴͛ฃʃ"],"encodeOffsets":[[22716,67302]]}},{"type":"Feature","id":"SWZ","properties":{"name":"Swaziland"},"geometry":{"type":"Polygon","coordinates":["@@ǡύӭěԅҖS̄ɰ̀ĂʔʐÒшƵŰϕðω"],"encodeOffsets":[[32842,-27375]]}},{"type":"Feature","id":"SYR","properties":{"name":"Syria"},"geometry":{"type":"Polygon","coordinates":["@@࿩ࣅऩͬgNŖŶ_ΈȸҠҜ̈́Əͤϗ¨ÿٞȶΌɤȀɤȀ°Ҹ˞Ǐऎɺ҂ƿۖFॴ̀Ґaक़žїԽҡȹĂؗͅ৫ᇵ࢓"],"encodeOffsets":[[39724,34180]]}},{"type":"Feature","id":"TCD","properties":{"name":"Chad"},"geometry":{"type":"Polygon","coordinates":["@@ĎЄաnDզΓ̶δ૊ੴߌ¬ન͖ၼǼΰΓ˾_ˌ̽ɔȷರࡔҠ…ྑ…ྏ¦ ܥÐϧإɝԯǬȝˡʳĨΏɑΕč̯̎¶Ǯ͕Vӥ̲ʛYȯՏƛэͽ؉ࣹ߅ϳ߹¾ʁûĊ̏ѫ̋Σ͟੓͏ȽȐƓhƹɍۛÙƀɪ˅ׄşΐλƜӷӪǼІϦċʂÐҸSқކŒ֐É֐ͭՠ"],"encodeOffsets":[[14844,13169]]}},{"type":"Feature","id":"TGO","properties":{"name":"Togo"},"geometry":{"type":"Polygon","coordinates":["@@ڱdzȇ̎ɡՔãкȆݴɁ̬ăڎD؎ΕѠÖˀ݂kŅѵʲʝ̈̋ŽЭǜǥኝȺׅ"],"encodeOffsets":[[1911,6290]]}},{"type":"Feature","id":"THA","properties":{"name":"Thailand"},"geometry":{"type":"Polygon","coordinates":["@@ݭϬܗeŬڈ݉Káऋґ௯˙ݏÌ؋ն΀ދưܭҶӓԚĭѤѧ˝·ևĵßќۇςƣƭͧ͒ƝжҁӄПЌƏӳǃҲĠԾʚ߬ТࡸҤ޶͟ތ`϶ĩҸ֕ښȩф̄ƺ̮ܶ·ֆՓؘН݆ΠƴϦࣦצœӬθӔȘθʷ´ԍ֨ȷࢭpݫࢰԆʤƧӰzǜَ̊ÍٖڽÀࠥںܷ›܅˙ϛ޿ŦગDž՟ۧȤ১"],"encodeOffsets":[[105047,12480]]}},{"type":"Feature","id":"TJK","properties":{"name":"Tajikistan"},"geometry":{"type":"Polygon","coordinates":["@@̭ʷࣳƖāӛ࣬Þਢ˗འŶɈާˠĐԜȓ‡͛ŴӍࡿBׁØԻϕύĉ̉ǯͩˠþ۸ʩ¢ĞʲғȐα̇ė͹Żūԇj˕ϩ˯nj؋ˑʱĺӀࡘǹض؟ȨɔφۮŸЌҬˌբ૲ȜǩϵŤɹΎv"],"encodeOffsets":[[72719,41211]]}},{"type":"Feature","id":"TKM","properties":{"name":"Turkmenistan"},"geometry":{"type":"Polygon","coordinates":["@@ñۼطŠॣݔڣĠगюׯþσƽ֙|ׯӓ݇NjƻרŪ࢞ٽ˶Ɏֺ֏¸Ȇ۾ߊȵ݈ˎؓԎʉӔڱɋď؛ʿհψ˨ॖǪ֨ɻךڅњ¤ॆ\\Əцܖ̂۾ӦଆѹĜڡ͐ǣࣦžˮƳаࡽ०ׇոЃ࢞Щ૤Ϋwԥʩ€Ѕɤſ̙۽NjǙڥӁʭڏŵǫϟهŏࡩ͈"],"encodeOffsets":[[62680,36506]]}},{"type":"Feature","id":"TLS","properties":{"name":"East Timor"},"geometry":{"type":"Polygon","coordinates":["@@IJȤܢȌז†ˀŀ͆Ľ̯ɫ࢕ο۳ʋeʬďǔ"],"encodeOffsets":[[127968,-9106]]}},{"type":"Feature","id":"TTO","properties":{"name":"Trinidad and Tobago"},"geometry":{"type":"Polygon","coordinates":["@@ӚŊǮ‡‘صۭġƯúʒɲiͪ"],"encodeOffsets":[[-63160,11019]]}},{"type":"Feature","id":"TUN","properties":{"name":"Tunisia"},"geometry":{"type":"Polygon","coordinates":["@@ΩພԭͺQȰۉԄóنԮҶȢۚƃߠǠќࣶͺךĵ}ы܊̲ÒljпЫMϱ̆ȽōܫփхDŽқѤaɄЍ͊ſ³٥Хʋʵˏֽ͓ĘΑïΟЧț"],"encodeOffsets":[[9710,31035]]}},{"type":"Feature","id":"TUR","properties":{"name":"Turkey"},"geometry":{"type":"MultiPolygon","coordinates":[["@@஺͗ঐżܤõলѬࣆ¢ߴЭƜ̑ăУزȻͨʕֻʇˀ५ǏʻҠڧЕƙ̏Ɋ঍ňίŽॗŽҏbॳ̿ەEҁǀऍɹ˝ǐ¯ҷɣǿɣǿ̱Ϡ͈͂ԟí۱ȖֿәౣĥڹҊࣟ†ȗΑׇij߻҄ࣻeӽ࠶ؗҰЦٸՓВठߨಒ’Μྀٔŏ৞հ঒ʄർlุף"],["@@۫ҏ˃Ϻ\\ǦȦĦʺՂХɞࡦ˄ܤőĴ͓ܼ˓Ƶȵি±Ωʷ"]],"encodeOffsets":[[[37800,42328]],[[27845,41668]]]}},{"type":"Feature","id":"TZA","properties":{"name":"United Republic of Tanzania"},"geometry":{"type":"Polygon","coordinates":["@@ƚġᵂႋÌӣ஼࠿ϱਙ¸Ӊՠ̩~ɓɳԓ¶ʭÇГ̌Ճΐ̰ࠡǿڝӣࣿ͛ԋb̙ʥבsɕŃঢ়ʂكåɽଢ˵ϺǛɶࠗƾӉʨՕƘͯƘΗɈґ੖ӣҺǗӤČѨƯޞΎ ̨̦͜ѬȺǮS˘ǷȐ·ͨʐł¶Ӷͫӄ̎Ķऄ[ႎà"],"encodeOffsets":[[34718,-972]]}},{"type":"Feature","id":"UGA","properties":{"name":"Uganda"},"geometry":{"type":"Polygon","coordinates":["@@ः\\̍ĵԇʷȯĐPوȜ͎²ڬǰϸ͎Ѭ͔ɠ˒̘͵Ŗ¼চΌɮՖȉڰȠעEԬϮЊ׍İсτ९̧ؓЯ֋ʉͽTࢹႍß"],"encodeOffsets":[[32631,-1052]]}},{"type":"Feature","id":"UKR","properties":{"name":"Ukraine"},"geometry":{"type":"Polygon","coordinates":["@@̾“ɄȒʮ¥ࢌĆ՞Ӈȿǝêʻڠ£̘ηkǑ੪̏٢Ƅ԰ϿӮVఊ˙XʙͿѯȆҩƃ˩߻Õџɻύڡã֑˕޽«ܣ̻¸ԹЪȭࡨ¼Ǐ̛ँơଛӟұǠȄЂࣽʘƨLjߪ˪ʑȔಯɆË̼ީĻ̷ҧٱةϟƠЁƉϑƺɂĞƦ˾ɲˎÑƮǬäĊśӸ{ɞØƽĎÐŲ̉ɈŧΘ̩ƐÒ˶ϝɦΉŽأʾ֑ĉȧŭΟ@Ƀȟاă˹ŹϷȴ՟HԳĢγǵÍɤұɮǐͺɸɔȀµɑϘބۦиİĜɾхܼДҢɪٲnࡖßबȫڎi͂ŧ̀Ʀɚȝݸ¢ͮąÄцʶȂܞº"],"encodeOffsets":[[32549,53353]]}},{"type":"Feature","id":"URY","properties":{"name":"Uruguay"},"geometry":{"type":"Polygon","coordinates":["@@ղĚࡆٯ̺|ࡺ՟ڈҫӠֱχЉɸӇεՇॉұاǚғěޥΰ֫ԟҬÞլǾȈS࠸ɤࡺȾڦ"],"encodeOffsets":[[-59008,-30941]]}},{"type":"Feature","id":"USA","properties":{"name":"United States of America"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ũƕȽŤ|ɾƓ̨¦ĤƤƎÍǔ¸þÜe͐ƙƬñƌőɊ̍q¯͟ǵˏſ"],["@@˭ÑƟǮīèQÀĈî̘āɘŹëĵ"],["@@ĝ҉|Úĸа•"],["@@­µÓŻˆŃȒ’ɤŚêÃʐ˥"],["@@ıĉ˱ƴªÖŸĈȘijȝ"],["@@Ƭңʼƛז½࡬ƅࠂʹڼŊਖɓ˞Tݨʄ߂̧ࠒ͗ں˩ٶˏĈəȢĉ½ĉɦǎĔ¦ȣǜƅɴ@ŬĹĽƫ࢖ЁǶށǚܳʗӹЁҥȁ̍mēĦť˸Ɓɂ@ঊ҆ࡾƀસмfĐ÷ʰƉǒϜƆࠜHޘAˎ͞ŀàࢶ؄ϜƸ౦N໾BĎȺː¦Φž̖Ϣʲٺٚي˨ə֜ƜώʏAଧռӅƢ˝࣋Пࡷ̃ࢱʝѻӿƛȋSѽˤѽΒsė̬ʦȇãʇ֥ƋЗhةƥλ¥ӥ¥۫ʏఀǂʠǃ୳ʥ՗C|ĺʭɷʚǹ׽ؑ٧×Ɏȁª˟ɀǪҍȼƭ^ͅˏ͛ҿڡûʺֲѕ͎įۦljεǴՑևƀׂ˓˜ߛʊÍĖ̃ŠࡁՕدࢇʝցӱнÁэ̱ţ˭इձӁЍЅӽŻׯƪ׍ˬܗώשLεЊঅ֥—͛ȿԡʣŃЯĺƁς͋ȖѻܢϹٞű͢Ǥ֐ɽҦٻ۲͟źࡑϡƭ¦СϼՃȺोŁݗĤٙÍΏſƲɟaͽǴǓLJō̵Ů́ǃ؍€طѺܻĿ؏ȚԹÏۻȝއح࠳γҝБȕϗUׅ¨ЕDŽ˹͝{׭ȂٽʺɽЄȁטӷӐ̃ӰуֺףͲۉgՉڑۣʦѡʪȽҦ˧Ѯӿτїˈ̩̖ป@C΋ڗ@ဩOቿפ౓ТĀǒ੩ĝॕÝƙіխӚϻĴğʌһ¦̝ɪޭĊɉƌĹҢࠁࡊ۩ୠˆȚχˤٯ۴řۆ҃ҞȀۢ…ܜˍ٢͠ߊĸނĺނƱૼˇܘʓ϶ĸǐ௒˷҂ߋȺɜƇې˷ێᛸ@᠂@ࠜ@ᢢ@៚@ᡀ@ᡄ@᭰@ᮞBაAF͔˴J"],["@@࠽͋ѕɐŽЀބ̘҆Ÿ֐ÉΤʻܫЍ"],["@@ԧŽսƾԛɮࠦƞښùĂ͑"],["@@԰DžԾĒڸɛ࠲őéĝُDZٕǾ͋Ʋݍµȧôº̈́"],["@@؊ϛώnjහ»¹ȕ౾ƛࡨČᄚ˅ྤā٨ʼn૦Ǝౢʧࣲŝ@@MᷱIⷍࠠ{ࠌɵהρݜցࠈҺࡈ˖Ҁѡ֤·ޒϙՂ׽࡮य़ේ՗xՋұЙҥ͂ݍˌʃܺએںҍߎ߯Ä೷rটʌ჉ࢎߩDŽ฽̜୑í࿻ϬৃΨटǯǦ׏ҫÁঁǫ݉˱झdzťӶϚࠚࣀʶɱɂੱҵֵ֑௅ױؚСߏ׿ࣗΗࡁʱȻωಽѡ˅ϿছΫֽÞ޷ɻ࡝˹ۧ˫෹ʉſƘऀϾࠔʸࣆҠਬĨвΈ୘ԊȈǚب̒ƢْђӸॹʫ˓Ơҕ̧շюɧ̝̽м࠿ͳԩBïԄƲ̮ե̚થLJ܁ЀַȬIӈ٩Ϊ͘ӘۆҸ̚њںÖ־ƇڴМ؎ï٘ʼƻϨҹưج͖ԩWࢻǽʯȃڏȄஏĥ௷ȬΛ͸੟Ӧ୾ΘመШ۔@ŕнᄢŽڽԶਕ͌ױр߫ΨଽˈҺѲ๰‚ਗ਼ϦȨФ࡬ЎࠊĪཪώޜÉಐ҄ౚǭ"]],"encodeOffsets":[[[-159275,19542]],[[-159825,21140]],[[-160520,21686]],[[-161436,21834]],[[-163169,22510]],[[-97093,50575]],[[-156678,58487]],[[-169553,61348]],[[-175853,65314]],[[-158789,72856]]]}},{"type":"Feature","id":"UZB","properties":{"name":"Uzbekistan"},"geometry":{"type":"Polygon","coordinates":["@@xԦૣά࢝ЪշЄ॥׈Яࡾ˭ƴࣥ͏ǤěڢଅѺ۽ӥܕ́Ɛхॅ[ᶾᓘӺƾïದ׻یͅߤݵঢŪ෸à৔ؗÙࡅЦMǢۍ੬ɲЉ̺Lπ׺૎הӖƺʠĉ۵խئ́ײȾ়ѷ੽؁ٕĊ΍uţɺǪ϶૱țˋաЋҫۭ ɓυؠȧǺصҿࡗهǰҳN"],"encodeOffsets":[[68116,38260]]}},{"type":"Feature","id":"VEN","properties":{"name":"Venezuela"},"geometry":{"type":"Polygon","coordinates":["@@yȣӱĭ˜ϡYѭυӥ͆ڙδÆȌ؈ʻ̒§َਸ਼΀řІ̎ˆ̞ןל_մҵ˧ݮQ࣌ĔӖϕٞĻҼʾXɄਨ¼৖\\܉ʛ˼Їڦ×ِЯƆڧѬn͢ȣڕӱó̫˾̷ȽƽԫƉjϱɫɱّ֪Őʁ̭͍ऱ̽׿Žʏȣڛɀثņƿýϔɑ‘֝ŜՉ܆ï°ǭ׷ʅĭΣΉƏسȝNjʱٷÅҧѼʯ࠺ɟ̧̌Ȅюм…ȊʅʠǛ֒à׼Ȉ˰ƲҎ̓Ơӏĩ؁®ͻęסܢӥńઉăȧ̊ȷê‡ǬĴ̶áͺȃȂŅϮѡÈɸӮĺ׶ʔ̸͘ʌɈрդƖ"],"encodeOffsets":[[-73043,12059]]}},{"type":"Feature","id":"VNM","properties":{"name":"Vietnam"},"geometry":{"type":"Polygon","coordinates":["@@૭ܗ۫ߍȁ׍٠ࢭ޺ળނԱԞګϪ།ŕ๓۫փ१եۇ۫਷ޱ̧ՠʀ֬دӌܬ͸ࢦÔσԚප٨ļ৖ț֖ƶࡀɃצٍאՋ݌ۥ঴৓Ԋʊ̠՞ɘ͙ܺਙPϕކӭڐҊȴڢIࠈĬܒ҄К̿ސƵƃӛАͿࡎɓ"],"encodeOffsets":[[110644,22070]]}},{"type":"Feature","id":"VUT","properties":{"name":"Vanuatu"},"geometry":{"type":"MultiPolygon","coordinates":[["@@ˣō˭ςŒɤՆӗ"],["@@ƌڱɥŀǩ­ťɴi٢Дʵ"]],"encodeOffsets":[[[171874,-16861]],[[171119,-15292]]]}},{"type":"Feature","id":"PSE","properties":{"name":"West Bank"},"geometry":{"type":"Polygon","coordinates":["@@@ԣŭʙЃŕ˜ɜɌŚɁĦǬ̤֔ś"],"encodeOffsets":[[36399,33172]]}},{"type":"Feature","id":"YEM","properties":{"name":"Yemen"},"geometry":{"type":"Polygon","coordinates":["@@؉ɥNjύo˹࠷Οഇϻݩףυ±ʥºӭΑ՗lj۷©ɃµǿɛəÕŻɇеlˍœ׉¨ɓӬzҠƍʜǑتʋΊǚ¤đϨĸNJ™ξςˌđΠɞЮΊɓɬúॺnƸċ߼č͐¨ɂ˫ϺƖ׼ࢦ޸Ϛᝒ͒ڀ൳˞ח"],"encodeOffsets":[[54384,17051]]}},{"type":"Feature","id":"ZAF","properties":{"name":"South Africa"},"geometry":{"type":"Polygon","coordinates":["@@ǏŧΣяɻћӇ׻ोࢁףԋًϣ࢛͙ѓ«ŇɷԛŰеDž࣫NJԙĹΏ¬ࡿͩܓƃԱͅϡoΣ̚˳fαϒŸśŏɦLӰ˙֞˔ƴs٤ս޼х܈AF׽તДдͪɯƘΫϘÓՈǃҌÖݤіB᷌ɨűӾߙûԟȈ̏׼ĒрϒЊʨȶДЦȚΠķВɽۂ£՞ȜĐʾƨДҚäʨ͂˪֔ݮغஒؤ΂UОƛ˲Ķ҂ċД஁ɔׯƫऩî̟чƶʏÑāʓɯ̿T̃ԆҕӮĜǢώْQȿؑıۥɑϛֵщ","@@νʶϻǟҕ҃͡Տـ٧̜ČƺˎҴƀƜ˜ʴФ̅ʪ"],"encodeOffsets":[[32278,-29959],[29674,-29650]]}},{"type":"Feature","id":"ZMB","properties":{"name":"Zambia"},"geometry":{"type":"Polygon","coordinates":["@@ІϏɊ܋ƝɩǙڻLjۡ˃̇ʭޭѶɓᢇۗĂׯٍřӍͯĹ̛̅ßܵۓҭխ˳o˗ĬऱĠƯÚOêͧȎկ¶ۋȑչԾ֣یžᦶშYí̂Ű̀ƧЀĪТėʺ̂q¶ʽϾrՖûˬϡڨŝԤˆȌѯ٠ş̴ΧΈҥ٠Që࣠ɱƳח͞ɧƬļࡈƬসȉψʈ՚ɤĶ଀ƚͦđΘɇͰƗՖƗӊʧ"],"encodeOffsets":[[33546,-9452]]}},{"type":"Feature","id":"ZWE","properties":{"name":"Zimbabwe"},"geometry":{"type":"Polygon","coordinates":["@@ҁČ˱ĵНƜ΁VՙϞٯźʙՒC̒έĞ्ई˃ӢǛƮ͓ڤलğ˘ī˴pҮծܶ۔̜àĺ̆ӎͰَŚÆ̻۬hϴǯǺȻАÓѦˑF੟Ǐ׋—عƊʝħӵŵùɛ؅ࢫ॓"],"encodeOffsets":[[31941,-22785]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/xiang_gang_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"8100","properties":{"name":"香港","cp":[114.2784,22.3057],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@™@}ScTʟ@cWuJÁ–]„l¦RLj¼BĄà˜ ŽH@TOHCTDDDHDNAT@PEHDDNJLX@BABALHFF@DKHADBBLDHHFBLEJB@GDBBFBADDB@@KFAFBBJJA@BB@@FFDDADFF@FADDDBJC@AFBD@@DDD@DAA@D@DB@DHHBFJBBFEHDFAN@DGDC@DLCBDDCFDlAFBFCBEF@BC@GDAB@FD@DZJ‚X´HĐMja@Ý`p_PCZ@lLnRGSDMFK|a\\Y}­ƒ§™Mën"],"encodeOffsets":[[117078,22678]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/xin_jiang_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"6528","properties":{"name":"巴音郭楞蒙古自治州","cp":[88.1653,39.6002],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@˜@ÈÒĊanwŎV„™Ȯ¦ͪŃĢ„ÜōȂçČéƐżLɆóĊ‚ĊaʊŁ±¯²Um»ˌmÈ»V™ʠţWÑůǓ郙ôƑƒğÆīŎī@Ƿ™wô™˺LÞ¯ƨVǪуšĢ™ȘV°wĢŽôk°¯ƒ»΀@Ȃ»ĸŽǔ@΀ƒ͔ôôLɆó̐ÝɜLɲōͪƒƨóŤK@ī@IU܃ÛmȻţǩÝ˹ÛljťǓǫō@Ɲ²¯VçōKͿŁΗÇţ»ƽ™ɅƑLÓŏÅÅɱV@ÝĊU¯ÑĊĭÞLšÞŎJ±̃XȣˌōlƒUÈ¯ŎKÆƅ°™XÑܱnŗġV¯™óaUƒƧUōŁ„Ñ™±„çɲ¥lĉkğ°ƒk¥˜ƒnğţL¯ÝÝUƽĬ΁lķ°@„ō„XÿݯV»ŹLʉÞɱŤĉó°ÝJ™¦ÝKÝ£ţܙÈĉ@ƒxǩUċƑ@ky͓¹™`U²ĉVġ»ğa¯¥ť@ĉ™‚ó@ŻÛÛJƒw¯nó¯ġWƽʩķÝɛwĉĕݼȭÞķō@ó£Å΀ƑŽ¯ôȯÞ¯Ȱ™ÆōèĉXǼó@ݚnºƒĸ„ÞVƜĸȚUʶõˀĵĖɱŎÝĖVࢰӒѢ°˘nϚVˌ™ÈmɼĵŦW¤öʊõʔ@°ÈXVŽ™ènŎȁb¯ǫĉ„±Èğ`ġwōÔğ»mVVŽ„Ý¥ó@™ĸķô@ššbX„ĶmV²²`Þ_˜˜ɴbͪÈ°„ÞWĸÈŌmބškɲŽÈUÆ»n¼ǬVķĸźô¯°n¦ɄǜÈ"],"encodeOffsets":[[86986,44534]]}},{"type":"Feature","id":"6532","properties":{"name":"和田地区","cp":[81.167,36.9855],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@ƨ¥šèź٨ΘƑᩄbUࢯÞĕɲōĶĕöʿVʵķșUƛƒÝ„ķm¹Þ™ô@È»ĊWŎçšÅ°ȯȰÝ°óƒÆͿĉ»̽çnƒmɱĵƧºóU™™ƽ@±wóL¯°̻L±Æ¯Vƴķb¯VÇ¥ğ²Ǖbk¥ÇKlÅɱġ@у™óK@™ÇaÝXğţxĉČǫķê¯K@уaŹ„ƑKƒ¼¯Vóaónġw™óÞéU™ġbóĉğÇl¹™aUóğKW„Vůn›ÇŋƑ›ķnʇ»óxĉw™çÇ°Åw™°ċ„XŽ™„ób±ƒkÈÇJ—ƒm²ţx@ÒݎšŦǺn„ó¼n°ÇbUÒ±¼XĸĠłƽXmwĉºƒzÈÜmnxmx²ĖmҚbnŽƧêUºĊêÆVóĖóUĉ¼ÅĬƑ°ɆƆŻŚlłÞLš¼nĠƒ¼@ޙšÞź@ŎÞ°VšɄɴжϼِ͈Ŏ„"],"encodeOffsets":[[81293,39764]]}},{"type":"Feature","id":"6522","properties":{"name":"哈密地区","cp":[93.7793,42.9236],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@WnŐÆĶLĢ¦ţºź„lxÅĸƽŚ‚Ʉ—Į˜è@ô²ÞUĔƐńV°¯ĸX¦Ɛm̐bƒ»Ɇa΀šĢ™ƐLˤ™ȘÑnƒІljĸÿn¯ĶaŎ¯ĢĕȘ¯°΂œla¯¥™ǕǔwˤӱlťО̻nŻmɃĕċţUw°WUóƨÅţķ°ýV±óÅǓéʉ¯ƽŁƒéōǖȁÝƏůǕw˹ǫȗǓƧǕVý™é@ĬţLƧôͩ„ɱŎɛK̏ÞɅôóK@²@°ōؚ¼lŦ¯ŰóƜÛlV¼ķ¼ƒ°kȰ™Ű„ĠƒǬ™ŚÝŎmĖ`@ÇÜn„"],"encodeOffsets":[[93387,44539]]}},{"type":"Feature","id":"6529","properties":{"name":"阿克苏地区","cp":[82.9797,41.0229],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@VƚxˌŎÞŎƒ°n„ȂÒ°²VĊ¯VğƾˍǬƨÞÞKÈÞĊVźôɆÞĢèŌôWČ²ŤVÞĸʶbl‚¯ôn_VÆĸlmÞnVź_ĸ¼Ȯmǖ„šéĸW°°„ĸJ„kʠ¼Æw°¤ÈƒlxɆzČºĶI²ÆǔUš°ô@Þ¦‚ƒUnUĠ¼ŎÓĢxĠ_²ÇĊƒǬ°ŽȂamōšçUÇW@¯öʓõʉX£ĶťnɻšÇUˋmϙ¯˗ӑѡᩃaΗƒœɜ°xWƴUxɃÒˣ¤Ʌwğ„ʉōóÝŹ±°ȗ@¯„ƃ²¼","@@ō™гwȁ¥Ƨ°ŹÑķV™¼ÞêĊ»‚lĵšm¦ÅW@ĀôÈźaɜxÈbÞÆĶIОŘnIÇŃÛÝĊÑĠƏ"],"encodeOffsets":[[80022,41294],[83914,41474]]}},{"type":"Feature","id":"6543","properties":{"name":"阿勒泰地区","cp":[88.2971,47.0929],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ɲˣĊIÈ¥‚ÅU±Ċýkō°ƒĉƽó»ĶƽXóʵʵ™ȯƑÅȁɅ¯ĉ@ÇሗK֛@@ˤV֜ʵрƒǬVĸƑŎ@ƆϯÑóŽķ@ʇ»ķ¦έmlÈĸĊX¼WźÛÞÝѸ‚ĢČþ„ĀĊôάVö¼ĊUƨ°°èŎČUÜƐóôVôôŽ²êȘlˌç°`n²ǬŽĊaš™ƒÛ°±kğmm»š@°ÝɆÛÅÇVaݍVm͔ğôÝÈb‚„@„ƒ™n¯š™ÜUĢÑĊ@źīżWŤÈǖWôŁÆI²ÓƨL@ŽĊX„mmÑÆ»ȰÑkƒĶō@ý°m—¯"],"encodeOffsets":[[92656,48460]]}},{"type":"Feature","id":"6531","properties":{"name":"喀什地区","cp":[77.168,37.8534],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@Č@°ƒĠ„ôÓô@Ŏĉ@Ƴĸ@Ť£ĢlVôWVóřXĉŤêÞ@ƐÒĢÑlèÈV@šĠIk°ÆŘ@ÈÈĀ@ǶťÒğ@š„@ÒĉlŻ_@šƧĖÅĬōÆ@bźÞnƒƒlVœÝĬšWƼʇ„ƒÝÅ@ÇÅÈwWóĉ±ğz‚ĬČƨƂÝIĉݯbÇÑĉƒ¯ʈV°xUŰĊ¤ƪ_ôÓɚI@lȚXȮ™ŎlɴȘ՘š„¦ɲÆʈ_ɴŽźŽôÞʊŎĠƒɆxˤ£ɄÑVwXƳ¯w›ɛŹ٧™çƧ¦ōƒُ͇еϻɃɳU™Ý¯@ōÝŹš™@݄»mğ™»ÝKkŁżřɅƅƒ¯ÆīĊ»ôVôĕÅUĉéV¹ƨém™anѱĕnwmwnÇۄyĉ¹ŹlŏkĵèķmōÞġKñÔċKÅèĉzƒŽ„ômxȗÿƿI@þÅČÝKÝ°@¼ÈVºš@ÅĢšÆUċłn„ÝÆǕČĵJm£ÝJ¦@ĊƒxV°ƏLċ¼ǩ™@™m@ÅĢómÇÆğ¹Çš™ÆšĖÞKšx„wô¦ÆÑÆL²ÆƾŽU„Ž±ŚÅŻĖ@ĬŤÈñ„@ǔÇx„Èǃ","@@VÇ™ţ°ğUĠ¯mk¯ó¥ķIġÿƏbƒ„ĉa±ÒĸĀlKU„_m»nwšŽ„m@ÈŤ¦ĉbÞ°±Þżł̦°ĢŁVé"],"encodeOffsets":[[76624,39196],[81507,40877]]}},{"type":"Feature","id":"6542","properties":{"name":"塔城地区","cp":[86.6272,45.8514],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ήnĸ¥ʈ¼ĸ@ôϰÒ@ƅƒōUķƑǫʶпU֛܃LګK@΋ĸ@Æ£ÞġÅĠċšLV݄»™@Å»Ýnm¯š»nŻĊ@nķŃ@¯ómóÛÝǟ¯aÝóȭ¥ƒšōUmxĉbÇї@›bUº¯X¯ÆƧbVÒĉnǕw¯°ƑŽV„—ŽÇ@kx±Uƒšɱn™ŽÅKƒ„¯ƒĠǠU°ɜL@°ƒxnĬ‚ĀŋŎÇLƒŽğšϱÞέƜkôÅĀǕłƒĸĊŤUŰĢ°„¦ȂϰÜɨ°x@°żǠÆƈČVĠ»ČL°ÇšbĊÑ̐óÞlĶwބɆVÞwǬxǪţȼÜLŐĶˢ@","@@óKĵĀV͈ĉłƾNJÆŤƒzXl°ƒÆL²¼źŽôÈĢǔ™¦l„ô°ɜÞʊĠğŃm»ʵƳƑʝȗīV¥¯ĉ°Ñ@ŃÅI™»ĉmğn™ƒašƒċƨbš™Vğ—w›ġ¯@Uōa™ĉÝJğÑÆŎkŎÞĀlźƒ¦"],"encodeOffsets":[[87593,48184],[86884,45760]]}},{"type":"Feature","id":"6523","properties":{"name":"昌吉回族自治州","cp":[89.6814,44.4507],"childNum":7},"geometry":{"type":"MultiPolygon","coordinates":[["@@መL@È°ĊȂɆƒÆĊ£„ťôWÓɆbĢÅŎƒÆ¦ČÑW¥°ķU¯ƏŃVē±Ý@ó—ç˜ĭɃƾřÆķkwŹƒŤ¹ġ¥ĵKŏÅXmˍщwǓ¤Ƒ@wóōVķ£ɱšġôÛa±Òȁ„óèţIVŽƽ¼k¤ó¹ġJmx—»ÝUƒ²™@ÅƃĸǫŎ„ĊmŎǬ՘"],["@@Þô°bÞǠôÜôn@°ĸń˜Ƕkłƒ¼UޙKğȂÆÝĢŤķ@@ΌڬL܄K@ˣȂ˭lĉńW¥ĵVÆý@ŃÞēUŃȗƅ@ŹƩǕĉ»k»Ç™VğóřX™ŻKƏŽċêȁèÛŎġƒͩń"]],"encodeOffsets":[[[90113,46080]],[[87638,44579]]]}},{"type":"Feature","id":"6530","properties":{"name":"克孜勒苏柯尔克孜自治州","cp":[74.6301,39.5233],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@ˎǫĠƽ°UUĉ¯±ȁÑmƒ„¯Ýōˋō™wUű»ÅƑ°ƒȘ@²¯ɳʇ`ɱŃ¥՗™ɳȗōkȭšșW@kəJóÔƩ`ĉ£Vů¯wU°ʇĊ„ÈÒ°aĊÞÞJŁċƧīĠyĊ²XôÇxÈÆÆ@„ÞʈƒÅ»™XÞīU›Ƒkm„ŹÝ@aŎÅÆīƨĕ@™ż`Ċk@љƒĠ@ŦÑ@ǵÇÿ@ÇÅŗl¯ğJ@™ÇUkçġÒƏÑÝ@ţéWĊôŚUŽóXUġkţ¤ķ@@ƴōĊó@óÔğƒ¯„ċ@@Қ¤kôˣŰ͓„k»ƒKX¯ċwƧôğɐšÒôIVƙš¯UķǬķšnŽ™¼ôb°ÒȰVVÈÞ°ƒĸó¤V¼°„V°²êƒlĢ҂Uƨ¦ôȰƴĊVV¼ǖIċĊ„ÞɜéšnČW˸Ǹša„řÈw±īšçĸ¤ĊšôšwšŽĸUĢ¦˜éǖĬ„Āô¼lÞkÒ°x°ƆÞx„šÆV²ǔ»„b°wގȘ¥°n„šŎV@°„„ʠè‚ŰȂb"],"encodeOffsets":[[80269,42396]]}},{"type":"Feature","id":"6521","properties":{"name":"吐鲁番地区","cp":[89.6375,42.4127],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@ôK„ĉǪa²¼lÜô@ʠê°Ĭ™ôȂƒ²ÑÜbĢóɲ™ĸ¤ŎUô@xƒŽǔ£ъxˎmƒÈÛ@‚_nĕÞōšř„ǫƒğšůlȯ„¯ĸ»U»Ükôƛ°ůkť™»Ŏŗ@¯@±͓óͿ„Ǔ@ķȁ¼Ϳ@Ƒ¼¯°ólġ¯xȗUġšƑ™ǩÒƧUÝ°˹Kóššx@ǸōĬÅĬƑĠ󃄚ǔêÆ°XÒʟŤUšÇ¼ˋnn¼±V²°ȂUŌݜbʟǔɅô@żǬaҎÈ"],"encodeOffsets":[[90248,44371]]}},{"type":"Feature","id":"6540","properties":{"name":"伊犁哈萨克自治州","cp":[82.5513,43.5498],"childNum":10},"geometry":{"type":"MultiPolygon","coordinates":[["@@ĉ„ÆŘȁ̐mÞ¯ĀX°±¼@ƾ¯ƴ°ŎÝþŋ¦WÜÞbȂĉźUœÇmwVUȂóô@ȰÝ΀nÆJn™ƾ™ʠ™ŌLČóǪ¯œ¥ǔaǖšŌaôÝĢLšx„ƒÆLšɲm„™²VlwÈ@˜Uƒƒ°¯ǖxĊmUÑƨa°Å°WV¹œa›ÇɃÈm¥°¯ŹóĸķǫUm»Å¼ÇVɱ™l݃ŋnķÇÝX¯ƒͩÇɳa——Ý`±_U±ĵnWƒ™a@™ĸóšķ™¯ǓV±ÅĵJċ¹ɅykwDŽ¯£Åxʟ»ƒlķI¯ƒX¯ķ‚™êǕƒȭnķ»Ź`±„kÞ@Žš„Ýô@Þ°xšŤŎIƨÆUxōš¯²ǔĬǬlUŚ"],["@@ÞĀlźƒ¦¯ĸŤKޙšƒċƨbš™Vğ—w›ġ¯@ţƽJ"]],"encodeOffsets":[[[82722,44337]],[[86817,45456]]]}},{"type":"Feature","id":"6527","properties":{"name":"博尔塔拉蒙古自治州","cp":[81.8481,44.6979],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@ήƛϲÝĠ™„ÈKŌōÿmī„w@¯ɛKV¯ğǟ°Ƒ™wġKóÞŋbǕ™Ǔb›¦ǩ°ċôŋKʟšƽšmšÅImŽͿŽȯÞó@ȁôUVnx›ÈŹVȁĊÝabŻ£¯°l„óxȂŤĸkĊšÞyĊêĊmĢxV„ƨÈŽĠX„ŽΘÆĠÔź‚Ɇţ°LXƾŤŤb"],"encodeOffsets":[[84555,46311]]}},{"type":"Feature","id":"6501","properties":{"name":"乌鲁木齐市","cp":[87.9236,43.5883],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@šŽWŽôŚUĠȚl¼Ċ¼ƪǖ@źȘƆ@ýlܚXVŘޙš¦V¼kĖó҃èkĊȁˮ֜@ǫ՗nōƒĉǬō„ķÆŚ@„±ÞV˜¼nwĢIôºl£ƾ»UŤJôçšó¯īʟéó@kÛ±»ǩbƒĊóLҍÇǫb@ŻɆóʠǓ›aŋÞȁVʉłĉbĉɅô"],"encodeOffsets":[[88887,44146]]}},{"type":"Feature","id":"6502","properties":{"name":"克拉玛依市","cp":[85.2869,45.5054],"childNum":2},"geometry":{"type":"MultiPolygon","coordinates":[["@@ɜÞʊĊýVaŃm»ʵƳƑʝȗīV¥¯ĉ°Ñ@ŃÅI™»ĉmğn™ƒaݚţL°ķóKĵĀV͈ĉłƾNJÆŤƒzXl°ƒÆL²¼źŽôÈĢǔ™¦l„ô°"],["@@ƾIŤ@UUwōa™ĉÝJğÑÆŎkŎ"]],"encodeOffsets":[[[87424,47245]],[[86817,45456]]]}},{"type":"Feature","id":"659002","properties":{"name":"阿拉尔市","cp":[81.2769,40.6549],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@nIÇŃÛÝĊÑĠƏō™гwȁ¥Ƨ°ŹÑķV™¼ÞêĊ»‚lĵšm¦ÅW@ĀôÈźaɜxÈbÞÆĶIОŘ"],"encodeOffsets":[[83824,41929]]}},{"type":"Feature","id":"659003","properties":{"name":"图木舒克市","cp":[79.1345,39.8749],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VéVÇ™ţ°ğUĠ¯mk¯ó¥ķIġÿƏbƒ„ĉa±ÒĸĀlKU„_m»nwšŽ„m@ÈŤ¦ĉbÞ°±Þżł̦°ĢŁ"],"encodeOffsets":[[81496,40962]]}},{"type":"Feature","id":"659004","properties":{"name":"五家渠市","cp":[87.5391,44.3024],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@„çôÑlĕU»™¥ÝšUŗ™WkÛ@þVńÝĔ@ńÅþĶUX¦Æƒ"],"encodeOffsets":[[89674,45636]]}},{"type":"Feature","id":"659001","properties":{"name":"石河子市","cp":[86.0229,44.2914],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@lŁ—ǵm‚ĉ@mż™¼n°ÞmƼš@"],"encodeOffsets":[[88178,45529]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/xi_zang_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"5424","properties":{"name":"那曲地区","cp":[88.1982,33.3215],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@ƨʔĸbܺÞwnxźbÞ°ô@„ĶŽĸIȼĊJŎÈôUšÝƒ¤ǔLސŎ@ĢŽȘblƒôL„ÇźçȤôLš¥ÞIÞ¯Ķxʊťƨ™ƿÑĉXVķŦ¯ȂKÇǕšÑ¯IUš£¯Óƿ£VĕōÞÿÆwƒƑ„£ǖxÞĕ±ÇÝaUÑȃU¯‚UōÈ݃wWŁĵ™±Ý„óĢÿ°IÞ±mÅĢ¯mÿ„¥°UnÑŤĢĕĶwǬŻͪwŎ¼źÇĢ„ĠĕˎŁ°óƨ¼Èa‚m@¥°wǔ„ǖ°ŽƨÇŤœšġƨ„ŎŃôbÈÛŎĊ°@Ġw²ÑÞJƃÆb²ƒ°êĊUނlȲƒV„ÈKĊÒĸĉ›»ÅôťUÅǃk¯@ǂÑklǁÅl™Ģ™VÑóƒ@°@„ÛĸƒV¯ƒÇĊ™n¯Uĕšƽ¯m›¯b™È@Ò°Ĭƒbĵ›¼„‚kxķýÇJk£ÝaUÑÅóĶǟkÓʉnĉƒÝ¼Ƒ„ó»Þmn£m™Č¯@ƒȮÿV¯ĸƒ™k@Ýówƒ»ğ„ġ±ǓLō„ƒšV¼Əèķĉ™è±b@Òţ„UÑóakƒl£™Ó@¯L@™ÇlUóȁš¯aġÈÅĕÝLķ¯Ė¯@WĬ—x‚ÒÈnW°ţôU²ǓÓġ²V°¯ôƒǔÝL—ċšk™š»Ý»Ýš¯ÞƒVƒwۄÝÇōͩÈĉċ»ĉm¯£W¥ţKkóġƏW@¯±kōŽÈ›b@җšÇaƒÆ¯a™„ƒkóŽÛƒÇ¦Ýa¯šÝ™ĉ@ǻۄmƒǓxķƛ¯lVĀÅÞġb™™ÇJUÅV™ĖƑW™zō»ōšƒW™n@è¯ÞóVkwƩnkźÇބҙޯƒƒýğÇUxÆÈnè±bĉÝ»ÈуwšwÞ@m»ÈV@ýÇ°ķ™xƒa„ݯXċ¥ƒÈóW@ôkxlnxVÈóĊkŤġ¼@°¯ŰƑL̻۱ŎÝV—Þ›VƒÇÞŎÇakƞ‚š@èğŎĸżšƾ°ÒšLÞôĠKȰĖźVÈÒĠ„¤™VôšŽU„ÈþťL@ôǬÞlÜÈnÇÒUŚ™@šĊƨW°™°Xƒ‚@ČÇþ„ƴĉÒķ¦@ŽĢôWĀôłUÞĢǬ™ź°¼š@ƒôV°„bUÆnzm¤ƽĸƒÈ"],"encodeOffsets":[[88133,36721]]}},{"type":"Feature","id":"5425","properties":{"name":"阿里地区","cp":[82.3645,32.7667],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@„Çƾķn£myVŃaU¯„ó™@¯»šŹġǫVÝóŁXÿġó@ĸ¥ĊуƳÈý@ċ„Wš¯X¯ĉƧ‚™š@VřÈÑÇmkÛǫÝ@óŦKÇýVƒ™U󚏃£ğÇÑŹUȯĕğLÝó™K¯Ñ™ƽķŻĠō@灙lƝÈbƍÈ݂„œU˜ÝÞU²ō̼ůƒK°ů@¯UK±—ĊƧbōÇmçÈġƒóšÅób™™źóš¥kīƯól™ç™KôĵUƒÅ„VŃķ¥nÅŏm¯¹Å‚™»@ÑǍóxÝkʇȤU¤ķb@ƒ¯ĊÇx¯ĸĉKm°šĀk¦l„„KnĬȀƾÛ¦WÆŐmNJĉ°ōUţ¤UšŎ°šŎKÞłÆ„Ǔ¦ƒÞ™‚™„ř¯bmUÝl¯Um™ğl¯£șwŎǫaÝnĉĶƒk@¯™K™šō»ĉn™aÞ»ťnkml™ĸ¥UŚŻkÑťƒĉV™ôó°LôīĠU„ÿĉǕÅz±Kƒ¤„²ō¤¯Ė¯UÝ¥Vĵ™óÈťÝwķșÑk¤ó„™ƒWýĵĕ™„VĠƒV󍃎Ǔ„ķ°k±VU±ţ¦UǟÝřJVљ¥XUċUŎlÛƆǕÆȗƆ¯wŏÞÅ@™šĉl݁óŽƒÒ™nUôńlxólÝôێ±™™LÛôÝL@‚ġ¯X¯ÇUżóa󤛼XÒġŎóLk¦‚ôżĸĠ™¼™KġƆô¦„ÆƑÔĉĶ¯ImÒ°¦n°¯Þl˜ÝČn„ƒÒšKĠޚĕkƒlýƾťœšôI‚ĖŤÒnƜm¼¯lnżóÞ@Ůó¦™ôƽĖċŚn°Ý°ôÈUƜƒblÞóŽ@Žǖô°UÈƆ°X„þôŽô‚lѢšŽ²Ėm¦°š@¤™XŽĊblܚzkºƒĖmX„šŎWVšóÞn°lĠxȚa°»żLźƒ„b@Æ°XĠÝȚxĊĕŤaȚ‚°È@„„@èŤ¦Ü¼œW˜ÞkŽÈ@V°lŤkŎ±²¦ƐUšlj°aÈÑŎbĢƒŎbÆ¥ÞIȘlššôVÈU‚™šb„kɲĶn„mnXb̼òƾĖŎ@ĢȂÑôÓĠĖʊšĊÔ"],"encodeOffsets":[[88133,36721]]}},{"type":"Feature","id":"5423","properties":{"name":"日喀则地区","cp":[86.2427,29.5093],"childNum":18},"geometry":{"type":"Polygon","coordinates":["@@ĶĖXþš„ôƒl£šÒĸÇÞxÇŦšôUĶÞ¦°V°ĕŎ£ƒ±„£²LÆyĊǖƒĀğVóĬ¯KóôUš‚ĊŦ„lҙżVÆķ¦kšlnŦmݼšbĊmŎ¼š™šL@°„lĊĵÞmǬbƍȚx°¤Ġknš°VÞkVn°aƒŚš‚š„Ýǔ¥ÅƒÝŁōL¯™ōV™Ť£ŎVĊ¯nljƏXÅÜ¥ǿƽmīƒLkƒl¥™ÿn¯ĊL°ķÈw°ĉ@ƑĸaV£ʈȣÞlôwȎ@Қ¼Æ°ºŐnmÆĸ¦UńƃV„óĶšLšèôkÅ°lĬ™¦Źôššôa™Æ„ôÇĢnèŎÈƨa˜ĉ²‚VLĢ»lţôĉUǂwkmlw@óôX„ÇȦ°WƒÞ„b‚wĸšÈ¯@þÇUn¼Ý@™x„xÇńÞ¼ĊŽ²amçÅÇVwĠȄþ°„šÝƒÑÈÝlŹƪmlxôU°Ý@çšm„XŎ™Ŏ¼šyƒXšĕÆUVÈIššĢaÆÝUÿ°kĸƜǔwn„܃ȼĊ@ޚ°™Þbȥ܄ô„lšƒ°b„ÅÈb˜™@ќa‚ǯUU¯Vġš»ƒ™¯aV¯Ç°Å™mnÑŤçǬVǬ™±ĉ¯¥Vĕ¯Ýk£˜ō—w@±ġÛ°ÇVїƒ@ۘa@ČL™Ƴ™„ƒÇa¯¤ÝIĵ¼U¥ƿōķÅţŻókÝóĕ‚¥¯™U»Æ£X¯ġŃÛkÝ°V°ó¼¯èWôÞĖ„ȎƒŽkĀƧĀówm¥¯JŹÝJݙōVVŁaݐƑ@ƒ˜ğŭǂ¯_ƒ˜ĵ—›VnxŃón›ƒĵxÇĖĉVÝÈğV™Ò󃯐±Żĉ£ķÆÅL™Ljĉý˜ţۃ¯VƒnV¤ÝÈ@°ÅÞݤ™ŰğŁm¦ÝxóKƒ¥ɱÈUĠôêVôÛ¼ÇWÝçĵaō¦óĖƧlÇĢƑŽnŎDŽV¼¼‚ºÛ@m¦ƽ„ĉmm¯ÝKÛç¯bŏłĬ™bƒ¼ÅLmŽ„xť°ÅU™šÝXkŽÝmĉ¦W„¯K„ÒknÝaV„Ýè¯KɅńÝKnÞ¯¼"],"encodeOffsets":[[84117,30927]]}},{"type":"Feature","id":"5426","properties":{"name":"林芝地区","cp":[95.4602,29.1138],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@‚VÈłVôÈk@š°K@ŽšÔk¤l„ôbVÒŤƒ@ѲašçĸĊƐçU»„™ŎƒǔKĢ²Ġƒ„¼ôx@ޚlƨĬ„Ul¯ÈLV‚šÞJ„°Ünʊ„wÜbXê‚VÞ¯°ššanaU°wƼɴÑWÑ°mÈýÈam¥Þ£Ť@„¥ôblÞĢ„ź¥ôxÈÅmݚ™ƒĕŃV»ĉōŤōnóƒ»ÈīķIUƒĠÑ°ġĸLÞ¯VÒƂ@Ābš¼WôÈ@V¼ôóŤKÈÑU»šwVǫżnWÒÈx™¼‚lŦ£ĊōŤx²¯@ƒÆƒU¯šçÆ@„¤°£„é°k°lšůÈó@¯ŤÇÈĉƒkkÿó¥ÝXķљÜ@ÒóŚÝ¯°ĉówÇ±¦ÅJUÒĉĀķw¯°mĖ¯„±akxÝÅnƒ™»lуK@¯lU™¯UVѯóĊ¯mōğVǓƅƒÞƒWÝÈÛ@ƿô¯ÜġzÅþ¯ólmôʇġĊÅUͿřŏȁˋŁóÇˡōƧƒÇb™w°Ķôk¦šÒƒnUþġҙÔkǔķèó@ƒ²@ŘōńĵyƒzġaݤÅIƒ¤Ƀť¦ğѯ¤ķbóš¯ó±ŽU²°¤ČÜVnÈƂ„ŚŎ°ôĢ„þÆzèVĀǎĀǘƒXŹÑ¯¤ówċķk¦šłUÒġzÇ@ƒ™ÆÝx@²Þ@Ƥ„Uô¦Uš°x„U"],"encodeOffsets":[[94737,30809]]}},{"type":"Feature","id":"5421","properties":{"name":"昌都地区","cp":[97.0203,30.7068],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@™ŽVĖm°ĉš„ÈU°ķ„ƒÜ¯@@ô„UÒġškš‚ÆkÈlŽÒ@Èl°È„VÆóŦƂœ¼‚a„ÅĢ™Ʉwnōw@¥Ŏ¦°ŹÞmVš°wnÿƒw„wÝw@¯šmÞŗ°wĠ˜ĸkÞğlĔ²¦°@„ĕĸwVóšal@nĢÇĊn°@¦šŽźUXçǔůĸVš™ÆK„ÈÝĠš²ÅĔô@lšŽÈ_m˜„zǖl„šaU¼ôwV°¯¦‚ĬÈa„l@Čǎ„¼™„nŽ˜I„xô»ɜ@ƨ¥ɆŁ„ŃǪȁkƛƨȍʊȡóĭ›@—ÈÇVƒůރĸƅmēƨť™ÅÈʉVǵ°ġVŭÅɧ°ÿnɛš£mƒķ²ŃóÑUĉ°mÇ»¯@mxUĀ¯èţ°ȁÝç„ġU¯ÆÇţÈ@°Çô™Ű¯k¯lƒê¯¤ƒ£Å@™èV°Å„@„±°ţwĉŎť¤kš»ÇwXÑŻmUǬ™xV¼ÇÒţLóôU»Ç@X󙻂a@ÿŁUÑÝ°ķK¯ĢğÒV„ĸJÇĬ„¼môţŎĊŎU¼Æ„„Ė™šnÞÇÆówŹ¦ġƒkÝóaƒ¦ţ@ݤn¦ÇbÇþ¯nXÒɳÒÅ»¯xVmb™b¯™Ý°UWéÛaƒxʉÛmƒ¯ÝI™‚UÇKk°ƒVƧīķ„U°ȭĀ@„ċ°nšm¤Ýnô¼ƒƒÞ»Ċ„ʊmlÔĵǠÆôVÒÞbl¤ÈIĸþlwƒœ»ĶŽ„a¯ī@њǰanœƾ°"],"encodeOffsets":[[97302,31917]]}},{"type":"Feature","id":"5422","properties":{"name":"山南地区","cp":[92.2083,28.3392],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@°ÞUĖ°¦²ĊôÇÜLǖĀɜŽȘŰÞLĸźêÞ@UÜUŤ°ɞ¯Ü„°WŦĀmŎ„¦ĢyVљŁl¥Čĸôx°£źÒ„Wȗ‚ÿȍUÿ‚çÅyƒýóġō¯ƒřŁmÇÛUċŽ¯£V±²°ôô™ĸa°£ĠÒŦ¥ɄŽ„£ÆJÞ£Ģb„yĶzŎŃ@ŗ„±ô@ĸçlǓšÓĢÑVý„m™Ñl¥ĵó‚¯̻̥™ƛǫÝһÇƧĉyţ¼ҍēVĶĉŎ°ĸmšÞVÝĸ™ÒÛaċ„ó™ŹĖƒèÈÈl¼k¤ÝX@`ސŏ¼Æō¼ÇçĉKUÝÝ£ğ¤@¦ġl¯Òġĉ¯óš™móxÝÞğVšƴċK@—b@ܘ„UÒ¯ÈĢÜ@²˜x—Ŏl¤"],"encodeOffsets":[[92363,29672]]}},{"type":"Feature","id":"5401","properties":{"name":"拉萨市","cp":[91.1865,30.1465],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@Ŏ²l@°‚XĢƐlôŤLX¦°¤ĊnČ¼ÇĊŎͪÞÈ܃„x„U°Ýޙ޼™¼lšČ™˜ŽÞK„Ǔ°óU¯Ģ±ǔÔV±ŤóX¯ÇmÑ˜wXī°@°ĕĸÞKÆĖĢÇ°bȂ™ÇŁUƒV¯wV™ó¥ƒVÅ£Ý@@±ÞwšÅ‚„È@ƒ¥nōťÿ¯Xۃɝ°ţ¯ÛVVÝ@ŹéķÝKȗůɛǕÿÛKóÈǫšǫUţèmҚn¯Æ°ÈU‚°b„š™¼UĢV°°V"],"encodeOffsets":[[92059,30696]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/yun_nan_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"5308","properties":{"name":"普洱市","cp":[100.7446,23.4229],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@U‚ô²‚a@Ž²²Ķ¥œV°šĶ²bl¤kVxl‚@œ°‚Ś²@˜„„y„@ô¦¯„@xƒxVxU„VššbVšÜm¼Ŏ„„ĢmºXXWÆ@ĀœšmŽmXU°ÅÒm¼Þx°w„@°‚XêĠ°»nV°U„l@k„@V±ôī@£‚ƒČŃÆ£„KÞý@¥‚k@y„a@—nWV„UVƒšwƒmƒ£Jƒknm@wmkn‚X„˜šX„¥mUUlUnbš¯°ŽnkƒVInlIUw°n™mk@@mlanXlanmšk@wVWUw™_@éĠašnmUaÜ£ƒmXƒ¥¯@@„óUmݯ¯ÞÝlKnxô£š»„»Ġ„J°aV„UÝÿV¥ÛbƒI@wmŽón¯yÛL@ƒWkŎmș`IWa¯K@¯mUnmaXm™bmak„¯ŽƒĢ™ÒÝm¯mV¯KÇb¯KۜWW™X@a™V™knċLUWV™kXóW@k™a@ƒób¯Uƒwmb¥UUlaU¥U£maķšƒKXkƒmÝ@kwmѯk±ċbUUVakaġ¦ƒƒkL@`ƒœ™a¯xƒm™Åƒ™LUWƒ@ċnŎUV°LkL@b°°@¤š²ƒ‚šnôôk„l°kè›ÒÈzV¤È„WôôƒnV@„ƒ¦@¼Ux"],"encodeOffsets":[[101903,23637]]}},{"type":"Feature","id":"5325","properties":{"name":"红河哈尼族彝族自治州","cp":[103.0408,23.6041],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@°°nÞôV@ƒ°@„¦WŽ„nÛ¤Vbmn™ğb@êš`VxUX@xš„ƏÞUnn˜WÞĸĢƒšÈ@ŽÇè@zÛÜWšÅêlš²„˜KnV¯ĖĊx@bk@@„°JÆ£Èbl„nnm°nlUkVUUwVm„Kn„‚nVŽÞxVLX¥laX@@xl@VzȎVmšk@b°šÈĸmŽV¦`W„XšƒbUb‚bX¼°x@ašVVkn@lþnXUlVxŤÅ„y‚IUƒka‚IŎĊ@lXx@b„z@‚ô„ƒ¥„_V@l‚n@„ôy@al_l`nmƒÈ»@kƒmXwWK™U¯»™a™Å@wƒmUÝKUa™UUƒ™wWƒ@w²»@kƃV£—mm£VKkÑV@@»nwƒ¥™ƒ@kƙnllIVlnLVakalknJšWmnaUaVÑVVލn¥m@ƒ„¯Uÿl™@™™™VçƒaXaV¯UyVLVkš@nJlšXLlŽkxlbla²Òl@nVJVkšx„KlkUaVķÝÑU@Åm¯@±™Uó°ğńķĠmU™Ñ@ǯ¯Å¼@nml@°¯¯`@w™£@¯Çƒk@ƒ»nmċ¯U»™I™Ž¯LÇĶÛn@bó°™U›šwmŽ¯„™Umǯa„™ƒ™ƒI@ykIƒVUŽ¯bƒIğŽƒ¼™¼ó¤mwkLÝÞ"],"encodeOffsets":[[104243,23429]]}},{"type":"Feature","id":"5326","properties":{"name":"文山壮族苗族自治州","cp":[104.8865,23.5712],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@šwô„š@²¯maUmôUÆxš@Xš˜bÞInlVUVw„JVaU„K°¥„xmÞXnlKlnna°@ĊČ„ÆwUmnkl@°ƒƒ£nyn@VV@Vak™ƒ@@kÞ݄bmx°Vnw°klÞInĖÞVlKl™@Xa°„„KlV„U@šJnx‚U@ÈĢbUKlm@ak_‚wšanWUk°ƒl»„k@Wk@lwU_ƒ@UalóU¥ƒÇnƒ™kJWƒ@mVXx±bƒK@nV±a@™Åa™£ÝK²ƒWknamKknǏk¯ƒaV™™V¯ĀƒU™„™Ò¥ƒI@mm¯¯xōW@@`k@ó»ƒUU¯lm£ÅWlĵ„w@mmwÅmWU@y±U—xmwU„¯Uƒ¥Ý¥¯£m@kŽÇVUV°VbklƒL™wUlUIm‚k@±ÑkbkalwkWKk™mI™@UlUKVzU°Wb„bU蚚@škšVĀƒ°@„n‚m¦ÝŽUUUÒVbmbXn™‚mIkllbUbmKUkkJmkŚ@lš„„¦mx@¼U@lÒULn¤˜nU¤Å„@l±¼@xX„šxV„šVVbÞLVŽ„n@xšÆšb°¼šV"],"encodeOffsets":[[106504,25037]]}},{"type":"Feature","id":"5303","properties":{"name":"曲靖市","cp":[103.9417,25.7025],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@ȦlKÞĕUV¯Um¯„ÇVUnVVUƒĉn™ĊÇƾLn°°È„JÆw„@lbÞa„¦V„XJ°¯W¯„aÞJVkUša„ƒ@lKnÅmWUk¯a¯»@m±@уkkbWWX_WÓU»_l™kÑm@U»m@l@IWċn¯l@VanV„UV™UVwVx„KȄVmUē‚@„ƒn@VÝÆL„w„VVwnVlmkUVÑÇ°ka@k™ÿÝaÞUl£™›—ċĕX±±ĉƒa@UnVnalónk@wl™UVmkÝJ—aW™™@ÅwóVVnnb±°™@óƒ™xXLWx„n@lǼn„m‚k_k`@bózƒ‚m@kU@ƒ`„¦óƒ@nWš@ÜÅXWw@ƒyƒb¦@ÒlnUb@x™lܐk‚@²Ç@Uƒ¯bmy@kV@bƒb„¦U`lLVx@b—Ll¼Þ¤@„°VVބU@WސUb›J@nnš@lnnm„šxUŽƒUUbƒK@šÇwklkUƒVWakn@ŽlbU@@„ULVxkKUn‚°¯Ò@¼™„kmƒ¦m@kl™Ȱ@lU„l¦„@Vl°wšnnþĊUÆbUx™b„ŽV„šĖU°„a‚nnašV„al@@b"],"encodeOffsets":[[106099,27653]]}},{"type":"Feature","id":"5323","properties":{"name":"楚雄彝族自治州","cp":[101.6016,25.3619],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@mҁXU`Wnšš™@Xl±¦š„Uxnbl°knmKUx„„ƒxVôUx°¼ôÒȄ°JlnÞKĠœW°¦ƒ„Vx²JVwš_°¥@UV@@wnymknK¯I@‚™²b°ƒš£V¥šwU‚V„¤nLškÆJÈwôô°„l»Č¯ƒġVƒUU@@ƒ°ƒƒÝXl@U»°Å„@U„¯@w±¯VmUUlm@m™„ÑnIVyUwmak£Vwm±—@Çw@nƒ@UxkwlÇnL‚mkř@±Žk™ka@kóJV¯Ç»U£lw¯™Xalbl¥¯UXƒ@a˜™UaÈL@ÇVIVƒkaU¯mm™akLWkUJ¯Umxnšƒ@ƒkUx¯xƒ„mWÅīÝkkbƒŤƒbkxWmXwWk¯wƒKkƒƒLŤċń„@¤óĬU²ƒ@@lƒk¯VmU¯¼@xV@k°l°kbUš°nm‚VnUš@°„š„UVèރÆbUÒÞnU¦›V—¼lô„@Vl"],"encodeOffsets":[[103433,26196]]}},{"type":"Feature","id":"5329","properties":{"name":"大理白族自治州","cp":[99.9536,25.6805],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@lbœKVIUa˜@²m@b™xôÒÜxXLmbnšl@š„„K°šš¼k„Uô‚xôlV¦nJ„Uš™Ænšm„@šx„ÆwšbXšÆôô„LUVwôK@wlmšaVwœ@WknmƒIUmlnJla@_™@kÝmKUašÑm¯Xw°aUaVl»²JV„bÆJkôĶĀ²VVk„mšbVwUó„wƒƒVwnLlmk¯maVw™ƒ²¥Wkš@™™XmV_‚WnÑUkƒ@k󘻜UV¥ÝmVÑÅa݄UçƒVƒ™@¯V™Umn¯mV™lak¯l¯U@@wğŽW鯁ƒ@¯xÝw¯š¯Jċa¯U¥mLU¤„bÞȤƒbÇLWUwmIUVW¼kbš`U„Vb¯L±ĊÛkƒÿÝKkwƒKţê™UĉþƒÈƒV¯ÞVbUŽ°KVšk²Ý‚mI—ƒmV@kƒm™UkšVxm„¯KXÈķJU¦V°ULWxšL@môƒšb@bkx±LnVUŽVLnkÜWnwlLŃmW@kkJU_ƒV„šWĊ„Þ"],"encodeOffsets":[[101408,26770]]}},{"type":"Feature","id":"5309","properties":{"name":"临沧市","cp":[99.613,24.0546],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@‚xĢ„l`²X°ŽV„šx@x°Þ°KXašğUњW‚bnIl`X²°b„xl°„„šV@xVxk¦mb„l@xšXV‚ÆzX¤™Æ˜k°„kx@lźêlaX»VUnJVx‚XÈK„aÝȣƒaV£nKV¦°‚Čb°I°™n»ÆÑV¯nWn›™@ÿXÅWWn¹ƒġōƒn»‚ÛU™™aU™VƒUw„w@w°ƒó¥ƒ@ƒz—ƒ±@ř›¯@kUwlk£±aĵŽ¯™›Uĵ¦±±@bó±VÝ@ó¤ƒw¯I@mńóm±XŽ¯IólƒK@š°Ullb™zkKlln@@ԙºƒUmVk²ôҙx™ŎUVóLƒb„ŽmÈnŽmbnl‚a„x@z„@Ǝ„¦kš"],"encodeOffsets":[[101251,24734]]}},{"type":"Feature","id":"5334","properties":{"name":"迪庆藏族自治州","cp":[99.4592,27.9327],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@W™Xwƒ™@akk@y›—k°īX¥›Uóķ¯w@n»UaVaUۃ¯ƒmV¼k‚™Þċô@n¯xÛÒm„V‚¯Ô@xƒ‚@šk™wm™Åa@ƒUa‚݁¯VŃyV„a@ÿšn»ÝVmank™mmÞÅôƒ@n£±›ğzÇmU¦™Vm„nÜmbn@°nV@xmzÅ@mºV¦k°ln¤š¼õô„n@xkƃIUxUš@Ťƒ¦VšmVkmkXW¤XzVx@ƚx™¼ƒÞ¯b@lVš™ĸގV„m¼XŽm¦V„ŽÞ@Ǝš¹Vón¥ÆKn„‚KX¯x@èĊȱłXšaÆxnlV@UÛlȻkğV¥„m²ljmÅÞĕƒƛm°„ÆmX¤mznƃŽV¦ÞVVb°bnÞWbnŽ°l@V„È@„‚VĵĊ±@ó„InxÆw„¥@£Þ›W¯ĸ£UƒUK‚ƒk±akkkbmWmÈķ„aÆÇU—ȃÆW@wmknmU¯"],"encodeOffsets":[[102702,28401]]}},{"type":"Feature","id":"5306","properties":{"name":"昭通市","cp":[104.0955,27.6031],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@mƒnK@wmƒUř¥mšóXǓŏmX@Ž—VƒmL@xţ™nk@mlUšŻÒğŋ@ƒL@mmLkm™š@b™XŎW¼ka¯lÇŹ¯aÇ»™ÝÝ_@m„@@a™@UklwUm@ak@ƒb™UmbmƒbV¯™ĕUƒƒšaVwÅaĉVmý™m¯xUkƒ@k¥VƒUXƒ¤VÈm`@„—ńÇÜ@Ākn‚ĔkƞÆĠ„™Þš‚U„VôƆÞI@ŽUxƦn„l@ĊĊnxUÒ°¦Vb¯WUnWŽIml@xn„Ubô¤‚¼ÈxlI„»šKVš„@ÈԂJkšUĖ±ÆVb@nœ„VÜVUVƒšL„wĠl„kn„Ġ@nx°¥Æ„²mUwƒ@m™mÅUl¯UњÑUm„Lll„Il±š@VkwƒW@w°@U»™kUóI°ƒ„»ĢтL„™š`nUĠ²lm„bôV@n„JUxƦX¦l@š‚ŎUƒV„@lV„KVřV£UaÞU™ƒnW@¯VU@ó™"],"encodeOffsets":[[107787,28244]]}},{"type":"Feature","id":"5301","properties":{"name":"昆明市","cp":[102.9199,25.4663],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@n@Vk‚VUn²°@xƒ°Vƒ@¯ÆV¼k@WŽ„Þ¯„@„@‚VVU„„Ģċ°k¼V„Ċxœ¤Ōœx°mVkƒÑȏšL‚°„x°Xœ°VmĊLVxUĖ°bX¦VW@kšȯlkn@„¥lnšƒ@»°Ñ¯VmlLUwVK@ƒV@ka@lmXb„UlVlkÈx@™„LVa„VV™wnƒmm@km™@mœIVaݏ@XƒVUݯU@ƒÝ£k»˜K@aUwkKV_ƒ¥„a@alU@nz°aV„È@@±lÛšk@wVakm@т¥„a„z‚@XxÆW@ÛX™@m@ƒy@aWw@kōĉJlbV„JƒzţÆUwVkmWkým@Ul™U@b¯wVºƒU™VUêšĠƒXUaUbVĊUŽWXUmkK™™WnUUU™V™ƒƒVV™Ý@kk±‚™¯ƒƒLkƒš±WkXlVklƒ@ƒwXbmLƒ›VUIVmk@Ubma@kkaVKUƒ™kmlXLWn™J¯ÒĊ°@zkºlLUŤn@@n›ô@lƁnmKkÈlxVw„@@mÈx˜@n²Uxl¤nbVxUzmJƒÒnš"],"encodeOffsets":[[104828,25999]]}},{"type":"Feature","id":"5307","properties":{"name":"丽江市","cp":[100.448,26.955],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@l@™„@w°ÓUnƒÜÑ°w@mČóšÝlU»n°„„VÜUbVbm¼@Ž°xôĸœVW¦¯Ĭlœ˜@zll@b„šWxXš‚a„X@ÆĠÆaXwl@XaƦn¼˜Jn@mnKW¯È»V¯°ak™VanXVwl@VyUĕVU„bÈīlaUk°ƒk¯lƒ²V˜Ukƛô@ƒ„I@mVwĊa„™ƒVaka„™ÆbUŽVLšaXIWKUw™ƒ„aWÑÅKUaVk°ƒ@Uw„ƒ¯¥›XğÝLkm¯Iǃóѯ»™aƒnUl±UĵÿlóÅIƒaU‚±Ik¼UŽVb¯bWxn°™ÒVbnLlޚ@@`kbmIkŽVn„JmnXl›@Ux™bkn@xóLUxVŽƒKóóŐW™™aÅxƒŽ™wƒ@™nÅm™šƒV™„ƒôX„ƒLlVU¤ƒb¦m¼™Ž@ĀƒbU‚„zUƂ°ÞVb@„Æbnššx"],"encodeOffsets":[[101937,28227]]}},{"type":"Feature","id":"5328","properties":{"name":"西双版纳傣族自治州","cp":[100.8984,21.8628],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@l²°ŽnÒlxÞ@„nWl„Lĸ™nbV¤V¦kbVV‚¦na„x°Vôa@„šb@lôXlWUšVXČKlmššU@bšWXXܛ°LÈa°LnU°‚ÞnšÑ„ġ°lƒnbšaƒ¯¯KWƒœó@kmK@UšĉV@k°„VV¹„a@y‚_ċl_nÓlL@anI@ƒóWl£VU—ƒl™kĕl™šKVw„U@™kVƒam¯ÅL@bƒ‚Ýk@Vn„UbÇbÝwÅ@ċ¥¯lk‚¼ÅŽ™Ò°b@¦nlUn@ŽÇV„mƁbWôU@ÝÅōm™¯ƒaU™™mk™WWw—@±ƒ™n¯U™è™a™Lƒ¯mƒL™škwƒl@°mnÈÒ¯šów@V™xƒĀU¤°Įƒ°Xl"],"encodeOffsets":[[102376,22579]]}},{"type":"Feature","id":"5305","properties":{"name":"保山市","cp":[99.0637,24.9884],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@X°„Il‚@¦ƒŽÈ¼m¼ÞaÞÅl„ÈxV¼šlVôÈÆlLޣȺlkUƒ‚ƒUw„¯UĕVwĊ@n¦mlnVĸIWÇ°LnƒUwl™šV„n@lnU˜„nJށl±U™¯LVUa°Ý„U„ÇĊýšVŤé„LlxÞL„ĀÜl²ĉ°KUaVƒ™_Źé@klw¯ƒlÅ—šW£ÅyU™W@wƒknal¥Uw@w™Uƒƒk¯ƒw¯aW±k_mJa™XVҙĠWb¯L¯Ý@w™wUƒ¯±Wk_ġƒwƒwōKmb@¤„bk°lĖƒô„UJƒšVnÅlťUš¯°VbnbWxX„m„ÞššWUĀ™L™yWzÛKmbUxVKkn݃kŽVšĀċ¤Ux„@Ž¯Žm@ƒ¦"],"encodeOffsets":[[100440,25943]]}},{"type":"Feature","id":"5304","properties":{"name":"玉溪市","cp":[101.9312,23.8898],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@l„„L°xXlWxXnlw„a„ţlaÞlÆĬnX„ƒ°wVw„l„@m™nw°VVIXllKšbnnV°lbU„UJ@ÈÇKVb—š@bW„°Vk¦kaWb°škxV¤È¼U°ôI@llblš²š@‚@œó@mm@VţkKl¹@yĉ¯°ÑšIXmWKnkšlV„ULlb@lnbVal@UnVJœU‚„nKWa„x„@lkkUlW²X„™‚l„K°„šl²@lšÞUŽ„U‚„UšVšVVXmššlLVnXWVUĉVaVb„W™ğVéšU„VU¹W»aVa„aW™Xƒ‚_U¥nÇķ¯™@a™lUnǍUyk@@wW@kbW¦UKÝwUmmƒƒLUnVxUVVlk¯mmnƒmkÇaŤ¯I@ƒl@@aĉw°ĕmU—L±ƒk™ÆéX™ÜÛ@yÈç@™Çġ„Ýķ—XmmÝVՙƒ™lmnkbmWkb@nl@nŽmš¯VxkJmUJ„ml¯™°makVVnVƒ¦™Wƒ—Wmnl@xmn„l‚I„¤„n™xU„ƒVUŽmX@˜ƒb@zl@¦Ýþ"],"encodeOffsets":[[103703,24874]]}},{"type":"Feature","id":"5333","properties":{"name":"怒江傈僳族自治州","cp":[99.1516,26.5594],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@WyX£lWlnnUU™„¥@ţV™Vw„JlÅ@wƒmö󙻂£kml¯U¥n¹Æ@ny@wmU@¯mnamÛnƒšUV¥ÈnĠy²œm¤„@ÆónݚnmlnbÞU‚¥„aV£kU„KWƒ„óšƒmIU¥ókwVólƒ™»¯™ƒL™ƒk@m™naWKÛwóњw@a±n—@VbUJ›LkaƒÝXĉƒ™„UV`lI@lnXÆƑkKmxÛXmlUKVmU²Klw@a™aó„@n™KXwVKU¯V¥mUnkm¥ĉ@UxVĖƒ°Vx„V„klmޙkKWĀkVWšnl°Lnm@°ŽUxlV@nk¦™JVÈ°ŽVÒ@nX°@ÆlUômlnôƒ²nxmłnVV„¯x@Èm°XblVUšl°@xkXU¤WXX‚W„Xƃ„mkÅJmށw±bƒxUīkKmÅVUĖÝèV„kx@š›lX„lnk¤ƒLkŽ‚Ėk¦‚xUššL°‚¯Ė@LnK@b°xVI„¥Ua°Ñ@»nm@¹‚KŎÞÈWln²n"],"encodeOffsets":[[101071,28891]]}},{"type":"Feature","id":"5331","properties":{"name":"德宏傣族景颇族自治州","cp":[98.1299,24.5874],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@„¥n@°@ƒVwČ£™ÿUlÞ„lmULVwnaÜLXyšzšKVÿ™XݙnƒWƒXwmaUa°¯V™ŦŽÆkUm„™VIƒ„ókĕl¯ƒa@£nama™@¯m¯œó@óyţbġkÅm±ÛammVkƒLwU`Wk@VƒkUmŃlUUKmbkkUVUwƒ¦óŽ°¼šbn°ô¦lºƒz@xšŽ¯„™@UŽ°nƒšU¤ţU„°VƆ@ÈmlnzÞl°¦Æa„xUxƒLkxWƒn@‚š²ŰšW„™‚@°ÈXl°Llx"],"encodeOffsets":[[100440,25943]]}}],"UTF8Encoding":true}; }); define('echarts/util/mapData/geoJson/zhe_jiang_geo',[],function() { return {"type":"FeatureCollection","features":[{"type":"Feature","id":"3311","properties":{"name":"丽水市","cp":[119.5642,28.1854],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@@V‚bVl@Xn‚UXƒKVŽ@¦nxlUXV‚n„KVmnL‚UV@bn¤lLXK˜²„`nnlJXIVJ‚I„Vnn°KnnVll@VLXWV@UkVaVK„zV@„ƒšVVaUK@U»VUl@@WnUUƒ@wVLn@Vwl@XW°LVbn@VU‚@X„l`@XnKVbkl@XVJlUnlV„„xlL@lnXl„@VšUnV°°„@a„UVLXblWVXn@VVUV@Lš¤VLV„U‚VbnalLUUVX_laVa„WVzXKV@@a@KUmImmXama@kU@yVIUK‚aVa@kXK@aWU@VIUmW@kkVm„Uš@VwUa@K@k@Uƒ`@kUKVk@UV@VaUm²Vy@klUUWUkVmUa@_ƒKVaXa›XmƒU@mUlWkaUXƒ@mmkL@w™JƒnVVÅbWKXa™@@I@aƒJUUÇ@V„UL™W@akLmb@K@a™XXw@mƒVmUVkUy@£@aU@@VkUWm@kUKƒXUWU_mW@wkkmJUUkLWWUXƒW@IkJ@k@mW_kӃ_Ul™Lƒm@I@aUa¯m@kƒa¯LUJƒ@mVVxUb™a@LUKkXƒbm@Uak@@a@Um`ƒIUbUJ@nUVW@@LnVV@lšUbVlUX@`š@blXklW„Ušm„Xlm¦U@@V¯bml@š@nUb@llnn@VbX@lV@ŽUVULmU@JVn„bVbkb™VWxU@@nUVk@"],"encodeOffsets":[[121546,28992]]}},{"type":"Feature","id":"3301","properties":{"name":"杭州市","cp":[119.5313,29.8773],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@X@l„°KXXlW„b@²„`šššb‚I„šX`l@„@bWl@n@VnLUV@V„@°¦@šl@XVlU@š@xVbUb@Vkb@‚@XVJVz™J@Lޚ@VmLUxUJ@LU„Vx‚b„xXUl@VaÈw„b‚aÞa@Vl@XUVx@V@V„LlbnV„al@lb„Vnn‚LnKnL@VlbVJXalIšb@KUU@mVInJ˜„U„Vl@xUšVLnUš@UÞaV@lkV@UanK„L@UlKVUnbÆmn@@nUlVnVJl@@UXU„L@WVIVJVxVLXV@IÜKnbn@V¥V@@I@ƒƒ„y°b@UUwnk°ÆƨVlUšçXm›£aƒÇ™IkVƒ@WV@@aWIUWUIkb@WW@UnƒK@UU@kaWVkƒVIVVnU@UWVUV@VmVkKkWIkVWaULU`UImJUImm—U@ƒƒwmwUV™IUWVkUamaU@mV—kƒb@KVU@aVU@anKULVJ‚U@kÛU™JUV›kkƒVakU@ƒaVwkW@UWkXmWaULUaUK@XƒJUUmƒVU@UVƒUkJ@ImwmKU@k„@lU„W@@akKm„kamIkWl_UwVm@UkaVUUaƒ@UamakbWlkL@aUalU@mkL@U@U™lmK@XkKm@Ýakb@xƒnXbƒ`ƒnUUU@›™U@™wU@@ƒmKkkƒV¯U@lULUbVbUb@V‚a@L™ºÝb@bLmK™x@VUL@bk@mxULWl"],"encodeOffsets":[[121185,30184]]}},{"type":"Feature","id":"3303","properties":{"name":"温州市","cp":[120.498,27.8119],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@ll@xnXV`VX„WVL@lXnlV@UV@@b@¤VzUlnV„U@nWxšW@b@LnalK@bšXVKUƒÈ@VV„I@b@Jš@WbXLÆaUU„mšI@xlKnn„@VWlbkXV‚@n„VWnœ‚WbUb„L@`VbUnVlVXkV@lUz±‚VnUbU@@VUlVL@l„_@V@l@LVbV@XLV`VÈlxn@lU@aœaVV‚k„@XJ@nl@@LU`°LVb„L°a@a„UVy@anI@a„a‚nV@²wÜJX@VšVV°k„na@WVk„aWwU@m@™ƒkƒaUĕ™ÝšÝŤnÈa„aóI›»@±X™WkUķ@kV±kw™ƒUkWw„™UƒÝ»ÛkɳlImaUaWóXÿǬk‚UnWVmmk™KţnŏÞğl™„UlUx@XWb„V@JkXƒ°mb@VULVxUVk@@LWWk@WIkšƒUkJmUkVmI@yƒ@Ua™kLm‚U@mUUUkaVk™@mK@UlUU@UmKmbUUUJ@n@KVLUL@VkJWXX`mnULWlkL@JVLVb@°kxkU@LVŽ™V@„VLV`UL@VUX"],"encodeOffsets":[[122502,28334]]}},{"type":"Feature","id":"3302","properties":{"name":"宁波市","cp":[121.5967,29.6466],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@Ċ¦ĸĀ°‚nXÞVšKškƨƑźÿ°»n„@wô¥ÜbœU°ÆXÞWóçĉݱIUƒÈ¥@U°wÆ»²mm_@aXƒVKÞVlk@akk›̅@£X»VwƏXWa¯aȗb™KƽۃĊ™xƒLóŽk@ƒƒƒ@¯nƒKUL@xkL›ÑkWULUUmJUXVŽU@mŽUX¯@V`mbXbV@@nn¤WXšx@škJ@nVVUVl²UbÝVUVk@Wx@V@„ƒVXzmlaƒL@VlLU`„XUVVVUnl@VbnJlnUVVnƒlUKkbmnn„VxlJnxmbU@UL@KUV™X@xmb@lk@mnVVUš™è"],"encodeOffsets":[[123784,30977]]}},{"type":"Feature","id":"3309","properties":{"name":"舟山市","cp":[122.2559,30.2234],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@l΢ƒʠþÆVĢLĊƒǬXĊ܄XôV„ÑÆw„ƒlšƏÈóVĭVǓ@ƒĉwɛkmK@ĉXīWaĉUĵÝmƒ¯ĉƒwĉ±±nż¯x@VǦV„²JĊÞôèÝXÅW¯›VÛaó¦@xƒŽmŽ¯¼ŹĀ"],"encodeOffsets":[[124437,30983]]}},{"type":"Feature","id":"3310","properties":{"name":"台州市","cp":[121.1353,28.6688],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@lV„IVWVz@bXJl@Xal@°„nLll@nVxnV„K@UJVbƒ¦°„k`UIWJXnƚ@bUJ„Xl@lb„Wn@UzVV@bVVšmVnnJVXna‚bšKUKnUVVUnVLlKVLXa„Jm£@mU@WanaU_°@VWnV@UVWnIVVVKlXœÒlK@wVK„L°m„@„„l@ô„Kšw„ĉƾůUƒl£@»UƒVk„m@ƅUƒƒaÛIŏmUk@m„w@a™£ƒWk@ţšƒIm±@ankôUlaU™Uw¯ƒōaƒbÇbţm™ÞšÞVĖ„b„l@š@n‚VXxƒbUl@XmbƒŽ¯lUUU™W@ÛI±xU@mƒb@bmJ@bUzƒV@b¯bƒKUa¯KV_@Kk@@mWIƒ@lUU›b@bkVm@kwUÇU_WKU@Ux™@ƒVUnllX@Vn‚J@UXV@bWL@lUbbVLUJ@z‚V@lnbWbnnnJVŽ@L"],"encodeOffsets":[[123312,29526]]}},{"type":"Feature","id":"3307","properties":{"name":"金华市","cp":[120.0037,29.1028],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@nbVb„@VbUVlb@VUnVxk`lXnJlbnƒlL@bX@Vƒ@klƒV@nLnx@JlI„V‚U@VUVn„VV„I@WVLVbVKXbWnXl@VlXUx„b@ŽlVUbl„œlVUšIÜVnalKX@@bV@@aUUlUƒwUw„@naWW„UVaUUšaVb„LlxXJVk°ƒUƒlkU¥@k„a@LVlXLVlšVWznVn@lxšJl_@WX_@mVa„a@alU@kVVna„KVLlK„b@UUaVašbnUWmXU@k@yVI@ařWmXIVJl_¯ƒ„¥UaVI@ƒLmUUw@mkkmK¯ƒk@Wbk@WI@aUyUXƒJkU@bU@WLUyƒXUbkbW`UVVkKmbUaVUƒUK™£@KVUUUm@UWkXWaUKƒV@b¯ƒ¯mU™V@UkƒmW@kkKƒwUƒmkkVUI@WlkUamL@Wk_Wƒ@UVm@Ua¯KWXk@Uxm@UK@xV„mV@Xk@UVV¼@‚VLUb™Uƒ„U@ƒyULUbVlU@@XlVUVVbƒU@lXXVW@XUVl@@VUVƒÈn@VVU„@lVa@„U„mL@`X@`WL@VUX@lUL@xlx"],"encodeOffsets":[[122119,29948]]}},{"type":"Feature","id":"3308","properties":{"name":"衢州市","cp":[118.6853,28.8666],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@XkVKnwl@@aVK@UšwnL‚K@aÞaš¹@Kb@UVaUaVaVK@k°V„UllnL@„V@šxV@œšV@VV„m„_Wa„m@wlaÞbn@lL@WnLšk@V@VlK@nkVVb@blKXklakw@wVK@kVW@UXK@_‚W@_nKVƒ@ƒUb@kVƒUUm@„ÇVU@Uk@VU@WUXWW@k„VUaVUkU@WWXUKk@Ukmm¯LmmƒUJUIWJkImmƒ_—±WLkKm£@aVUmKUnƒLmWUkVmw@¥U„LVWm@WUka@UmmLmm@@bUX™@@WUIm@UVUK@UVUUU™VVJmb@b„Xn‚mVƒ¼nnn¦mJUVƒL„V@VW@UzUlVnUbl`UnVl@XU@kl@bmÈUx™Vk@@J@„ƒ¼W@ÅaVVnzmVƒ„@WJk@kWJ@ƒlXbWbXxmVnšlLXb@°lKVXnWšbWV„„X„mbV@Xl‚bšI@Kn@@x@šVLlm"],"encodeOffsets":[[121185,30184]]}},{"type":"Feature","id":"3306","properties":{"name":"绍兴市","cp":[120.564,29.7565],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@„x@„˜VnnVJnIVJV_VKXblUXJlŽlLUŽUnU@UVVX@ŽmVUUUJl„XUlbV@@V„LVmX@@XlaVJVXXJ@b‚@XU„@lUšJ„È‚bœ¤Ō„JšçV™UUnml@@kna@wšWVU@LVKV@namwkIUwmƒnmlaVL„kUmVUkmmIUak@VmUUVUƒWV_kK@U„K‚bnkWy„U@ƒ@UXwl@VUÞUVak±VUUU@mlI@™™wXWƒIWbUKkLUKVmUUmVVL™LambUWmIUm™nUU@aUUVym@ƒXkak@ƒW@z@lWVXnmV™aUbVb@VƒakLUKƒLmbUU@lkV@bƒbUb@nW`@Xk`™Ikwm@mUXy™UUkWKUk@Kƒb@lV¦klV„¯„UlWIkwƒKUa™bVVUbƒVXXmbƒ@Vx„xkVVV@bU@@aW@kLmb@lVUIVKmL@bUV@bUV@L„a˜lnUV@nbVbUlVXšJVUnx"],"encodeOffsets":[[122997,30561]]}},{"type":"Feature","id":"3304","properties":{"name":"嘉兴市","cp":[120.9155,30.6354],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@@blIX@@VÜVUnn@l‚k„lKnI°Þl`²LVKVbnbVaVLUVn@W¦@VkVVb„@VI„`@blLnL‚aX@„VVb@U‚@XlVa„@@kVaUKV»U_lWXUƒƒ@alb„k@VllnLVKn@@UVIUw@y°IVVXU@VV@lw„m@wVkƾaœJ‚LkΡƧƒ™l™LÝUmW¯ķÿĉ¥ƒIŋŽWn™èkVƧU¯ÅmlVx@V¯aƒz„Ž@„@JU@U¦m@@šnVmn@V„LV‚"],"encodeOffsets":[[123233,31382]]}},{"type":"Feature","id":"3305","properties":{"name":"湖州市","cp":[119.8608,30.7782],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@kLlƒkm@VmÛU@UW@kJ@aUƒK@UnmmU@™maÛL@JWUUKUwUIUJ@XƒKWV@Vk@UIUmVk@mm@ÅnmaUVkL@VƒKmLVbU@klU@ÝbV™@mVUKV™@wUkVƒ—ƒmIUJ@nVV@L™akJWbUIka@UmKmLKmmƒUUVk@@nmLX`WXUV@Ž@nUl™kmlU@Ub„„ƒxVVšIlV„Žšnn„@@n˜„UҚ@„°n@@xmb@„VbnV@šš„@b@`@L@L@x@blVklVbnnV@‚aXb°VlU@W„b°U„LXWVUV™„™VwÈwÜ»ĸaĠnUVw²X@V@lVU@wlaUUVm@knUV›"],"encodeOffsets":[[123379,31500]]}}],"UTF8Encoding":true}; }); /** * zrender * * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * * shape类:支持半平滑的polygon,折线面积图使用 * 可配图形属性: { // 基础属性 shape : 'halfSmoothPolygon', // 必须,shape类标识,需要显式指定 id : {string}, // 必须,图形唯一标识,可通过zrender实例方法newShapeId生成 zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中 invisible : {boolean}, // 默认为false,是否可见 // 样式属性,默认状态样式样式属性 style : { pointList : {Array}, // 必须,多边形各个顶角坐标 brushType : {string}, // 默认为fill,绘画方式 // fill(填充) | stroke(描边) | both(填充+描边) color : {color}, // 默认为'#000',填充颜色,支持rgba strokeColor : {color}, // 默认为'#000',描边颜色(轮廓),支持rgba lineWidth : {number}, // 默认为1,线条宽度,描边下有效 opacity : {number}, // 默认为1,透明度设置,如果color为rgba,则最终透明度效果叠加 shadowBlur : {number}, // 默认为0,阴影模糊度,大于0有效 shadowColor : {color}, // 默认为'#000',阴影色彩,支持rgba shadowOffsetX : {number}, // 默认为0,阴影横向偏移,正值往右,负值往左 shadowOffsetY : {number}, // 默认为0,阴影纵向偏移,正值往下,负值往上 text : {string}, // 默认为null,附加文本 textFont : {string}, // 默认为null,附加文本样式,eg:'bold 18px verdana' textPosition : {string}, // 默认为top,附加文本位置。 // inside | left | right | top | bottom textAlign : {string}, // 默认根据textPosition自动设置,附加文本水平对齐。 // start | end | left | right | center textBaseline : {string}, // 默认根据textPosition自动设置,附加文本垂直对齐。 // top | bottom | middle | // alphabetic | hanging | ideographic textColor : {color}, // 默认根据textPosition自动设置,默认策略如下,附加文本颜色 // 'inside' ? '#fff' : color }, // 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示 highlightStyle : { // 同style } // 交互属性,详见shape.Base // 事件属性,详见shape.Base } 例子: { shape : 'halfSmoothPolygon', id : '123456', zlevel : 1, style : { pointList : [[10, 10], [300, 20], [298, 400], [50, 450]] color : '#eee', text : 'Baidu' }, myName : 'kener', // 可自带任何有效自定义属性 clickable : true, onClick : function(eventPacket) { alert(eventPacket.target.myName); } } */ define( 'echarts/util/shape/halfSmoothPolygon',['require','zrender/shape','zrender/shape/base','zrender/shape'],function(require) { function HalfSmoothPolygon() { this.type = 'halfSmoothPolygon'; } HalfSmoothPolygon.prototype = { /** * 创建多边形路径 * @param {Context2D} ctx Canvas 2D上下文 * @param {Object} style 样式 */ buildPath : function(ctx, style) { var pointList = style.pointList; if (pointList.length < 2) { // 少于2个点就不画了~ return; } if (style.smooth) { var controlPoints = this.smoothBezier( pointList.slice(0, -2), style.smooth ); ctx.moveTo(pointList[0][0], pointList[0][1]); var cp1; var cp2; var p; var l = pointList.length; for (var i = 0; i < l - 3; i++) { cp1 = controlPoints[i * 2]; cp2 = controlPoints[i * 2 + 1]; p = pointList[i + 1]; ctx.bezierCurveTo( cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1] ); } ctx.lineTo(pointList[l - 2][0], pointList[l - 2][1]); ctx.lineTo(pointList[l - 1][0], pointList[l - 1][1]); ctx.lineTo(pointList[0][0], pointList[0][1]); } else { require('zrender/shape').get('polygon').buildPath( ctx, style ); } return; } }; require('zrender/shape/base').derive(HalfSmoothPolygon); require('zrender/shape').define( 'halfSmoothPolygon', new HalfSmoothPolygon() ); return HalfSmoothPolygon; } ); /** * echarts图表类:折线图 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/chart/line',['require','../component/base','./calculableBase','zrender/tool/color','zrender/shape','zrender/shape','../util/shape/halfSmoothPolygon','../chart'],function(require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} series 数据 * @param {Object} component 组件 */ function Line(ecConfig, messageCenter, zr, option, component){ // 基类装饰 var ComponentBase = require('../component/base'); ComponentBase.call(this, ecConfig, zr); // 可计算特性装饰 var CalculableBase = require('./calculableBase'); CalculableBase.call(this, zr, option); var zrColor = require('zrender/tool/color'); var self = this; self.type = ecConfig.CHART_TYPE_LINE; var series; // 共享数据源,不要修改跟自己无关的项 var _zlevelBase = self.getZlevelBase(); var finalPLMap = {}; // 完成的point list(PL) var _sIndex2ColorMap = {}; // series默认颜色索引,seriesIndex索引到color var _symbol = ecConfig.symbolList; var _sIndex2ShapeMap = {}; // series拐点图形类型,seriesIndex索引到shape type require('zrender/shape').get('icon').define( 'legendLineIcon', legendLineIcon ); function _buildShape() { finalPLMap = {}; self.selectedMap = {}; // 水平垂直双向series索引 ,position索引到seriesIndex var _position2sIndexMap = { top : [], bottom : [], left : [], right : [] }; var xAxisIndex; var yAxisIndex; var xAxis; var yAxis; for (var i = 0, l = series.length; i < l; i++) { if (series[i].type == self.type) { series[i] = self.reformOption(series[i]); xAxisIndex = series[i].xAxisIndex; yAxisIndex = series[i].yAxisIndex; xAxis = component.xAxis.getAxis(xAxisIndex); yAxis = component.yAxis.getAxis(yAxisIndex); if (xAxis.type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY ) { _position2sIndexMap[xAxis.getPosition()].push(i); } else if (yAxis.type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY ) { _position2sIndexMap[yAxis.getPosition()].push(i); } } } //console.log(_position2sIndexMap) for (var position in _position2sIndexMap) { if (_position2sIndexMap[position].length > 0) { _buildSinglePosition( position, _position2sIndexMap[position] ); } } for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } /** * 构建单个方向上的折线图 * * @param {number} seriesIndex 系列索引 */ function _buildSinglePosition(position, seriesArray) { var mapData = _mapData(seriesArray); var locationMap = mapData.locationMap; var maxDataLength = mapData.maxDataLength; if (maxDataLength === 0 || locationMap.length === 0) { return; } var xMarkMap = {}; // 为标注记录一些参数 switch (position) { case 'bottom' : case 'top' : _buildHorizontal(maxDataLength, locationMap, xMarkMap); break; case 'left' : case 'right' : _buildVertical(maxDataLength, locationMap, xMarkMap); break; } for (var i = 0, l = seriesArray.length; i < l; i++) { self.buildMark( series[seriesArray[i]], seriesArray[i], component, { xMarkMap : xMarkMap } ); } } /** * 数据整形 * 数组位置映射到系列索引 */ function _mapData(seriesArray) { var serie; // 临时映射变量 var dataIndex = 0; // 堆叠数据所在位置映射 var stackMap = {}; // 堆叠数据位置映射,堆叠组在二维中的第几项 var magicStackKey = '__kener__stack__'; // 堆叠命名,非堆叠数据安单一堆叠处理 var stackKey; // 临时映射变量 var serieName; // 临时映射变量 var legend = component.legend; var locationMap = []; // 需要返回的东西:数组位置映射到系列索引 var maxDataLength = 0; // 需要返回的东西:最大数据长度 var iconShape; // 计算需要显示的个数和分配位置并记在下面这个结构里 for (var i = 0, l = seriesArray.length; i < l; i++) { serie = series[seriesArray[i]]; serieName = serie.name; _sIndex2ShapeMap[seriesArray[i]] = _sIndex2ShapeMap[seriesArray[i]] || self.query(serie,'symbol') || _symbol[i % _symbol.length]; if (legend){ self.selectedMap[serieName] = legend.isSelected(serieName); _sIndex2ColorMap[seriesArray[i]] = legend.getColor(serieName); iconShape = legend.getItemShape(serieName); if (iconShape) { // 回调legend,换一个更形象的icon iconShape.shape = 'icon'; iconShape.style.iconType = 'legendLineIcon'; iconShape.style.symbol = _sIndex2ShapeMap[seriesArray[i]]; legend.setItemShape(serieName, iconShape); } } else { self.selectedMap[serieName] = true; _sIndex2ColorMap[seriesArray[i]] = zr.getColor(seriesArray[i]); } if (self.selectedMap[serieName]) { stackKey = serie.stack || (magicStackKey + seriesArray[i]); if (typeof stackMap[stackKey] == 'undefined') { stackMap[stackKey] = dataIndex; locationMap[dataIndex] = [seriesArray[i]]; dataIndex++; } else { // 已经分配了位置就推进去就行 locationMap[stackMap[stackKey]].push(seriesArray[i]); } } // 兼职帮算一下最大长度 maxDataLength = Math.max(maxDataLength, serie.data.length); } /* 调试输出 var s = ''; for (var i = 0, l = maxDataLength; i < l; i++) { s = '['; for (var j = 0, k = locationMap.length; j < k; j++) { s +='[' for (var m = 0, n = locationMap[j].length - 1; m < n; m++) { s += series[locationMap[j][m]].data[i] + ',' } s += series[locationMap[j][locationMap[j].length - 1]] .data[i]; s += ']' } s += ']'; console.log(s); } console.log(locationMap) */ return { locationMap : locationMap, maxDataLength : maxDataLength }; } /** * 构建类目轴为水平方向的折线图系列 */ function _buildHorizontal(maxDataLength, locationMap, xMarkMap) { // 确定类目轴和数值轴,同一方向随便找一个即可 var seriesIndex = locationMap[0][0]; var serie = series[seriesIndex]; var xAxisIndex = serie.xAxisIndex; var categoryAxis = component.xAxis.getAxis(xAxisIndex); var yAxisIndex; // 数值轴各异 var valueAxis; // 数值轴各异 var x; var y; var lastYP; // 正向堆叠处理 var baseYP; var lastYN; // 负向堆叠处理 var baseYN; //var finalPLMap = {}; // 完成的point list(PL) var curPLMap = {}; // 正在记录的point list(PL) var data; var value; for (var i = 0, l = maxDataLength; i < l; i++) { if (typeof categoryAxis.getNameByIndex(i) == 'undefined') { // 系列数据超出类目轴长度 break; } x = categoryAxis.getCoordByIndex(i); for (var j = 0, k = locationMap.length; j < k; j++) { // 堆叠数据用第一条valueAxis yAxisIndex = series[locationMap[j][0]].yAxisIndex || 0; valueAxis = component.yAxis.getAxis(yAxisIndex); baseYP = lastYP = baseYN = lastYN = valueAxis.getCoord(0); for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; serie = series[seriesIndex]; data = serie.data[i]; value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; curPLMap[seriesIndex] = curPLMap[seriesIndex] || []; if (value == '-') { // 空数据则把正在记录的curPLMap添加到finalPLMap中 if (curPLMap[seriesIndex].length > 0) { finalPLMap[seriesIndex] = finalPLMap[seriesIndex] || []; finalPLMap[seriesIndex].push( curPLMap[seriesIndex] ); curPLMap[seriesIndex] = []; } continue; } //y = valueAxis.getCoord(value); if (value >= 0) { // 正向堆叠 lastYP -= m > 0 ? valueAxis.getCoordSize(value) : (baseYP - valueAxis.getCoord(value)); y = lastYP; } else if (value < 0){ // 负向堆叠 lastYN += m > 0 ? valueAxis.getCoordSize(value) : (valueAxis.getCoord(value) - baseYN); y = lastYN; } curPLMap[seriesIndex].push( [x, y, i, categoryAxis.getNameByIndex(i), x, baseYP] ); xMarkMap[seriesIndex] = xMarkMap[seriesIndex] || { min : Number.POSITIVE_INFINITY, max : Number.NEGATIVE_INFINITY, sum : 0, counter : 0, average : 0 }; if (xMarkMap[seriesIndex].min > value) { xMarkMap[seriesIndex].min = value; xMarkMap[seriesIndex].minY = y; xMarkMap[seriesIndex].minX = x; } if (xMarkMap[seriesIndex].max < value) { xMarkMap[seriesIndex].max = value; xMarkMap[seriesIndex].maxY = y; xMarkMap[seriesIndex].maxX = x; } xMarkMap[seriesIndex].sum += value; xMarkMap[seriesIndex].counter++; } } // 补充空数据的拖拽提示 lastYP = component.grid.getY(); var symbolSize; for (var j = 0, k = locationMap.length; j < k; j++) { for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; serie = series[seriesIndex]; data = serie.data[i]; value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; if (value != '-') { // 只关心空数据 continue; } if (self.deepQuery( [data, serie, option], 'calculable' ) ) { symbolSize = self.deepQuery( [data, serie], 'symbolSize' ); lastYP += symbolSize * 2 + 5; y = lastYP; self.shapeList.push(_getCalculableItem( seriesIndex, i, categoryAxis.getNameByIndex(i), x, y, 'horizontal' )); } } } } // 把剩余未完成的curPLMap全部添加到finalPLMap中 for (var sId in curPLMap) { if (curPLMap[sId].length > 0) { finalPLMap[sId] = finalPLMap[sId] || []; finalPLMap[sId].push(curPLMap[sId]); curPLMap[sId] = []; } } for (var j = 0, k = locationMap.length; j < k; j++) { for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; xMarkMap[seriesIndex].average = (xMarkMap[seriesIndex].sum / xMarkMap[seriesIndex].counter).toFixed(2) - 0; y = component.yAxis.getAxis(series[seriesIndex].yAxisIndex || 0) .getCoord(xMarkMap[seriesIndex].average); xMarkMap[seriesIndex].averageLine = [ [component.grid.getX(), y], [component.grid.getXend(), y] ]; xMarkMap[seriesIndex].minLine = [ [component.grid.getX(), xMarkMap[seriesIndex].minY], [component.grid.getXend(), xMarkMap[seriesIndex].minY] ]; xMarkMap[seriesIndex].maxLine = [ [component.grid.getX(), xMarkMap[seriesIndex].maxY], [component.grid.getXend(), xMarkMap[seriesIndex].maxY] ]; } } _buildBorkenLine(finalPLMap, categoryAxis, 'horizontal'); } /** * 构建类目轴为垂直方向的折线图系列 */ function _buildVertical(maxDataLength, locationMap, xMarkMap) { // 确定类目轴和数值轴,同一方向随便找一个即可 var seriesIndex = locationMap[0][0]; var serie = series[seriesIndex]; var yAxisIndex = serie.yAxisIndex; var categoryAxis = component.yAxis.getAxis(yAxisIndex); var xAxisIndex; // 数值轴各异 var valueAxis; // 数值轴各异 var x; var y; var lastXP; // 正向堆叠处理 var baseXP; var lastXN; // 负向堆叠处理 var baseXN; //var finalPLMap = {}; // 完成的point list(PL) var curPLMap = {}; // 正在记录的point list(PL) var data; var value; for (var i = 0, l = maxDataLength; i < l; i++) { if (typeof categoryAxis.getNameByIndex(i) == 'undefined') { // 系列数据超出类目轴长度 break; } y = categoryAxis.getCoordByIndex(i); for (var j = 0, k = locationMap.length; j < k; j++) { // 堆叠数据用第一条valueAxis xAxisIndex = series[locationMap[j][0]].xAxisIndex || 0; valueAxis = component.xAxis.getAxis(xAxisIndex); baseXP = lastXP = baseXN = lastXN = valueAxis.getCoord(0); for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; serie = series[seriesIndex]; data = serie.data[i]; value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; curPLMap[seriesIndex] = curPLMap[seriesIndex] || []; if (value == '-') { // 空数据则把正在记录的curPLMap添加到finalPLMap中 if (curPLMap[seriesIndex].length > 0) { finalPLMap[seriesIndex] = finalPLMap[seriesIndex] || []; finalPLMap[seriesIndex].push( curPLMap[seriesIndex] ); curPLMap[seriesIndex] = []; } continue; } //x = valueAxis.getCoord(value); if (value >= 0) { // 正向堆叠 lastXP += m > 0 ? valueAxis.getCoordSize(value) : (valueAxis.getCoord(value) - baseXP); x = lastXP; } else if (value < 0){ // 负向堆叠 lastXN -= m > 0 ? valueAxis.getCoordSize(value) : (baseXN - valueAxis.getCoord(value)); x = lastXN; } curPLMap[seriesIndex].push( [x, y, i, categoryAxis.getNameByIndex(i), baseXP, y] ); xMarkMap[seriesIndex] = xMarkMap[seriesIndex] || { min : Number.POSITIVE_INFINITY, max : Number.NEGATIVE_INFINITY, sum : 0, counter : 0, average : 0 }; if (xMarkMap[seriesIndex].min > value) { xMarkMap[seriesIndex].min = value; xMarkMap[seriesIndex].minX = x; xMarkMap[seriesIndex].minY = y; } if (xMarkMap[seriesIndex].max < value) { xMarkMap[seriesIndex].max = value; xMarkMap[seriesIndex].maxX = x; xMarkMap[seriesIndex].maxY = y; } xMarkMap[seriesIndex].sum += value; xMarkMap[seriesIndex].counter++; } } // 补充空数据的拖拽提示 lastXP = component.grid.getXend(); var symbolSize; for (var j = 0, k = locationMap.length; j < k; j++) { for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; serie = series[seriesIndex]; data = serie.data[i]; value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; if (value != '-') { // 只关心空数据 continue; } if (self.deepQuery( [data, serie, option], 'calculable' ) ) { symbolSize = self.deepQuery( [data, serie], 'symbolSize' ); lastXP -= symbolSize * 2 + 5; x = lastXP; self.shapeList.push(_getCalculableItem( seriesIndex, i, categoryAxis.getNameByIndex(i), x, y, 'vertical' )); } } } } // 把剩余未完成的curPLMap全部添加到finalPLMap中 for (var sId in curPLMap) { if (curPLMap[sId].length > 0) { finalPLMap[sId] = finalPLMap[sId] || []; finalPLMap[sId].push(curPLMap[sId]); curPLMap[sId] = []; } } for (var j = 0, k = locationMap.length; j < k; j++) { for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; xMarkMap[seriesIndex].average = xMarkMap[seriesIndex].sum / xMarkMap[seriesIndex].counter; x = component.xAxis.getAxis(series[seriesIndex].xAxisIndex || 0) .getCoord(xMarkMap[seriesIndex].average); xMarkMap[seriesIndex].averageLine = [ [x, component.grid.getYend()], [x, component.grid.getY()] ]; xMarkMap[seriesIndex].minLine = [ [xMarkMap[seriesIndex].minX, component.grid.getYend()], [xMarkMap[seriesIndex].minX, component.grid.getY()] ]; xMarkMap[seriesIndex].maxLine = [ [xMarkMap[seriesIndex].maxX, component.grid.getYend()], [xMarkMap[seriesIndex].maxX, component.grid.getY()] ]; } } _buildBorkenLine(finalPLMap, categoryAxis, 'vertical'); } /** * 生成折线和折线上的拐点 */ function _buildBorkenLine(pointList, categoryAxis, orient) { var defaultColor; // 折线相关 var lineWidth; var lineType; var lineColor; var normalColor; // 填充相关 var isFill; var fillNormalColor; var serie; var data; var seriesPL; var singlePL; // 堆叠层叠需求,反顺序构建 for (var seriesIndex = series.length - 1; seriesIndex >= 0; seriesIndex-- ) { serie = series[seriesIndex]; seriesPL = pointList[seriesIndex]; if (serie.type == self.type && typeof seriesPL != 'undefined') { defaultColor = _sIndex2ColorMap[seriesIndex]; // 多级控制 lineWidth = self.query( serie, 'itemStyle.normal.lineStyle.width' ); lineType = self.query( serie, 'itemStyle.normal.lineStyle.type' ); lineColor = self.query( serie, 'itemStyle.normal.lineStyle.color' ); normalColor = self.getItemStyleColor( self.query(serie, 'itemStyle.normal.color'), seriesIndex, -1 ); isFill = typeof self.query( serie, 'itemStyle.normal.areaStyle' ) != 'undefined'; fillNormalColor = self.query( serie, 'itemStyle.normal.areaStyle.color' ); for (var i = 0, l = seriesPL.length; i < l; i++) { singlePL = seriesPL[i]; for (var j = 0, k = singlePL.length; j < k; j++) { data = serie.data[singlePL[j][2]]; if (self.deepQuery( [data, serie], 'showAllSymbol' ) // 全显示 || (categoryAxis.isMainAxis(singlePL[j][2]) && self.deepQuery( [data, serie], 'symbol' ) != 'none' ) // 主轴非空 || self.deepQuery( [data, serie, option], 'calculable' ) // 可计算 ) { self.shapeList.push(_getSymbol( seriesIndex, singlePL[j][2], // dataIndex singlePL[j][3], // name singlePL[j][0], // x singlePL[j][1], // y orient )); } } // 折线图 self.shapeList.push({ shape : 'brokenLine', zlevel : _zlevelBase, style : { miterLimit: lineWidth, pointList : singlePL, strokeColor : lineColor || normalColor || defaultColor, lineWidth : lineWidth, lineType : lineType, smooth : _getSmooth(serie.smooth), shadowColor : self.query( serie, 'itemStyle.normal.lineStyle.shadowColor' ), shadowBlur: self.query( serie, 'itemStyle.normal.lineStyle.shadowBlur' ), shadowOffsetX: self.query( serie, 'itemStyle.normal.lineStyle.shadowOffsetX' ), shadowOffsetY: self.query( serie, 'itemStyle.normal.lineStyle.shadowOffsetY' ) }, hoverable : false, _main : true, _seriesIndex : seriesIndex, _orient : orient }); if (isFill) { self.shapeList.push({ shape : 'halfSmoothPolygon', zlevel : _zlevelBase, style : { miterLimit: lineWidth, pointList : singlePL.concat([ [ singlePL[singlePL.length - 1][4], singlePL[singlePL.length - 1][5] - 2 ], [ singlePL[0][4], singlePL[0][5] - 2 ] ]), brushType : 'fill', smooth : _getSmooth(serie.smooth), color : fillNormalColor ? fillNormalColor : zrColor.alpha(defaultColor,0.5) }, hoverable : false, _main : true, _seriesIndex : seriesIndex, _orient : orient }); } } } } } function _getSmooth(isSmooth/*, pointList, orient*/) { if (isSmooth) { /* 不科学啊,发现0.3通用了 var delta; if (orient == 'horizontal') { delta = Math.abs(pointList[0][0] - pointList[1][0]); } else { delta = Math.abs(pointList[0][1] - pointList[1][1]); } */ return 0.3; } else { return 0; } } /** * 生成空数据所需的可计算提示图形 */ function _getCalculableItem( seriesIndex, dataIndex, name, x, y, orient ) { var color = series[seriesIndex].calculableHolderColor || ecConfig.calculableHolderColor; var itemShape = _getSymbol( seriesIndex, dataIndex, name, x, y, orient ); itemShape.style.color = color; itemShape.style.strokeColor = color; itemShape.rotation = [0,0]; itemShape.hoverable = false; itemShape.draggable = false; itemShape.style.text = undefined; return itemShape; } /** * 生成折线图上的拐点图形 */ function _getSymbol(seriesIndex, dataIndex, name, x, y, orient) { var serie = series[seriesIndex]; var data = serie.data[dataIndex]; var itemShape = self.getSymbolShape( serie, seriesIndex, data, dataIndex, name, x, y, _sIndex2ShapeMap[seriesIndex], _sIndex2ColorMap[seriesIndex], '#fff', orient == 'vertical' ? 'horizontal' : 'vertical' // 翻转 ); itemShape.zlevel = _zlevelBase + 1; if (self.deepQuery([data, serie, option], 'calculable')) { self.setCalculable(itemShape); itemShape.draggable = true; } return itemShape; } // 位置转换 function getMarkCoord(serie, seriesIndex, mpData, markCoordParams) { var xAxis = component.xAxis.getAxis(serie.xAxisIndex); var yAxis = component.yAxis.getAxis(serie.yAxisIndex); if (mpData.type && (mpData.type == 'max' || mpData.type == 'min' || mpData.type == 'average') ) { // 特殊值内置支持 return [ markCoordParams.xMarkMap[seriesIndex][mpData.type + 'X'], markCoordParams.xMarkMap[seriesIndex][mpData.type + 'Y'], markCoordParams.xMarkMap[seriesIndex][mpData.type + 'Line'], markCoordParams.xMarkMap[seriesIndex][mpData.type] ]; } return [ typeof mpData.xAxis != 'string' && xAxis.getCoordByIndex ? xAxis.getCoordByIndex(mpData.xAxis || 0) : xAxis.getCoord(mpData.xAxis || 0), typeof mpData.yAxis != 'string' && yAxis.getCoordByIndex ? yAxis.getCoordByIndex(mpData.yAxis || 0) : yAxis.getCoord(mpData.yAxis || 0) ]; } /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newSeries * @param {Object} newComponent */ function init(newOption, newComponent) { component = newComponent; refresh(newOption); } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; series = option.series; } self.clear(); _buildShape(); } function ontooltipHover(param, tipShape) { var seriesIndex = param.seriesIndex; var dataIndex = param.dataIndex; var seriesPL; var singlePL; var len = seriesIndex.length; while (len--) { seriesPL = finalPLMap[seriesIndex[len]]; if (seriesPL) { for (var i = 0, l = seriesPL.length; i < l; i++) { singlePL = seriesPL[i]; for (var j = 0, k = singlePL.length; j < k; j++) { if (dataIndex == singlePL[j][2]) { tipShape.push(_getSymbol( seriesIndex[len], // seriesIndex singlePL[j][2], // dataIndex singlePL[j][3], // name singlePL[j][0], // x singlePL[j][1], // y 'horizontal' )); } } } } } } /** * 动态数据增加动画 */ function addDataAnimation(params) { var aniMap = {}; // seriesIndex索引参数 for (var i = 0, l = params.length; i < l; i++) { aniMap[params[i][0]] = params[i]; } var x; var dx; var y; var dy; var seriesIndex; var pointList; var isHorizontal; // 是否横向布局, isHorizontal; for (var i = self.shapeList.length - 1; i >= 0; i--) { seriesIndex = self.shapeList[i]._seriesIndex; if (aniMap[seriesIndex] && !aniMap[seriesIndex][3]) { // 有数据删除才有移动的动画 if (self.shapeList[i]._main) { pointList = self.shapeList[i].style.pointList; // 主线动画 dx = Math.abs(pointList[0][0] - pointList[1][0]); dy = Math.abs(pointList[0][1] - pointList[1][1]); isHorizontal = self.shapeList[i]._orient == 'horizontal'; if (aniMap[seriesIndex][2]) { // 队头加入删除末尾 if (self.shapeList[i].shape == 'polygon') { //区域图 var len = pointList.length; self.shapeList[i].style.pointList[len - 3] = pointList[len - 2]; isHorizontal ? (self.shapeList[i].style.pointList[len - 3][0] = pointList[len - 4][0] ) : (self.shapeList[i].style.pointList[len - 3][1] = pointList[len - 4][1] ); self.shapeList[i].style.pointList[len - 2] = pointList[len - 1]; } self.shapeList[i].style.pointList.pop(); isHorizontal ? (x = dx, y = 0) : (x = 0, y = -dy); } else { // 队尾加入删除头部 self.shapeList[i].style.pointList.shift(); if (self.shapeList[i].shape == 'polygon') { //区域图 var targetPoint = self.shapeList[i].style.pointList.pop(); isHorizontal ? (targetPoint[0] = pointList[0][0]) : (targetPoint[1] = pointList[0][1]); self.shapeList[i].style.pointList.push( targetPoint ); } isHorizontal ? (x = -dx, y = 0) : (x = 0, y = dy); } zr.modShape( self.shapeList[i].id, { style : { pointList: self.shapeList[i].style.pointList } }, true ); } else { // 拐点动画 if (aniMap[seriesIndex][2] && self.shapeList[i]._dataIndex == series[seriesIndex].data.length - 1 ) { // 队头加入删除末尾 zr.delShape(self.shapeList[i].id); continue; } else if (!aniMap[seriesIndex][2] && self.shapeList[i]._dataIndex === 0 ) { // 队尾加入删除头部 zr.delShape(self.shapeList[i].id); continue; } } zr.animate(self.shapeList[i].id, '') .when( 500, {position : [x, y]} ) .start(); } } } /** * 动画设定 */ function animation() { var duration = self.query(option, 'animationDuration'); var easing = self.query(option, 'animationEasing'); var x; var y; var serie; var dataIndex = 0; for (var i = 0, l = self.shapeList.length; i < l; i++) { if (self.shapeList[i]._main) { serie = series[self.shapeList[i]._seriesIndex]; dataIndex += 1; x = self.shapeList[i].style.pointList[0][0]; y = self.shapeList[i].style.pointList[0][1]; if (self.shapeList[i]._orient == 'horizontal') { zr.modShape( self.shapeList[i].id, { scale : [0, 1, x, y] }, true ); } else { zr.modShape( self.shapeList[i].id, { scale : [1, 0, x, y] }, true ); } zr.animate(self.shapeList[i].id, '') .when( (self.query(serie,'animationDuration') || duration) + dataIndex * 100, {scale : [1, 1, x, y]} ) .start( self.query(serie, 'animationEasing') || easing ); } } self.animationMark(duration, easing); } // 重载基类方法 self.getMarkCoord = getMarkCoord; self.animation = animation; self.init = init; self.refresh = refresh; self.ontooltipHover = ontooltipHover; self.addDataAnimation = addDataAnimation; init(option, component); } function legendLineIcon(ctx, style) { var x = style.x; var y = style.y; var width = style.width; var height = style.height; var dy = height / 2; if (style.symbol.match('empty')) { ctx.fillStyle = '#fff'; } style.brushType = 'both'; var symbol = style.symbol.replace('empty', '').toLowerCase(); if (symbol.match('star')) { dy = (symbol.replace('star','') - 0) || 5; y -= 1; symbol = 'star'; } else if (symbol == 'rectangle' || symbol == 'arrow') { x += (width - height) / 2; width = height; } var imageLocation = ''; if (symbol.match('image')) { imageLocation = symbol.replace( new RegExp('^image:\\/\\/'), '' ); symbol = 'image'; x += Math.round((width - height) / 2) - 1; width = height = height + 2; } symbol = require('zrender/shape').get('icon').get(symbol); if (symbol) { var x2 = style.x; var y2 = style.y; ctx.moveTo(x2, y2 + dy); ctx.lineTo(x2 + 5, y2 + dy); ctx.moveTo(x2 + style.width - 5, y2 + dy); ctx.lineTo(x2 + style.width, y2 + dy); symbol(ctx, { x : x + 4, y : y + 4, width : width - 8, height : height - 8, n : dy, image : imageLocation }); } else { ctx.moveTo(x, y + dy); ctx.lineTo(x + width, y + dy); } } // 动态扩展zrender shape:halfSmoothPolygon require('../util/shape/halfSmoothPolygon'); // 图表注册 require('../chart').define('line', Line); return Line; }); /** * echarts图表类:柱形图 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/chart/bar',['require','../component/base','./calculableBase','../util/ecData','zrender/tool/color','../chart'],function(require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} series 数据 * @param {Object} component 组件 */ function Bar(ecConfig, messageCenter, zr, option, component){ // 基类装饰 var ComponentBase = require('../component/base'); ComponentBase.call(this, ecConfig, zr); // 可计算特性装饰 var CalculableBase = require('./calculableBase'); CalculableBase.call(this, zr, option); var ecData = require('../util/ecData'); var zrColor = require('zrender/tool/color'); var self = this; self.type = ecConfig.CHART_TYPE_BAR; var series; // 共享数据源,不要修改跟自己无关的项 var _zlevelBase = self.getZlevelBase(); var _sIndex2colorMap = {}; // series默认颜色索引,seriesIndex索引到color function _buildShape() { self.selectedMap = {}; // 水平垂直双向series索引 ,position索引到seriesIndex var _position2sIndexMap = { top : [], bottom : [], left : [], right : [] }; var xAxisIndex; var yAxisIndex; var xAxis; var yAxis; for (var i = 0, l = series.length; i < l; i++) { if (series[i].type == ecConfig.CHART_TYPE_BAR) { series[i] = self.reformOption(series[i]); xAxisIndex = series[i].xAxisIndex; yAxisIndex = series[i].yAxisIndex; xAxis = component.xAxis.getAxis(xAxisIndex); yAxis = component.yAxis.getAxis(yAxisIndex); if (xAxis.type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY ) { _position2sIndexMap[xAxis.getPosition()].push(i); } else if (yAxis.type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY ) { _position2sIndexMap[yAxis.getPosition()].push(i); } } } // console.log(_position2sIndexMap) for (var position in _position2sIndexMap) { if (_position2sIndexMap[position].length > 0) { _buildSinglePosition( position, _position2sIndexMap[position] ); } } for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } /** * 构建单个方向上的柱形图 * * @param {number} seriesIndex 系列索引 */ function _buildSinglePosition(position, seriesArray) { var mapData = _mapData(seriesArray); var locationMap = mapData.locationMap; var maxDataLength = mapData.maxDataLength; if (maxDataLength === 0 || locationMap.length === 0) { return; } switch (position) { case 'bottom' : case 'top' : _buildHorizontal(maxDataLength, locationMap, seriesArray); break; case 'left' : case 'right' : _buildVertical(maxDataLength, locationMap, seriesArray); break; } } /** * 数据整形 * 数组位置映射到系列索引 */ function _mapData(seriesArray) { var serie; // 临时映射变量 var dataIndex = 0; // 堆叠数据所在位置映射 var stackMap = {}; // 堆叠数据位置映射,堆叠组在二维中的第几项 var magicStackKey = '__kener__stack__'; // 堆叠命名,非堆叠数据安单一堆叠处理 var stackKey; // 临时映射变量 var serieName; // 临时映射变量 var legend = component.legend; var locationMap = []; // 需要返回的东西:数组位置映射到系列索引 var maxDataLength = 0; // 需要返回的东西:最大数据长度 var iconShape; // 计算需要显示的个数和分配位置并记在下面这个结构里 for (var i = 0, l = seriesArray.length; i < l; i++) { serie = series[seriesArray[i]]; serieName = serie.name; if (legend){ self.selectedMap[serieName] = legend.isSelected(serieName); _sIndex2colorMap[seriesArray[i]] = legend.getColor(serieName); iconShape = legend.getItemShape(serieName); if (iconShape) { // 回调legend,换一个更形象的icon if (serie.itemStyle.normal.borderWidth > 0) { iconShape.style.x += 1; iconShape.style.y += 1; iconShape.style.width -= 2; iconShape.style.height -= 2; iconShape.style.strokeColor = iconShape.highlightStyle.strokeColor = serie.itemStyle.normal.borderColor; iconShape.highlightStyle.lineWidth = 3; iconShape.style.brushType = 'both'; } legend.setItemShape(serieName, iconShape); } } else { self.selectedMap[serieName] = true; _sIndex2colorMap[seriesArray[i]] = zr.getColor(seriesArray[i]); } if (self.selectedMap[serieName]) { stackKey = serie.stack || (magicStackKey + seriesArray[i]); if (typeof stackMap[stackKey] == 'undefined') { stackMap[stackKey] = dataIndex; locationMap[dataIndex] = [seriesArray[i]]; dataIndex++; } else { // 已经分配了位置就推进去就行 locationMap[stackMap[stackKey]].push(seriesArray[i]); } } // 兼职帮算一下最大长度 maxDataLength = Math.max(maxDataLength, serie.data.length); } /* 调试输出 var s = ''; for (var i = 0, l = maxDataLength; i < l; i++) { s = '['; for (var j = 0, k = locationMap.length; j < k; j++) { s +='[' for (var m = 0, n = locationMap[j].length - 1; m < n; m++) { s += series[locationMap[j][m]].data[i] + ',' } s += series[locationMap[j][locationMap[j].length - 1]] .data[i]; s += ']' } s += ']'; console.log(s); } console.log(locationMap) */ return { locationMap : locationMap, maxDataLength : maxDataLength }; } /** * 构建类目轴为水平方向的柱形图系列 */ function _buildHorizontal(maxDataLength, locationMap, seriesArray) { // 确定类目轴和数值轴,同一方向随便找一个即可 var seriesIndex = locationMap[0][0]; var serie = series[seriesIndex]; var xAxisIndex = serie.xAxisIndex; var categoryAxis = component.xAxis.getAxis(xAxisIndex); var yAxisIndex; // 数值轴各异 var valueAxis; // 数值轴各异 var size = _mapSize(categoryAxis, locationMap); var gap = size.gap; var barGap = size.barGap; var barWidthMap = size.barWidthMap; var barWidth = size.barWidth; // 自适应宽度 var barMinHeightMap = size.barMinHeightMap; var barHeight; var xMarkMap = {}; // 为标注记录一些参数 var x; var y; var lastYP; // 正向堆叠处理 var baseYP; var lastYN; // 负向堆叠处理 var baseYN; var barShape; var data; var value; for (var i = 0, l = maxDataLength; i < l; i++) { if (typeof categoryAxis.getNameByIndex(i) == 'undefined') { // 系列数据超出类目轴长度 break; } x = categoryAxis.getCoordByIndex(i) - gap / 2; for (var j = 0, k = locationMap.length; j < k; j++) { // 堆叠数据用第一条valueAxis yAxisIndex = series[locationMap[j][0]].yAxisIndex || 0; valueAxis = component.yAxis.getAxis(yAxisIndex); baseYP = lastYP = baseYN = lastYN = valueAxis.getCoord(0); for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; serie = series[seriesIndex]; data = serie.data[i]; value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; if (value == '-') { // 空数据在做完后补充拖拽提示框 continue; } //y = valueAxis.getCoord(value); if (value > 0) { // 正向堆叠 //barHeight = baseYP - y; barHeight = m > 0 ? valueAxis.getCoordSize(value) : (baseYP - valueAxis.getCoord(value)); // 非堆叠数据最小高度有效 if (n == 1 && barMinHeightMap[seriesIndex] > barHeight ) { barHeight = barMinHeightMap[seriesIndex]; } lastYP -= barHeight; y = lastYP; } else if (value < 0){ // 负向堆叠 //barHeight = y - baseYN; barHeight = m > 0 ? valueAxis.getCoordSize(value) : (valueAxis.getCoord(value) - baseYN); // 非堆叠数据最小高度有效 if (n == 1 && barMinHeightMap[seriesIndex] > barHeight ) { barHeight = barMinHeightMap[seriesIndex]; } y = lastYN; lastYN += barHeight; } else { // 0值 barHeight = 0;//baseYP - y; // 最小高度无效 lastYP -= barHeight; y = lastYP; } barShape = _getBarItem( seriesIndex, i, categoryAxis.getNameByIndex(i), x, y, barWidthMap[seriesIndex] || barWidth, barHeight, 'vertical' ); xMarkMap[seriesIndex] = xMarkMap[seriesIndex] || { min : Number.POSITIVE_INFINITY, max : Number.NEGATIVE_INFINITY, sum : 0, counter : 0, average : 0 }; xMarkMap[seriesIndex][i] = x + (barWidthMap[seriesIndex] || barWidth) / 2; if (xMarkMap[seriesIndex].min > value) { xMarkMap[seriesIndex].min = value; xMarkMap[seriesIndex].minY = y; xMarkMap[seriesIndex].minX = xMarkMap[seriesIndex][i]; } if (xMarkMap[seriesIndex].max < value) { xMarkMap[seriesIndex].max = value; xMarkMap[seriesIndex].maxY = y; xMarkMap[seriesIndex].maxX = xMarkMap[seriesIndex][i]; } xMarkMap[seriesIndex].sum += value; xMarkMap[seriesIndex].counter++; self.shapeList.push(barShape); } // 补充空数据的拖拽提示框 for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; serie = series[seriesIndex]; data = serie.data[i]; value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; if (value != '-') { // 只关心空数据 continue; } if (self.deepQuery( [data, serie, option], 'calculable' ) ) { lastYP -= ecConfig.island.r; y = lastYP; barShape = _getBarItem( seriesIndex, i, categoryAxis.getNameByIndex(i), x + 0.5, y + 0.5, (barWidthMap[seriesIndex] || barWidth) - 1, ecConfig.island.r - 1, 'vertical' ); barShape.hoverable = false; barShape.draggable = false; barShape.style.lineWidth = 1; barShape.style.brushType = 'stroke'; barShape.style.strokeColor = serie.calculableHolderColor || ecConfig.calculableHolderColor; self.shapeList.push(barShape); } } x += ((barWidthMap[seriesIndex] || barWidth) + barGap); } } for (var j = 0, k = locationMap.length; j < k; j++) { for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; xMarkMap[seriesIndex].average = (xMarkMap[seriesIndex].sum / xMarkMap[seriesIndex].counter).toFixed(2) - 0; y = component.yAxis.getAxis(series[seriesIndex].yAxisIndex || 0) .getCoord(xMarkMap[seriesIndex].average); xMarkMap[seriesIndex].averageLine = [ [component.grid.getX(), y], [component.grid.getXend(), y] ]; xMarkMap[seriesIndex].minLine = [ [component.grid.getX(), xMarkMap[seriesIndex].minY], [component.grid.getXend(), xMarkMap[seriesIndex].minY] ]; xMarkMap[seriesIndex].maxLine = [ [component.grid.getX(), xMarkMap[seriesIndex].maxY], [component.grid.getXend(), xMarkMap[seriesIndex].maxY] ]; } } _buildMark(seriesArray, xMarkMap, true); } /** * 构建类目轴为垂直方向的柱形图系列 */ function _buildVertical(maxDataLength, locationMap, seriesArray) { // 确定类目轴和数值轴,同一方向随便找一个即可 var seriesIndex = locationMap[0][0]; var serie = series[seriesIndex]; var yAxisIndex = serie.yAxisIndex; var categoryAxis = component.yAxis.getAxis(yAxisIndex); var xAxisIndex; // 数值轴各异 var valueAxis; // 数值轴各异 var size = _mapSize(categoryAxis, locationMap); var gap = size.gap; var barGap = size.barGap; var barWidthMap = size.barWidthMap; var barWidth = size.barWidth; // 自适应宽度 var barMinHeightMap = size.barMinHeightMap; var barHeight; var xMarkMap = {}; // 为标注记录一个横向偏移 var x; var y; var lastXP; // 正向堆叠处理 var baseXP; var lastXN; // 负向堆叠处理 var baseXN; var barShape; var data; var value; for (var i = 0, l = maxDataLength; i < l; i++) { if (typeof categoryAxis.getNameByIndex(i) == 'undefined') { // 系列数据超出类目轴长度 break; } y = categoryAxis.getCoordByIndex(i) + gap / 2; for (var j = 0, k = locationMap.length; j < k; j++) { // 堆叠数据用第一条valueAxis xAxisIndex = series[locationMap[j][0]].xAxisIndex || 0; valueAxis = component.xAxis.getAxis(xAxisIndex); baseXP = lastXP = baseXN = lastXN = valueAxis.getCoord(0); for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; serie = series[seriesIndex]; data = serie.data[i]; value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; if (value == '-') { // 空数据在做完后补充拖拽提示框 continue; } //x = valueAxis.getCoord(value); if (value > 0) { // 正向堆叠 //barHeight = x - baseXP; barHeight = m > 0 ? valueAxis.getCoordSize(value) : (valueAxis.getCoord(value) - baseXP); // 非堆叠数据最小高度有效 if (n == 1 && barMinHeightMap[seriesIndex] > barHeight ) { barHeight = barMinHeightMap[seriesIndex]; } x = lastXP; lastXP += barHeight; } else if (value < 0){ // 负向堆叠 //barHeight = baseXN - x; barHeight = m > 0 ? valueAxis.getCoordSize(value) : (baseXN - valueAxis.getCoord(value)); // 非堆叠数据最小高度有效 if (n == 1 && barMinHeightMap[seriesIndex] > barHeight ) { barHeight = barMinHeightMap[seriesIndex]; } lastXN -= barHeight; x = lastXN; } else { // 0值 barHeight = 0;//x - baseXP; // 最小高度无效 x = lastXP; lastXP += barHeight; } barShape = _getBarItem( seriesIndex, i, categoryAxis.getNameByIndex(i), x, y - (barWidthMap[seriesIndex] || barWidth), barHeight, barWidthMap[seriesIndex] || barWidth, 'horizontal' ); xMarkMap[seriesIndex] = xMarkMap[seriesIndex] || { min : Number.POSITIVE_INFINITY, max : Number.NEGATIVE_INFINITY, sum : 0, counter : 0, average : 0 }; xMarkMap[seriesIndex][i] = y - (barWidthMap[seriesIndex] || barWidth) / 2; if (xMarkMap[seriesIndex].min > value) { xMarkMap[seriesIndex].min = value; xMarkMap[seriesIndex].minX = x + barHeight; xMarkMap[seriesIndex].minY = xMarkMap[seriesIndex][i]; } if (xMarkMap[seriesIndex].max < value) { xMarkMap[seriesIndex].max = value; xMarkMap[seriesIndex].maxX = x + barHeight; xMarkMap[seriesIndex].maxY = xMarkMap[seriesIndex][i]; } xMarkMap[seriesIndex].sum += value; xMarkMap[seriesIndex].counter++; self.shapeList.push(barShape); } // 补充空数据的拖拽提示框 for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; serie = series[seriesIndex]; data = serie.data[i]; value = typeof data != 'undefined' ? (typeof data.value != 'undefined' ? data.value : data) : '-'; if (value != '-') { // 只关心空数据 continue; } if (self.deepQuery( [data, serie, option], 'calculable' ) ) { x = lastXP; lastXP += ecConfig.island.r; barShape = _getBarItem( seriesIndex, i, categoryAxis.getNameByIndex(i), x + 0.5, y + 0.5 - (barWidthMap[seriesIndex] || barWidth), ecConfig.island.r - 1, (barWidthMap[seriesIndex] || barWidth) - 1, 'horizontal' ); barShape.hoverable = false; barShape.draggable = false; barShape.style.lineWidth = 1; barShape.style.brushType = 'stroke'; barShape.style.strokeColor = serie.calculableHolderColor || ecConfig.calculableHolderColor; self.shapeList.push(barShape); } } y -= ((barWidthMap[seriesIndex] || barWidth) + barGap); } } for (var j = 0, k = locationMap.length; j < k; j++) { for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; xMarkMap[seriesIndex].average = xMarkMap[seriesIndex].sum / xMarkMap[seriesIndex].counter; x = component.xAxis.getAxis(series[seriesIndex].xAxisIndex || 0) .getCoord(xMarkMap[seriesIndex].average); xMarkMap[seriesIndex].averageLine = [ [x, component.grid.getYend()], [x, component.grid.getY()] ]; xMarkMap[seriesIndex].minLine = [ [xMarkMap[seriesIndex].minX, component.grid.getYend()], [xMarkMap[seriesIndex].minX, component.grid.getY()] ]; xMarkMap[seriesIndex].maxLine = [ [xMarkMap[seriesIndex].maxX, component.grid.getYend()], [xMarkMap[seriesIndex].maxX, component.grid.getY()] ]; } } _buildMark(seriesArray, xMarkMap, false); } /** * 我真是自找麻烦啊,为啥要允许系列级个性化最小宽度和高度啊!!! * @param {CategoryAxis} categoryAxis 类目坐标轴,需要知道类目间隔大小 * @param {Array} locationMap 整形数据的系列索引 */ function _mapSize(categoryAxis, locationMap, ignoreUserDefined) { var barWidthMap = {}; var barMinHeightMap = {}; var sBarWidth; var sBarWidthCounter = 0; var sBarWidthTotal = 0; var barGap; var barCategoryGap; var hasFound; var queryTarget; for (var j = 0, k = locationMap.length; j < k; j++) { hasFound = false; // 同一堆叠第一个barWidth生效 for (var m = 0, n = locationMap[j].length; m < n; m++) { seriesIndex = locationMap[j][m]; queryTarget = series[seriesIndex]; if (!ignoreUserDefined) { if (!hasFound) { sBarWidth = self.query( queryTarget, 'barWidth' ); if (typeof sBarWidth != 'undefined') { // 同一堆叠第一个生效barWidth barWidthMap[seriesIndex] = sBarWidth; sBarWidthTotal += sBarWidth; sBarWidthCounter++; hasFound = true; // 复位前面同一堆叠但没被定义的 for (var ii = 0, ll = m; ii < ll; ii++) { var pSeriesIndex = locationMap[j][ii]; barWidthMap[pSeriesIndex] = sBarWidth; } } } else { barWidthMap[seriesIndex] = sBarWidth; // 用找到的一个 } } barMinHeightMap[seriesIndex] = self.query( queryTarget, 'barMinHeight' ); barGap = typeof barGap != 'undefined' ? barGap : self.query( queryTarget, 'barGap' ); barCategoryGap = typeof barCategoryGap != 'undefined' ? barCategoryGap : self.query( queryTarget, 'barCategoryGap' ); } } var gap; var barWidth; if (locationMap.length != sBarWidthCounter) { // 至少存在一个自适应宽度的柱形图 if (!ignoreUserDefined) { gap = typeof barCategoryGap == 'string' && barCategoryGap.match(/%$/) // 百分比 ? Math.floor( categoryAxis.getGap() * (100 - parseFloat(barCategoryGap)) / 100 ) // 数值 : (categoryAxis.getGap() - barCategoryGap); if (typeof barGap == 'string' && barGap.match(/%$/)) { barGap = parseFloat(barGap) / 100; barWidth = Math.floor( (gap - sBarWidthTotal) / ((locationMap.length - 1) * barGap + locationMap.length - sBarWidthCounter) ); barGap = Math.floor(barWidth * barGap); } else { barGap = parseFloat(barGap); barWidth = Math.floor( (gap - sBarWidthTotal - barGap * (locationMap.length - 1) ) / (locationMap.length - sBarWidthCounter) ); } // 无法满足用户定义的宽度设计,忽略用户宽度,打回重做 if (barWidth < 0) { return _mapSize(categoryAxis, locationMap, true); } } else { // 忽略用户定义的宽度设定 gap = categoryAxis.getGap(); barGap = 0; barWidth = Math.floor(gap / locationMap.length); // 已经忽略用户定义的宽度设定依然还无法满足显示,只能硬来了; if (barWidth < 0) { barWidth = 1; } } } else { // 全是自定义宽度,barGap无效,系列间隔决定barGap gap = sBarWidthCounter > 1 ? (typeof barCategoryGap == 'string' && barCategoryGap.match(/%$/) ) // 百分比 ? Math.floor( categoryAxis.getGap() * (100 - parseFloat(barCategoryGap)) / 100 ) // 数值 : (categoryAxis.getGap() - barCategoryGap) // 只有一个 : sBarWidthTotal; barWidth = 0; barGap = sBarWidthCounter > 1 ? Math.floor( (gap - sBarWidthTotal) / (sBarWidthCounter - 1) ) : 0; if (barGap < 0) { // 无法满足用户定义的宽度设计,忽略用户宽度,打回重做 return _mapSize(categoryAxis, locationMap, true); } } return { barWidthMap : barWidthMap, barMinHeightMap : barMinHeightMap , gap : gap, barWidth : barWidth, barGap : barGap }; } /** * 生成最终图形数据 */ function _getBarItem( seriesIndex, dataIndex, name, x, y, width, height, orient ) { var barShape; var serie = series[seriesIndex]; var data = serie.data[dataIndex]; // 多级控制 var defaultColor = _sIndex2colorMap[seriesIndex]; var queryTarget = [data, serie]; var normalColor = self.deepQuery( queryTarget, 'itemStyle.normal.color' ) || defaultColor; var emphasisColor = self.deepQuery( queryTarget, 'itemStyle.emphasis.color' ); var normal = self.deepMerge( queryTarget, 'itemStyle.normal' ); var normalBorderWidth = normal.borderWidth; var emphasis = self.deepMerge( queryTarget, 'itemStyle.emphasis' ); barShape = { shape : 'rectangle', zlevel : _zlevelBase, clickable: true, style : { x : x, y : y, width : width, height : height, brushType : 'both', color : self.getItemStyleColor(normalColor, seriesIndex, dataIndex, data), radius : normal.borderRadius, lineWidth : normalBorderWidth, strokeColor : normal.borderColor }, highlightStyle : { color : self.getItemStyleColor(emphasisColor, seriesIndex, dataIndex, data), radius : emphasis.borderRadius, lineWidth : emphasis.borderWidth, strokeColor : emphasis.borderColor }, _orient : orient }; barShape.highlightStyle.color = barShape.highlightStyle.color || (typeof barShape.style.color == 'string' ? zrColor.lift(barShape.style.color, -0.3) : barShape.style.color ); // 考虑线宽的显示优化 if (normalBorderWidth > 0 && barShape.style.height > normalBorderWidth && barShape.style.width > normalBorderWidth ) { barShape.style.y += normalBorderWidth / 2; barShape.style.height -= normalBorderWidth; barShape.style.x += normalBorderWidth / 2; barShape.style.width -= normalBorderWidth; } else { // 太小了或者线宽小于0,废了边线 barShape.style.brushType = 'fill'; } barShape.highlightStyle.textColor = barShape.highlightStyle.color; barShape = self.addLabel(barShape, serie, data, name, orient); if (self.deepQuery([data, serie, option],'calculable')) { self.setCalculable(barShape); barShape.draggable = true; } ecData.pack( barShape, series[seriesIndex], seriesIndex, series[seriesIndex].data[dataIndex], dataIndex, name ); return barShape; } // 添加标注 function _buildMark(seriesArray, xMarkMap ,isHorizontal) { for (var i = 0, l = seriesArray.length; i < l; i++) { self.buildMark( series[seriesArray[i]], seriesArray[i], component, { isHorizontal : isHorizontal, xMarkMap : xMarkMap } ); } } // 位置转换 function getMarkCoord(serie, seriesIndex, mpData, markCoordParams) { var xAxis = component.xAxis.getAxis(serie.xAxisIndex); var yAxis = component.yAxis.getAxis(serie.yAxisIndex); var dataIndex; var pos; if (mpData.type && (mpData.type == 'max' || mpData.type == 'min' || mpData.type == 'average') ) { // 特殊值内置支持 pos = [ markCoordParams.xMarkMap[seriesIndex][mpData.type + 'X'], markCoordParams.xMarkMap[seriesIndex][mpData.type + 'Y'], markCoordParams.xMarkMap[seriesIndex][mpData.type + 'Line'], markCoordParams.xMarkMap[seriesIndex][mpData.type] ]; } else if (markCoordParams.isHorizontal) { // 横向 dataIndex = typeof mpData.xAxis == 'string' && xAxis.getIndexByName ? xAxis.getIndexByName(mpData.xAxis) : (mpData.xAxis || 0); pos = [ markCoordParams.xMarkMap[seriesIndex][dataIndex], yAxis.getCoord(mpData.yAxis || 0) ]; } else { // 纵向 dataIndex = typeof mpData.yAxis == 'string' && yAxis.getIndexByName ? yAxis.getIndexByName(mpData.yAxis) : (mpData.yAxis || 0); pos = [ xAxis.getCoord(mpData.xAxis || 0), markCoordParams.xMarkMap[seriesIndex][dataIndex] ]; } return pos; } /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newSeries * @param {Object} newComponent */ function init(newOption, newComponent) { component = newComponent; refresh(newOption); } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; series = option.series; } self.clear(); _buildShape(); } /** * 动态数据增加动画 */ function addDataAnimation(params) { var aniMap = {}; // seriesIndex索引参数 for (var i = 0, l = params.length; i < l; i++) { aniMap[params[i][0]] = params[i]; } var x; var dx; var y; var dy; var serie; var seriesIndex; var dataIndex; for (var i = self.shapeList.length - 1; i >= 0; i--) { seriesIndex = ecData.get(self.shapeList[i], 'seriesIndex'); if (aniMap[seriesIndex] && !aniMap[seriesIndex][3]) { // 有数据删除才有移动的动画 if (self.shapeList[i].shape == 'rectangle') { // 主动画 dataIndex = ecData.get(self.shapeList[i], 'dataIndex'); serie = series[seriesIndex]; if (aniMap[seriesIndex][2] && dataIndex == serie.data.length - 1 ) { // 队头加入删除末尾 zr.delShape(self.shapeList[i].id); continue; } else if (!aniMap[seriesIndex][2] && dataIndex === 0) { // 队尾加入删除头部 zr.delShape(self.shapeList[i].id); continue; } if (self.shapeList[i]._orient == 'horizontal') { // 条形图 dy = component.yAxis.getAxis( serie.yAxisIndex || 0 ).getGap(); y = aniMap[seriesIndex][2] ? -dy : dy; x = 0; } else { // 柱形图 dx = component.xAxis.getAxis( serie.xAxisIndex || 0 ).getGap(); x = aniMap[seriesIndex][2] ? dx : -dx; y = 0; } zr.animate(self.shapeList[i].id, '') .when( 500, {position : [x, y]} ) .start(); } } } } /** * 动画设定 */ function animation() { var duration; var easing; var width; var height; var x; var y; var serie; var dataIndex; var value; for (var i = 0, l = self.shapeList.length; i < l; i++) { if (self.shapeList[i].shape == 'rectangle') { serie = ecData.get(self.shapeList[i], 'series'); dataIndex = ecData.get(self.shapeList[i], 'dataIndex'); value = ecData.get(self.shapeList[i], 'value'); duration = self.deepQuery( [serie, option], 'animationDuration' ); easing = self.deepQuery( [serie, option], 'animationEasing' ); if (self.shapeList[i]._orient == 'horizontal') { // 条形图 width = self.shapeList[i].style.width; x = self.shapeList[i].style.x; if (value < 0) { zr.modShape( self.shapeList[i].id, { style: { x : x + width, width: 0 } }, true ); zr.animate(self.shapeList[i].id, 'style') .when( duration + dataIndex * 100, { x : x, width : width } ) .start(easing); } else { zr.modShape( self.shapeList[i].id, { style: { width: 0 } }, true ); zr.animate(self.shapeList[i].id, 'style') .when( duration + dataIndex * 100, { width : width } ) .start(easing); } } else { // 柱形图 height = self.shapeList[i].style.height; y = self.shapeList[i].style.y; if (value < 0) { zr.modShape( self.shapeList[i].id, { style: { height: 0 } }, true ); zr.animate(self.shapeList[i].id, 'style') .when( duration + dataIndex * 100, { height : height } ) .start(easing); } else { zr.modShape( self.shapeList[i].id, { style: { y: y + height, height: 0 } }, true ); zr.animate(self.shapeList[i].id, 'style') .when( duration + dataIndex * 100, { y : y, height : height } ) .start(easing); } } } } self.animationMark(duration, easing); } // 重载基类方法 self.getMarkCoord = getMarkCoord; self.animation = animation; self.init = init; self.refresh = refresh; self.addDataAnimation = addDataAnimation; init(option, component); } // 图表注册 require('../chart').define('bar', Bar); return Bar; }); /** * echarts图表类:饼图 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, linzhifeng@baidu.com) * */ define('echarts/chart/pie',['require','../component/base','./calculableBase','../util/ecData','zrender/tool/math','zrender/tool/util','zrender/tool/color','../util/accMath','../chart'],function(require) { /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} series 数据 * @param {Object} component 组件 */ function Pie(ecConfig, messageCenter, zr, option, component){ // 基类装饰 var ComponentBase = require('../component/base'); ComponentBase.call(this, ecConfig, zr); // 可计算特性装饰 var CalculableBase = require('./calculableBase'); CalculableBase.call(this, zr, option); var ecData = require('../util/ecData'); var zrMath = require('zrender/tool/math'); var zrUtil = require('zrender/tool/util'); var zrColor = require('zrender/tool/color'); var self = this; self.type = ecConfig.CHART_TYPE_PIE; var series; // 共享数据源,不要修改跟自己无关的项 var _zlevelBase = self.getZlevelBase(); var _selectedMode; var _selected = {}; function _buildShape() { var legend = component.legend; self.selectedMap = {}; _selected = {}; var center; var radius; var pieCase; // 饼图箱子 _selectedMode = false; var serieName; for (var i = 0, l = series.length; i < l; i++) { if (series[i].type == ecConfig.CHART_TYPE_PIE) { series[i] = self.reformOption(series[i]); serieName = series[i].name || ''; // 系列图例开关 self.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true; if (!self.selectedMap[serieName]) { continue; } center = self.parseCenter(zr, series[i].center); radius = self.parseRadius(zr, series[i].radius); _selectedMode = _selectedMode || series[i].selectedMode; _selected[i] = []; if (self.deepQuery([series[i], option], 'calculable')) { pieCase = { shape : radius[0] <= 10 ? 'circle' : 'ring', zlevel : _zlevelBase, hoverable : false, style : { x : center[0], // 圆心横坐标 y : center[1], // 圆心纵坐标 // 圆环内外半径 r0 : radius[0] <= 10 ? 0 : radius[0] - 10, r : radius[1] + 10, brushType : 'stroke', lineWidth: 1, strokeColor : series[i].calculableHolderColor || ecConfig.calculableHolderColor } }; ecData.pack(pieCase, series[i], i, undefined, -1); self.setCalculable(pieCase); self.shapeList.push(pieCase); } _buildSinglePie(i); self.buildMark( series[i], i, component ); } } for (var i = 0, l = self.shapeList.length; i < l; i++) { self.shapeList[i].id = zr.newShapeId(self.type); zr.addShape(self.shapeList[i]); } } /** * 构建单个饼图 * * @param {number} seriesIndex 系列索引 */ function _buildSinglePie(seriesIndex) { var serie = series[seriesIndex]; var data = serie.data; var legend = component.legend; var itemName; var totalSelected = 0; // 迭代累计选中且非0个数 var totalSelectedValue0 = 0; // 迭代累计选中0只个数 var totalValue = 0; // 迭代累计 var maxValue = Number.NEGATIVE_INFINITY; // 计算需要显示的个数和总值 for (var i = 0, l = data.length; i < l; i++) { itemName = data[i].name; if (legend){ self.selectedMap[itemName] = legend.isSelected(itemName); } else { self.selectedMap[itemName] = true; } if (self.selectedMap[itemName] && !isNaN(data[i].value)) { if (+data[i].value !== 0) { totalSelected++; } else { totalSelectedValue0++; } totalValue += +data[i].value; maxValue = Math.max(maxValue, +data[i].value); } } var percent = 100; var lastPercent; // 相邻细角度优化 var lastAddRadius = 0; var clockWise = serie.clockWise; var startAngle = serie.startAngle.toFixed(2) - 0; var endAngle; var minAngle = serie.minAngle || 0.01; // #bugfixed var totalAngle = 360 - (minAngle * totalSelected) - 0.01 * totalSelectedValue0; var defaultColor; var roseType = serie.roseType; var radius; var r0; // 扇形内半径 var r1; // 扇形外半径 for (var i = 0, l = data.length; i < l; i++){ itemName = data[i].name; if (!self.selectedMap[itemName] || isNaN(data[i].value)) { continue; } // 默认颜色策略 if (legend) { // 有图例则从图例中获取颜色定义 defaultColor = legend.getColor(itemName); } else { // 全局颜色定义 defaultColor = zr.getColor(i); } lastPercent = percent; percent = data[i].value / totalValue; if (roseType != 'area') { endAngle = clockWise ? (startAngle - percent * totalAngle - (percent !== 0 ? minAngle : 0.01)) : (percent * totalAngle + startAngle + (percent !== 0 ? minAngle : 0.01)); } else { endAngle = clockWise ? (startAngle - 360 / l) : (360 / l + startAngle); } endAngle = endAngle.toFixed(2) - 0; percent = (percent * 100).toFixed(2); radius = self.parseRadius(zr, serie.radius); r0 = +radius[0]; r1 = +radius[1]; if (roseType == 'radius') { r1 = data[i].value / maxValue * (r1 - r0) * 0.8 + (r1 - r0) * 0.2 + r0; } else if (roseType == 'area') { r1 = Math.sqrt(data[i].value / maxValue) * (r1 - r0) + r0; } if (clockWise) { var temp; temp = startAngle; startAngle = endAngle; endAngle = temp; } // 当前小角度需要检查前一个是否也是小角度,如果是得调整长度,不能完全避免,但能大大降低覆盖概率 if (i > 0 && percent < 4 // 约15度 && lastPercent < 4 && _needLabel(serie, data[i], false) && self.deepQuery( [data[i], serie], 'itemStyle.normal.label.position' ) != 'center' ) { // 都小就延长,前小后大就缩短 lastAddRadius += (percent < 4 ? 20 : -20); } else { lastAddRadius = 0; } _buildItem( seriesIndex, i, percent, lastAddRadius, // 相邻最小角度优化 data[i].selected, r0, r1, startAngle, endAngle, defaultColor ); if (!clockWise) { startAngle = endAngle; } } } /** * 构建单个扇形及指标 */ function _buildItem( seriesIndex, dataIndex, percent, lastAddRadius, isSelected, r0, r1, startAngle, endAngle, defaultColor ) { // 扇形 var sector = _getSector( seriesIndex, dataIndex, percent, isSelected, r0, r1, startAngle, endAngle, defaultColor ); // 图形需要附加的私有数据 ecData.pack( sector, series[seriesIndex], seriesIndex, series[seriesIndex].data[dataIndex], dataIndex, series[seriesIndex].data[dataIndex].name, percent ); sector._lastAddRadius = lastAddRadius; self.shapeList.push(sector); // 文本标签,需要显示则会有返回 var label = _getLabel( seriesIndex, dataIndex, percent, lastAddRadius, startAngle, endAngle, defaultColor, false ); if (label) { label._dataIndex = dataIndex; self.shapeList.push(label); } // 文本标签视觉引导线,需要显示则会有返回 var labelLine = _getLabelLine( seriesIndex, dataIndex, lastAddRadius, r0, r1, startAngle, endAngle, defaultColor, false ); if (labelLine) { labelLine._dataIndex = dataIndex; self.shapeList.push(labelLine); } } /** * 构建扇形 */ function _getSector( seriesIndex, dataIndex, percent, isSelected, r0, r1, startAngle, endAngle, defaultColor ) { var serie = series[seriesIndex]; var data = serie.data[dataIndex]; var queryTarget = [data, serie]; var center = self.parseCenter(zr, serie.center); // 多级控制 var normal = self.deepMerge( queryTarget, 'itemStyle.normal' ) || {}; var emphasis = self.deepMerge( queryTarget, 'itemStyle.emphasis' ) || {}; var normalColor = self.getItemStyleColor(normal.color, seriesIndex, dataIndex, data) || defaultColor; var emphasisColor = self.getItemStyleColor(emphasis.color, seriesIndex, dataIndex, data) || (typeof normalColor == 'string' ? zrColor.lift(normalColor, -0.2) : normalColor ); var sector = { shape : 'sector', // 扇形 zlevel : _zlevelBase, clickable : true, style : { x : center[0], // 圆心横坐标 y : center[1], // 圆心纵坐标 r0 : r0, // 圆环内半径 r : r1, // 圆环外半径 startAngle : startAngle, endAngle : endAngle, brushType : 'both', color : normalColor, lineWidth : normal.borderWidth, strokeColor : normal.borderColor, lineJoin: 'round' }, highlightStyle : { color : emphasisColor, lineWidth : emphasis.borderWidth, strokeColor : emphasis.borderColor, lineJoin: 'round' }, _seriesIndex : seriesIndex, _dataIndex : dataIndex }; if (isSelected) { var midAngle = ((sector.style.startAngle + sector.style.endAngle) / 2) .toFixed(2) - 0; sector.style._hasSelected = true; sector.style._x = sector.style.x; sector.style._y = sector.style.y; var offset = self.query(serie, 'selectedOffset'); sector.style.x += zrMath.cos(midAngle, true) * offset; sector.style.y -= zrMath.sin(midAngle, true) * offset; _selected[seriesIndex][dataIndex] = true; } else { _selected[seriesIndex][dataIndex] = false; } if (_selectedMode) { sector.onclick = self.shapeHandler.onclick; } if (self.deepQuery([data, serie, option], 'calculable')) { self.setCalculable(sector); sector.draggable = true; } // “normal下不显示,emphasis显示”添加事件响应 if (_needLabel(serie, data, true) // emphasis下显示文本 || _needLabelLine(serie, data, true) // emphasis下显示引导线 ) { sector.onmouseover = self.shapeHandler.onmouseover; } return sector; } /** * 需要显示则会有返回构建好的shape,否则返回undefined */ function _getLabel( seriesIndex, dataIndex, percent, lastAddRadius, startAngle, endAngle, defaultColor, isEmphasis ) { var serie = series[seriesIndex]; var data = serie.data[dataIndex]; // 特定状态下是否需要显示文本标签 if (!_needLabel(serie, data, isEmphasis)) { return; } var status = isEmphasis ? 'emphasis' : 'normal'; // serie里有默认配置,放心大胆的用! var itemStyle = zrUtil.merge( zrUtil.clone(data.itemStyle) || {}, serie.itemStyle, { 'overwrite' : false, 'recursive' : true } ); // label配置 var labelControl = itemStyle[status].label; var textStyle = labelControl.textStyle || {}; var center = self.parseCenter(zr, serie.center); var centerX = center[0]; // 圆心横坐标 var centerY = center[1]; // 圆心纵坐标 var x; var y; var midAngle = ((endAngle + startAngle) / 2 + 360) % 360; // 中值 var radius = self.parseRadius(zr, serie.radius); // 标签位置半径 var textAlign; var textBaseline = 'middle'; labelControl.position = labelControl.position || itemStyle.normal.label.position; if (labelControl.position == 'center') { // center显示 radius = radius[1]; x = centerX; y = centerY; textAlign = 'center'; } else if (labelControl.position == 'inner'){ // 内部显示 radius = (radius[0] + radius[1]) / 2 + lastAddRadius; x = Math.round( centerX + radius * zrMath.cos(midAngle, true) ); y = Math.round( centerY - radius * zrMath.sin(midAngle, true) ); defaultColor = '#fff'; textAlign = 'center'; } else { // 外部显示,默认 labelControl.position == 'outer') radius = radius[1] - (-itemStyle[status].labelLine.length) //- (-textStyle.fontSize) + lastAddRadius; x = centerX + radius * zrMath.cos(midAngle, true); y = centerY - radius * zrMath.sin(midAngle, true); textAlign = (midAngle >= 90 && midAngle <= 270) ? 'right' : 'left'; } if (labelControl.position != 'center' && labelControl.position != 'inner' ) { x += textAlign == 'left' ? 20 : -20; } data.__labelX = x - (textAlign == 'left' ? 5 : -5); data.__labelY = y; return { shape : 'text', zlevel : _zlevelBase + 1, hoverable : false, style : { x : x, y : y, color : textStyle.color || defaultColor, text : _getLabelText( seriesIndex, dataIndex, percent, status ), textAlign : textStyle.align || textAlign, textBaseline : textStyle.baseline || textBaseline, textFont : self.getFont(textStyle) }, highlightStyle : { brushType : 'fill' }, _seriesIndex : seriesIndex, _dataIndex : dataIndex }; } /** * 根据lable.format计算label text */ function _getLabelText(seriesIndex, dataIndex, percent, status) { var serie = series[seriesIndex]; var data = serie.data[dataIndex]; var formatter = self.deepQuery( [data, serie], 'itemStyle.' + status + '.label.formatter' ); if (formatter) { if (typeof formatter == 'function') { return formatter( serie.name, data.name, data.value, percent ); } else if (typeof formatter == 'string') { formatter = formatter.replace('{a}','{a0}') .replace('{b}','{b0}') .replace('{c}','{c0}') .replace('{d}','{d0}'); formatter = formatter.replace('{a0}', serie.name) .replace('{b0}', data.name) .replace('{c0}', data.value) .replace('{d0}', percent); return formatter; } } else { return data.name; } } /** * 需要显示则会有返回构建好的shape,否则返回undefined */ function _getLabelLine( seriesIndex, dataIndex, lastAddRadius, r0, r1, startAngle, endAngle, defaultColor, isEmphasis ) { var serie = series[seriesIndex]; var data = serie.data[dataIndex]; // 特定状态下是否需要显示文本标签 if (_needLabelLine(serie, data, isEmphasis)) { var status = isEmphasis ? 'emphasis' : 'normal'; // serie里有默认配置,放心大胆的用! var itemStyle = zrUtil.merge( zrUtil.clone(data.itemStyle) || {}, serie.itemStyle, { 'overwrite' : false, 'recursive' : true } ); // labelLine配置 var labelLineControl = itemStyle[status].labelLine; var lineStyle = labelLineControl.lineStyle || {}; var center = self.parseCenter(zr, serie.center); var centerX = center[0]; // 圆心横坐标 var centerY = center[1]; // 圆心纵坐标 // 视觉引导线起点半径 var midRadius = r1; // 视觉引导线终点半径 var maxRadius = self.parseRadius(zr, serie.radius)[1] - (-labelLineControl.length) + lastAddRadius; var midAngle = ((endAngle + startAngle) / 2) % 360; // 角度中值 var cosValue = zrMath.cos(midAngle, true); var sinValue = zrMath.sin(midAngle, true); // 三角函数缓存已在zrender/tool/math中做了 return { shape : 'brokenLine', zlevel : _zlevelBase + 1, hoverable : false, style : { pointList : [ [ centerX + midRadius * cosValue, centerY - midRadius * sinValue ], [ centerX + maxRadius * cosValue, centerY - maxRadius * sinValue ], [ data.__labelX, data.__labelY ] ], //xStart : centerX + midRadius * cosValue, //yStart : centerY - midRadius * sinValue, //xEnd : centerX + maxRadius * cosValue, //yEnd : centerY - maxRadius * sinValue, strokeColor : lineStyle.color || defaultColor, lineType : lineStyle.type, lineWidth : lineStyle.width }, _seriesIndex : seriesIndex, _dataIndex : dataIndex }; } else { return; } } /** * 返回特定状态(normal or emphasis)下是否需要显示label标签文本 * @param {Object} serie * @param {Object} data * @param {boolean} isEmphasis true is 'emphasis' and false is 'normal' */ function _needLabel(serie, data, isEmphasis) { return self.deepQuery( [data, serie], 'itemStyle.' + (isEmphasis ? 'emphasis' : 'normal') + '.label.show' ); } /** * 返回特定状态(normal or emphasis)下是否需要显示labelLine标签视觉引导线 * @param {Object} serie * @param {Object} data * @param {boolean} isEmphasis true is 'emphasis' and false is 'normal' */ function _needLabelLine(serie, data, isEmphasis) { return self.deepQuery( [data, serie], 'itemStyle.' + (isEmphasis ? 'emphasis' : 'normal') +'.labelLine.show' ); } /** * 参数修正&默认值赋值,重载基类方法 * @param {Object} opt 参数 */ function reformOption(opt) { // 常用方法快捷方式 var _merge = zrUtil.merge; opt = _merge( opt || {}, ecConfig.pie, { 'overwrite' : false, 'recursive' : true } ); // 通用字体设置 opt.itemStyle.normal.label.textStyle = _merge( opt.itemStyle.normal.label.textStyle || {}, ecConfig.textStyle, { 'overwrite' : false, 'recursive' : true } ); opt.itemStyle.emphasis.label.textStyle = _merge( opt.itemStyle.emphasis.label.textStyle || {}, ecConfig.textStyle, { 'overwrite' : false, 'recursive' : true } ); return opt; } /** * 构造函数默认执行的初始化方法,也用于创建实例后动态修改 * @param {Object} newSeries * @param {Object} newComponent */ function init(newOption, newComponent) { component = newComponent; refresh(newOption); } /** * 刷新 */ function refresh(newOption) { if (newOption) { option = newOption; series = option.series; } self.clear(); _buildShape(); } /** * 动态数据增加动画 * 心跳效果 function addDataAnimation(params) { var aniMap = {}; // seriesIndex索引参数 for (var i = 0, l = params.length; i < l; i++) { aniMap[params[i][0]] = params[i]; } var x; var y; var r; var seriesIndex; for (var i = self.shapeList.length - 1; i >= 0; i--) { seriesIndex = ecData.get(self.shapeList[i], 'seriesIndex'); if (aniMap[seriesIndex]) { if (self.shapeList[i].shape == 'sector' || self.shapeList[i].shape == 'circle' || self.shapeList[i].shape == 'ring' ) { r = self.shapeList[i].style.r; zr.animate(self.shapeList[i].id, 'style') .when( 300, {r : r * 0.9} ) .when( 500, {r : r} ) .start(); } } } } */ /** * 动态数据增加动画 */ function addDataAnimation(params) { var aniMap = {}; // seriesIndex索引参数 for (var i = 0, l = params.length; i < l; i++) { aniMap[params[i][0]] = params[i]; } // 构建新的饼图匹配差异做动画 var sectorMap = {}; var textMap = {}; var lineMap = {}; var backupShapeList = zrUtil.clone(self.shapeList); self.shapeList = []; var seriesIndex; var isHead; var dataGrow; var deltaIdxMap = {}; // 修正新增数据后会对dataIndex产生错位匹配 for (var i = 0, l = params.length; i < l; i++) { seriesIndex = params[i][0]; isHead = params[i][2]; dataGrow = params[i][3]; if (series[seriesIndex] && series[seriesIndex].type == ecConfig.CHART_TYPE_PIE ) { if (isHead) { if (!dataGrow) { sectorMap[ seriesIndex + '_' + series[seriesIndex].data.length ] = 'delete'; } deltaIdxMap[seriesIndex] = 1; } else { if (!dataGrow) { sectorMap[seriesIndex + '_-1'] = 'delete'; deltaIdxMap[seriesIndex] = -1; } else { deltaIdxMap[seriesIndex] = 0; } } _buildSinglePie(seriesIndex); } } var dataIndex; var key; for (var i = 0, l = self.shapeList.length; i < l; i++) { seriesIndex = self.shapeList[i]._seriesIndex; dataIndex = self.shapeList[i]._dataIndex; key = seriesIndex + '_' + dataIndex; // map映射让n*n变n switch (self.shapeList[i].shape) { case 'sector' : sectorMap[key] = self.shapeList[i]; break; case 'text' : textMap[key] = self.shapeList[i]; break; case 'line' : lineMap[key] = self.shapeList[i]; break; } } self.shapeList = []; var targeSector; for (var i = 0, l = backupShapeList.length; i < l; i++) { seriesIndex = backupShapeList[i]._seriesIndex; if (aniMap[seriesIndex]) { dataIndex = backupShapeList[i]._dataIndex + deltaIdxMap[seriesIndex]; key = seriesIndex + '_' + dataIndex; targeSector = sectorMap[key]; if (!targeSector) { continue; } if (backupShapeList[i].shape == 'sector') { if (targeSector != 'delete') { // 原有扇形 zr.animate(backupShapeList[i].id, 'style') .when( 400, { startAngle : targeSector.style.startAngle, endAngle : targeSector.style.endAngle } ) .start(); } else { // 删除的扇形 zr.animate(backupShapeList[i].id, 'style') .when( 400, deltaIdxMap[seriesIndex] < 0 ? { endAngle : backupShapeList[i].style.startAngle } : { startAngle : backupShapeList[i].style.endAngle } ) .start(); } } else if (backupShapeList[i].shape == 'text' || backupShapeList[i].shape == 'line' ) { if (targeSector == 'delete') { // 删除逻辑一样 zr.delShape(backupShapeList[i].id); } else { // 懒得新建变量了,借用一下 switch (backupShapeList[i].shape) { case 'text': targeSector = textMap[key]; zr.animate(backupShapeList[i].id, 'style') .when( 400, { x :targeSector.style.x, y :targeSector.style.y } ) .start(); break; case 'line': targeSector = lineMap[key]; zr.animate(backupShapeList[i].id, 'style') .when( 400, { xStart:targeSector.style.xStart, yStart:targeSector.style.yStart, xEnd : targeSector.style.xEnd, yEnd : targeSector.style.yEnd } ) .start(); break; } } } } } self.shapeList = backupShapeList; } /** * 动画设定 */ function animation() { var duration = self.query(option, 'animationDuration'); var easing = self.query(option, 'animationEasing'); var x; var y; var r0; var r; var serie; var dataIndex; for (var i = 0, l = self.shapeList.length; i < l; i++) { if (self.shapeList[i].shape == 'sector' || self.shapeList[i].shape == 'circle' || self.shapeList[i].shape == 'ring' ) { x = self.shapeList[i].style.x; y = self.shapeList[i].style.y; r0 = self.shapeList[i].style.r0; r = self.shapeList[i].style.r; zr.modShape( self.shapeList[i].id, { rotation : [Math.PI*2, x, y], style : { r0 : 0, r : 0 } }, true ); serie = ecData.get(self.shapeList[i], 'series'); dataIndex = ecData.get(self.shapeList[i], 'dataIndex'); zr.animate(self.shapeList[i].id, 'style') .when( (self.query(serie,'animationDuration') || duration) + dataIndex * 10, { r0 : r0, r : r } ) .start('QuinticOut'); zr.animate(self.shapeList[i].id, '') .when( (self.query(serie,'animationDuration') || duration) + dataIndex * 100, {rotation : [0, x, y]} ) .start( self.query(serie, 'animationEasing') || easing ); } else if (!self.shapeList[i]._mark){ dataIndex = self.shapeList[i]._dataIndex; zr.modShape( self.shapeList[i].id, { scale : [0, 0, x, y] }, true ); zr.animate(self.shapeList[i].id, '') .when( duration + dataIndex * 100, {scale : [1, 1, x, y]} ) .start('QuinticOut'); } } self.animationMark(duration, easing); } function onclick(param) { if (!self.isClick || !param.target) { // 没有在当前实例上发生点击直接返回 return; } var offset; // 偏移 var target = param.target; var style = target.style; var seriesIndex = ecData.get(target, 'seriesIndex'); var dataIndex = ecData.get(target, 'dataIndex'); for (var i = 0, len = self.shapeList.length; i < len; i++) { if (self.shapeList[i].id == target.id) { seriesIndex = ecData.get(target, 'seriesIndex'); dataIndex = ecData.get(target, 'dataIndex'); // 当前点击的 if (!style._hasSelected) { var midAngle = ((style.startAngle + style.endAngle) / 2) .toFixed(2) - 0; target.style._hasSelected = true; _selected[seriesIndex][dataIndex] = true; target.style._x = target.style.x; target.style._y = target.style.y; offset = self.query( series[seriesIndex], 'selectedOffset' ); target.style.x += zrMath.cos(midAngle, true) * offset; target.style.y -= zrMath.sin(midAngle, true) * offset; } else { // 复位 target.style.x = target.style._x; target.style.y = target.style._y; target.style._hasSelected = false; _selected[seriesIndex][dataIndex] = false; } zr.modShape(target.id, target); } else if (self.shapeList[i].style._hasSelected && _selectedMode == 'single' ) { seriesIndex = ecData.get(self.shapeList[i], 'seriesIndex'); dataIndex = ecData.get(self.shapeList[i], 'dataIndex'); // 单选模式下需要取消其他已经选中的 self.shapeList[i].style.x = self.shapeList[i].style._x; self.shapeList[i].style.y = self.shapeList[i].style._y; self.shapeList[i].style._hasSelected = false; _selected[seriesIndex][dataIndex] = false; zr.modShape( self.shapeList[i].id, self.shapeList[i] ); } } messageCenter.dispatch( ecConfig.EVENT.PIE_SELECTED, param.event, {selected : _selected} ); zr.refresh(); } /** * 数据项被拖拽进来, 重载基类方法 */ function ondrop(param, status) { if (!self.isDrop || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } var target = param.target; // 拖拽安放目标 var dragged = param.dragged; // 当前被拖拽的图形对象 var seriesIndex = ecData.get(target, 'seriesIndex'); var dataIndex = ecData.get(target, 'dataIndex'); var data; var legend = component.legend; if (dataIndex == -1) { // 落到pieCase上,数据被拖拽进某个饼图,增加数据 data = { value : ecData.get(dragged, 'value'), name : ecData.get(dragged, 'name') }; // 修饼图数值不为负值 if (data.value < 0) { data.value = 0; } series[seriesIndex].data.push(data); legend && legend.add( data.name, dragged.style.color || dragged.style.strokeColor ); } else { // 落到sector上,数据被拖拽到某个数据项上,数据修改 var accMath = require('../util/accMath'); data = series[seriesIndex].data[dataIndex]; legend && legend.del(data.name); data.name += option.nameConnector + ecData.get(dragged, 'name'); data.value = accMath.accAdd( data.value, ecData.get(dragged, 'value') ); legend && legend.add( data.name, dragged.style.color || dragged.style.strokeColor ); } // 别status = {}赋值啊!! status.dragIn = status.dragIn || true; // 处理完拖拽事件后复位 self.isDrop = false; return; } /** * 数据项被拖拽出去,重载基类方法 */ function ondragend(param, status) { if (!self.isDragend || !param.target) { // 没有在当前实例上发生拖拽行为则直接返回 return; } var target = param.target; // 被拖拽图形元素 var seriesIndex = ecData.get(target, 'seriesIndex'); var dataIndex = ecData.get(target, 'dataIndex'); // 被拖拽的图形是饼图sector,删除被拖拽走的数据 component.legend && component.legend.del( series[seriesIndex].data[dataIndex].name ); series[seriesIndex].data.splice(dataIndex, 1); // 别status = {}赋值啊!! status.dragOut = true; status.needRefresh = true; // 处理完拖拽事件后复位 self.isDragend = false; return; } /** * 输出动态视觉引导线 */ self.shapeHandler.onmouseover = function(param) { var shape = param.target; var seriesIndex = ecData.get(shape, 'seriesIndex'); var dataIndex = ecData.get(shape, 'dataIndex'); var percent = ecData.get(shape, 'special'); var lastAddRadius = shape._lastAddRadius; var startAngle = shape.style.startAngle; var endAngle = shape.style.endAngle; var defaultColor = shape.highlightStyle.color; // 文本标签,需要显示则会有返回 var label = _getLabel( seriesIndex, dataIndex, percent, lastAddRadius, startAngle, endAngle, defaultColor, true ); if (label) { zr.addHoverShape(label); } // 文本标签视觉引导线,需要显示则会有返回 var labelLine = _getLabelLine( seriesIndex, dataIndex, lastAddRadius, shape.style.r0, shape.style.r, startAngle, endAngle, defaultColor, true ); if (labelLine) { zr.addHoverShape(labelLine); } }; self.reformOption = reformOption; // 重载基类方法 self.animation = animation; // 接口方法 self.init = init; self.refresh = refresh; self.addDataAnimation = addDataAnimation; self.onclick = onclick; self.ondrop = ondrop; self.ondragend = ondragend; init(option, component); } // 图表注册 require('../chart').define('pie', Pie); return Pie; }); define('_chart',['require','echarts/chart/scatter','echarts/chart/k','echarts/chart/radar','echarts/chart/chord','echarts/chart/force','echarts/chart/map','echarts/util/mapData/geoJson/an_hui_geo','echarts/util/mapData/geoJson/ao_men_geo','echarts/util/mapData/geoJson/bei_jing_geo','echarts/util/mapData/geoJson/china_geo','echarts/util/mapData/geoJson/chong_qing_geo','echarts/util/mapData/geoJson/fu_jian_geo','echarts/util/mapData/geoJson/gan_su_geo','echarts/util/mapData/geoJson/guang_dong_geo','echarts/util/mapData/geoJson/guang_xi_geo','echarts/util/mapData/geoJson/gui_zhou_geo','echarts/util/mapData/geoJson/hai_nan_geo','echarts/util/mapData/geoJson/hei_long_jiang_geo','echarts/util/mapData/geoJson/he_bei_geo','echarts/util/mapData/geoJson/he_nan_geo','echarts/util/mapData/geoJson/hu_bei_geo','echarts/util/mapData/geoJson/hu_nan_geo','echarts/util/mapData/geoJson/jiang_su_geo','echarts/util/mapData/geoJson/jiang_xi_geo','echarts/util/mapData/geoJson/ji_lin_geo','echarts/util/mapData/geoJson/liao_ning_geo','echarts/util/mapData/geoJson/nei_meng_gu_geo','echarts/util/mapData/geoJson/ning_xia_geo','echarts/util/mapData/geoJson/qing_hai_geo','echarts/util/mapData/geoJson/shang_hai_geo','echarts/util/mapData/geoJson/shan_dong_geo','echarts/util/mapData/geoJson/shan_xi_1_geo','echarts/util/mapData/geoJson/shan_xi_2_geo','echarts/util/mapData/geoJson/si_chuan_geo','echarts/util/mapData/geoJson/tai_wan_geo','echarts/util/mapData/geoJson/tian_jin_geo','echarts/util/mapData/geoJson/world_geo','echarts/util/mapData/geoJson/xiang_gang_geo','echarts/util/mapData/geoJson/xin_jiang_geo','echarts/util/mapData/geoJson/xi_zang_geo','echarts/util/mapData/geoJson/yun_nan_geo','echarts/util/mapData/geoJson/zhe_jiang_geo','echarts/chart/line','echarts/chart/bar','echarts/chart/pie'],function(require) { require("echarts/chart/scatter"); require("echarts/chart/k"); require("echarts/chart/radar"); require("echarts/chart/chord"); require("echarts/chart/force"); require("echarts/chart/map"); require("echarts/util/mapData/geoJson/an_hui_geo"); require("echarts/util/mapData/geoJson/ao_men_geo"); require("echarts/util/mapData/geoJson/bei_jing_geo"); require("echarts/util/mapData/geoJson/china_geo"); require("echarts/util/mapData/geoJson/chong_qing_geo"); require("echarts/util/mapData/geoJson/fu_jian_geo"); require("echarts/util/mapData/geoJson/gan_su_geo"); require("echarts/util/mapData/geoJson/guang_dong_geo"); require("echarts/util/mapData/geoJson/guang_xi_geo"); require("echarts/util/mapData/geoJson/gui_zhou_geo"); require("echarts/util/mapData/geoJson/hai_nan_geo"); require("echarts/util/mapData/geoJson/hei_long_jiang_geo"); require("echarts/util/mapData/geoJson/he_bei_geo"); require("echarts/util/mapData/geoJson/he_nan_geo"); require("echarts/util/mapData/geoJson/hu_bei_geo"); require("echarts/util/mapData/geoJson/hu_nan_geo"); require("echarts/util/mapData/geoJson/jiang_su_geo"); require("echarts/util/mapData/geoJson/jiang_xi_geo"); require("echarts/util/mapData/geoJson/ji_lin_geo"); require("echarts/util/mapData/geoJson/liao_ning_geo"); require("echarts/util/mapData/geoJson/nei_meng_gu_geo"); require("echarts/util/mapData/geoJson/ning_xia_geo"); require("echarts/util/mapData/geoJson/qing_hai_geo"); require("echarts/util/mapData/geoJson/shang_hai_geo"); require("echarts/util/mapData/geoJson/shan_dong_geo"); require("echarts/util/mapData/geoJson/shan_xi_1_geo"); require("echarts/util/mapData/geoJson/shan_xi_2_geo"); require("echarts/util/mapData/geoJson/si_chuan_geo"); require("echarts/util/mapData/geoJson/tai_wan_geo"); require("echarts/util/mapData/geoJson/tian_jin_geo"); require("echarts/util/mapData/geoJson/world_geo"); require("echarts/util/mapData/geoJson/xiang_gang_geo"); require("echarts/util/mapData/geoJson/xin_jiang_geo"); require("echarts/util/mapData/geoJson/xi_zang_geo"); require("echarts/util/mapData/geoJson/yun_nan_geo"); require("echarts/util/mapData/geoJson/zhe_jiang_geo"); require("echarts/chart/line"); require("echarts/chart/bar"); require("echarts/chart/pie"); });