| |
| /**
|
| * 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} <br/>{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 <canvas> 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(' <g_vml_:group',
|
| ' coordsize="', Z * W, ',', Z * H, '"',
|
| ' coordorigin="0,0"' ,
|
| ' style="width:', W, 'px;height:', H, 'px;position:absolute;');
|
|
|
| // If filters are necessary (rotation exists), create them
|
| // filters are bog-slow, so only create them if abbsolutely necessary
|
| // The following check doesn't account for skews (which don't exist
|
| // in the canvas spec (yet) anyway.
|
|
|
| if (this.m_[0][0] != 1 || this.m_[0][1] ||
|
| this.m_[1][1] != 1 || this.m_[1][0]) {
|
| var filter = [];
|
|
|
| scaleX = Math.sqrt(this.m_[0][0] * this.m_[0][0] + this.m_[0][1] * this.m_[0][1]);
|
| scaleY = Math.sqrt(this.m_[1][0] * this.m_[1][0] + this.m_[1][1] * this.m_[1][1]);
|
|
|
| // Note the 12/21 reversal
|
| filter.push('M11=', this.m_[0][0] / scaleX, ',',
|
| 'M12=', this.m_[1][0] / scaleY, ',',
|
| 'M21=', this.m_[0][1] / scaleX, ',',
|
| 'M22=', this.m_[1][1] / scaleY, ',',
|
| 'Dx=', mr(d.x / Z), ',',
|
| 'Dy=', mr(d.y / Z), '');
|
|
|
| // Bounding box calculation (need to minimize displayed area so that
|
| // filters don't waste time on unused pixels.
|
| var max = d;
|
| var c2 = getCoords(this, dx + dw, dy);
|
| var c3 = getCoords(this, dx, dy + dh);
|
| var c4 = getCoords(this, dx + dw, dy + dh);
|
|
|
| max.x = m.max(max.x, c2.x, c3.x, c4.x);
|
| max.y = m.max(max.y, c2.y, c3.y, c4.y);
|
|
|
| vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
|
| 'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
|
| filter.join(''), ", sizingmethod='clip');");
|
|
|
| } else {
|
| vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
|
| }
|
|
|
| vmlStr.push(' ">');
|
|
|
| // Draw a special cropping div if needed
|
| if (sx || sy) {
|
| // Apply scales to width and height
|
| vmlStr.push('<div style="overflow: hidden; width:', Math.ceil((dw + sx * dw / sw) * scaleX), 'px;',
|
| ' height:', Math.ceil((dh + sy * dh / sh) * scaleY), 'px;',
|
| ' filter:progid:DxImageTransform.Microsoft.Matrix(Dx=',
|
| -sx * dw / sw * scaleX, ',Dy=', -sy * dh / sh * scaleY, ');">');
|
| }
|
|
|
|
|
| // Apply scales to width and height
|
| vmlStr.push('<div style="width:', Math.round(scaleX * w * dw / sw), 'px;',
|
| ' height:', Math.round(scaleY * h * dh / sh), 'px;',
|
| ' filter:');
|
|
|
| // If there is a globalAlpha, apply it to image
|
| if(this.globalAlpha < 1) {
|
| vmlStr.push(' progid:DXImageTransform.Microsoft.Alpha(opacity=' + (this.globalAlpha * 100) + ')');
|
| }
|
|
|
| vmlStr.push(' progid:DXImageTransform.Microsoft.AlphaImageLoader(src=', image.src, ',sizingMethod=scale)">');
|
|
|
| // Close the crop div if necessary
|
| if (sx || sy) vmlStr.push('</div>');
|
|
|
| vmlStr.push('</div></div>');
|
|
|
| this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));
|
| };
|
|
|
| contextPrototype.stroke = function(aFill) {
|
| var lineStr = [];
|
| var lineOpen = false;
|
|
|
| var W = 10;
|
| var H = 10;
|
|
|
| lineStr.push('<g_vml_:shape',
|
| ' filled="', !!aFill, '"',
|
| ' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
|
| ' coordorigin="0,0"',
|
| ' coordsize="', Z * W, ',', Z * H, '"',
|
| ' stroked="', !aFill, '"',
|
| ' path="');
|
|
|
| var newSeq = false;
|
| var min = {x: null, y: null};
|
| var max = {x: null, y: null};
|
|
|
| for (var i = 0; i < this.currentPath_.length; i++) {
|
| var p = this.currentPath_[i];
|
| var c;
|
|
|
| switch (p.type) {
|
| case 'moveTo':
|
| c = p;
|
| lineStr.push(' m ', mr(p.x), ',', mr(p.y));
|
| break;
|
| case 'lineTo':
|
| lineStr.push(' l ', mr(p.x), ',', mr(p.y));
|
| break;
|
| case 'close':
|
| lineStr.push(' x ');
|
| p = null;
|
| break;
|
| case 'bezierCurveTo':
|
| lineStr.push(' c ',
|
| mr(p.cp1x), ',', mr(p.cp1y), ',',
|
| mr(p.cp2x), ',', mr(p.cp2y), ',',
|
| mr(p.x), ',', mr(p.y));
|
| break;
|
| case 'at':
|
| case 'wa':
|
| lineStr.push(' ', p.type, ' ',
|
| mr(p.x - this.arcScaleX_ * p.radius), ',',
|
| mr(p.y - this.arcScaleY_ * p.radius), ' ',
|
| mr(p.x + this.arcScaleX_ * p.radius), ',',
|
| mr(p.y + this.arcScaleY_ * p.radius), ' ',
|
| mr(p.xStart), ',', mr(p.yStart), ' ',
|
| mr(p.xEnd), ',', mr(p.yEnd));
|
| break;
|
| }
|
|
|
|
|
| // TODO: Following is broken for curves due to
|
| // move to proper paths.
|
|
|
| // Figure out dimensions so we can do gradient fills
|
| // properly
|
| if (p) {
|
| if (min.x == null || p.x < min.x) {
|
| min.x = p.x;
|
| }
|
| if (max.x == null || p.x > max.x) {
|
| max.x = p.x;
|
| }
|
| if (min.y == null || p.y < min.y) {
|
| min.y = p.y;
|
| }
|
| if (max.y == null || p.y > max.y) {
|
| max.y = p.y;
|
| }
|
| }
|
| }
|
| lineStr.push(' ">');
|
|
|
| if (!aFill) {
|
| appendStroke(this, lineStr);
|
| } else {
|
| appendFill(this, lineStr, min, max);
|
| }
|
|
|
| lineStr.push('</g_vml_:shape>');
|
|
|
| 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(
|
| '<g_vml_:stroke',
|
| ' opacity="', opacity, '"',
|
| ' joinstyle="', ctx.lineJoin, '"',
|
| ' miterlimit="', ctx.miterLimit, '"',
|
| ' endcap="', processLineCap(ctx.lineCap), '"',
|
| ' weight="', lineWidth, 'px"',
|
| ' color="', color, '" />'
|
| );
|
| }
|
|
|
| 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('<g_vml_:fill type="', fillStyle.type_, '"',
|
| ' method="none" focus="100%"',
|
| ' color="', color1, '"',
|
| ' color2="', color2, '"',
|
| ' colors="', colors.join(','), '"',
|
| ' opacity="', opacity2, '"',
|
| ' g_o_:opacity2="', opacity1, '"',
|
| ' angle="', angle, '"',
|
| ' focusposition="', focus.x, ',', focus.y, '" />');
|
| } else if (fillStyle instanceof CanvasPattern_) {
|
| if (width && height) {
|
| var deltaLeft = -min.x;
|
| var deltaTop = -min.y;
|
| lineStr.push('<g_vml_:fill',
|
| ' position="',
|
| deltaLeft / width * arcScaleX * arcScaleX, ',',
|
| deltaTop / height * arcScaleY * arcScaleY, '"',
|
| ' type="tile"',
|
| // TODO: Figure out the correct size to fit the scale.
|
| //' size="', w, 'px ', h, 'px"',
|
| ' src="', fillStyle.src_, '" />');
|
| }
|
| } else {
|
| var a = processStyle(ctx.fillStyle);
|
| var color = a.color;
|
| var opacity = a.alpha * ctx.globalAlpha;
|
| lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
|
| '" />');
|
| }
|
| }
|
|
|
| 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('<g_vml_:line from="', -left ,' 0" to="', right ,' 0.05" ',
|
| ' coordsize="100 100" coordorigin="0 0"',
|
| ' filled="', !stroke, '" stroked="', !!stroke,
|
| '" style="position:absolute;width:1px;height:1px;">');
|
|
|
| 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('<g_vml_:skew on="t" matrix="', skewM ,'" ',
|
| ' offset="', skewOffset, '" origin="', left ,' 0" />',
|
| '<g_vml_:path textpathok="true" />',
|
| '<g_vml_:textpath on="true" string="',
|
| encodeHtmlAttribute(text),
|
| '" style="v-text-align:', textAlign,
|
| ';font:', encodeHtmlAttribute(fontStyleString),
|
| '" /></g_vml_:line>');
|
|
|
| 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 = '<span style="position:absolute;' +
|
| 'top:-20000px;left:0;padding:0;margin:0;border:none;' +
|
| 'white-space:pre;"></span>';
|
| 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<len; i++) {
|
| if (array[i] === value) {
|
| return i;
|
| }
|
| }
|
| return -1;
|
| }
|
|
|
| /**
|
| * 计算包围盒
|
| */
|
| function computeBoundingBox(points, min, max) {
|
| if (points.length === 0) {
|
| return;
|
| }
|
| var left = points[0][0];
|
| var right = points[0][0];
|
| var top = points[0][1];
|
| var bottom = points[0][1];
|
|
|
| for (var i = 1; i < points.length; i++) {
|
| var p = points[i];
|
| if (p[0] < left) {
|
| left = p[0];
|
| }
|
| if (p[0] > 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;
|
| }
|
|
|
| /**
|
| * 颜色值数组转为指定格式颜色,例如:<br/>
|
| * 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) + ')'
|
| );
|
| }
|
|
|
| /**
|
| * 获取颜色值数组,返回值范围: <br/>
|
| * RGB 范围[0-255] <br/>
|
| * HSL/HSV/HSB 范围[0-1]<br/>
|
| * 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.2';
|
|
|
| /**
|
| * 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)
|
| + '<br/>'
|
| + 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 || parseInt(stl.width, 10))
|
| - parseInt(stl.paddingLeft, 10) // 请原谅我这比较粗暴
|
| - parseInt(stl.paddingRight, 10)).toFixed(0) - 0;
|
| }
|
|
|
| function _getHeight(){
|
| var stl = root.currentStyle
|
| || document.defaultView.getComputedStyle(root);
|
|
|
| return ((root.clientHeight || parseInt(stl.height, 10))
|
| - parseInt(stl.paddingTop, 10) // 请原谅我这比较粗暴
|
| - parseInt(stl.paddingBottom, 10)).toFixed(0) - 0;
|
| }
|
|
|
| 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 <l; i++) {
|
| ctx.lineTo(point[i][0], point[i][1]);
|
| }
|
| ctx.lineTo(x, y);
|
| },
|
|
|
| getPointList : function(style) {
|
| var pointList = [
|
| [style.xStart, style.yStart],
|
| [style.xEnd, style.yEnd]
|
| ];
|
| if (style.smooth === 'spline') {
|
| var lastPointX = pointList[1][0];
|
| var lastPointY = pointList[1][1];
|
| pointList[3] = [lastPointX, lastPointY];
|
| pointList[1] = this.getOffetPoint(pointList[0], pointList[3]);
|
| pointList[2] = this.getOffetPoint(pointList[3], pointList[0]);
|
| pointList = this.smoothSpline(pointList, false);
|
| // 修正最后一点在插值产生的偏移
|
| pointList[pointList.length - 1] = [lastPointX, lastPointY];
|
| }
|
| return pointList;
|
| },
|
|
|
| /**
|
| * {Array} start point
|
| * {Array} end point
|
| */
|
| getOffetPoint : function(sp, ep) {
|
| var distance = Math.sqrt(Math.round(
|
| (sp[0] - ep[0]) * (sp[0] - ep[0]) + (sp[1] - ep[1]) * (sp[1] - ep[1])
|
| )) / 3;
|
| //console.log(delta);
|
| var mp = [sp[0], sp[1]];
|
| var angle;
|
| var deltaAngle = 0.2; // 偏移0.2弧度
|
| if (sp[0] != ep[0] && sp[1] != ep[1]) {
|
| // 斜率存在
|
| var k = (ep[1] - sp[1]) / (ep[0] - sp[0]);
|
| angle = Math.atan(k);
|
| }
|
| else if (sp[0] == ep[0]){
|
| // 垂直线
|
| angle = (sp[1] <= ep[1] ? 1 : -1) * Math.PI / 2;
|
| }
|
| else {
|
| // 水平线
|
| angle = 0;
|
| }
|
| var dX;
|
| var dY;
|
| if (sp[0] <= ep[0]) {
|
| angle -= deltaAngle;
|
| dX = Math.round(Math.cos(angle) * distance);
|
| dY = Math.round(Math.sin(angle) * distance);
|
| mp[0] += dX;
|
| mp[1] += dY;
|
| }
|
| else {
|
| angle += deltaAngle;
|
| dX = Math.round(Math.cos(angle) * distance);
|
| dY = Math.round(Math.sin(angle) * distance);
|
| mp[0] -= dX;
|
| mp[1] -= dY;
|
| }
|
| return mp;
|
| },
|
|
|
| /**
|
| * 返回矩形区域,用于局部刷新和文字定位
|
| * @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
|
| };
|
| },
|
|
|
| isCover : function(e, x, y) {
|
| return require('zrender/shape').get(
|
| e.style.smooth !== 'spline' ? 'line' : 'brokenLine'
|
| ).isCover(e,x,y);
|
| }
|
| };
|
|
|
| require('zrender/shape/base').derive(MarkLine);
|
| require('zrender/shape').define('markLine', new MarkLine());
|
|
|
| return MarkLine;
|
| }
|
| ); |
| /**
|
| * echart图表库
|
| *
|
| * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
|
| * @author Kener (@Kener-林峰, linzhifeng@baidu.com)
|
| */
|
| define('echarts/chart',[],function(/*require*/) { //chart
|
| var self = {};
|
|
|
| var _chartLibrary = {}; //echart图表库
|
|
|
| /**
|
| * 定义图形实现
|
| * @param {Object} name
|
| * @param {Object} clazz 图形实现
|
| */
|
| self.define = function(name, clazz) {
|
| _chartLibrary[name] = clazz;
|
| return self;
|
| };
|
|
|
| /**
|
| * 获取图形实现
|
| * @param {Object} name
|
| */
|
| self.get = function(name) {
|
| return _chartLibrary[name];
|
| };
|
|
|
| return self;
|
| }); |
| /**
|
| * echarts通用私有数据服务
|
| *
|
| * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
|
| * @author Kener (@Kener-林峰, linzhifeng@baidu.com)
|
| *
|
| */
|
| define('echarts/util/ecData',[],function() {
|
| /**
|
| * 打包私有数据
|
| *
|
| * @param {shape} shape 修改目标
|
| * @param {Object} series
|
| * @param {number} seriesIndex
|
| * @param {number | Object} data
|
| * @param {number} dataIndex
|
| * @param {*=} special
|
| * @param {*=} special2
|
| */
|
| function pack(
|
| shape, series, seriesIndex, data, dataIndex, name, special, special2
|
| ) {
|
| var value;
|
| if (typeof data != 'undefined') {
|
| if (typeof data.value != 'undefined') {
|
| value = data.value;
|
| }
|
| else {
|
| value = data;
|
| }
|
| }
|
|
|
| shape._echartsData = {
|
| '_series' : series,
|
| '_seriesIndex' : seriesIndex,
|
| '_data' : data,
|
| '_dataIndex' : dataIndex,
|
| '_name' : name,
|
| '_value' : value,
|
| '_special' : special,
|
| '_special2' : special2
|
| };
|
| return shape._echartsData;
|
| }
|
|
|
| /**
|
| * 从私有数据中获取特定项
|
| * @param {shape} shape
|
| * @param {string} key
|
| */
|
| function get(shape, key) {
|
| var data = shape._echartsData;
|
| if (!key) {
|
| return data;
|
| }
|
|
|
| switch (key) {
|
| case 'series' :
|
| return data && data._series;
|
| case 'seriesIndex' :
|
| return data && data._seriesIndex;
|
| case 'data' :
|
| return data && data._data;
|
| case 'dataIndex' :
|
| return data && data._dataIndex;
|
| case 'name' :
|
| return data && data._name;
|
| case 'value' :
|
| return data && data._value;
|
| case 'special' :
|
| return data && data._special;
|
| case 'special2' :
|
| return data && data._special2;
|
| }
|
|
|
| return null;
|
| }
|
|
|
| /**
|
| * 修改私有数据中获取特定项
|
| * @param {shape} shape
|
| * @param {string} key
|
| * @param {*} value
|
| */
|
| function set(shape, key, value) {
|
| shape._echartsData = shape._echartsData || {};
|
| switch (key) {
|
| case 'series' : // 当前系列值
|
| shape._echartsData._series = value;
|
| break;
|
| case 'seriesIndex' : // 系列数组位置索引
|
| shape._echartsData._seriesIndex = value;
|
| break;
|
| case 'data' : // 当前数据值
|
| shape._echartsData._data = value;
|
| break;
|
| case 'dataIndex' : // 数据数组位置索引
|
| shape._echartsData._dataIndex = value;
|
| break;
|
| case 'name' :
|
| shape._echartsData._name = value;
|
| break;
|
| case 'value' :
|
| shape._echartsData._value = value;
|
| break;
|
| case 'special' :
|
| shape._echartsData._special = value;
|
| break;
|
| case 'special2' :
|
| shape._echartsData._special2 = value;
|
| break;
|
| }
|
| }
|
|
|
| return {
|
| pack : pack,
|
| set : set,
|
| get : get
|
| };
|
| }); |
| /**
|
| * echarts层级查找方法
|
| *
|
| * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
|
| * @author Kener (@Kener-林峰, linzhifeng@baidu.com)
|
| *
|
| */
|
| define('echarts/util/ecQuery',['zrender/tool/util'],function() {
|
| var zrUtil = require('zrender/tool/util');
|
|
|
| /**
|
| * 获取嵌套选项的基础方法
|
| * 返回optionTarget中位于optionLocation上的值,如果没有定义,则返回undefined
|
| */
|
| function query(optionTarget, optionLocation) {
|
| if (typeof optionTarget == 'undefined') {
|
| return undefined;
|
| }
|
| if (!optionLocation) {
|
| return optionTarget;
|
| }
|
| optionLocation = optionLocation.split('.');
|
|
|
| var length = optionLocation.length;
|
| var curIdx = 0;
|
| while (curIdx < length) {
|
| optionTarget = optionTarget[optionLocation[curIdx]];
|
| if (typeof optionTarget == 'undefined') {
|
| return undefined;
|
| }
|
| curIdx++;
|
| }
|
| return optionTarget;
|
| }
|
|
|
| /**
|
| * 获取多级控制嵌套属性的基础方法
|
| * 返回ctrList中优先级最高(最靠前)的非undefined属性,ctrList中均无定义则返回undefined
|
| */
|
| function deepQuery(ctrList, optionLocation) {
|
| var finalOption;
|
| for (var i = 0, l = ctrList.length; i < l; i++) {
|
| finalOption = query(ctrList[i], optionLocation);
|
| if (typeof finalOption != 'undefined') {
|
| return finalOption;
|
| }
|
| }
|
| return undefined;
|
| }
|
|
|
| /**
|
| * 获取多级控制嵌套属性的基础方法
|
| * 根据ctrList中优先级合并产出目标属性
|
| */
|
| function deepMerge (ctrList, optionLocation) {
|
| var finalOption;
|
| var tempOption;
|
| var len = ctrList.length;
|
| while (len--) {
|
| tempOption = query(ctrList[len], optionLocation);
|
| if (typeof tempOption != 'undefined') {
|
| if (typeof finalOption == 'undefined') {
|
| finalOption = zrUtil.clone(tempOption);
|
| }
|
| else {
|
| zrUtil.merge(
|
| finalOption, tempOption,
|
| { 'overwrite': true, 'recursive': true }
|
| );
|
| }
|
| }
|
| }
|
| return finalOption;
|
| }
|
|
|
| return {
|
| query : query,
|
| deepQuery : deepQuery,
|
| deepMerge : deepMerge
|
| };
|
| }); |
| /**
|
| * echarts数字运算相关
|
| *
|
| * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
|
| * @author Kener (@Kener-林峰, linzhifeng@baidu.com)
|
| *
|
| */
|
| define('echarts/util/number',[],function() {
|
| function _trim(str) {
|
| return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
|
| }
|
|
|
| /**
|
| * 百分比计算
|
| */
|
| function parsePercent(value, maxValue) {
|
| if (typeof(value) === 'string') {
|
| if (_trim(value).match(/%$/)) {
|
| return parseFloat(value) / 100 * maxValue;
|
| } else {
|
| return parseFloat(value);
|
| }
|
| } else {
|
| return value;
|
| }
|
| }
|
|
|
| /**
|
| * 获取中心坐标
|
| */
|
| function parseCenter(zr, center) {
|
| return [
|
| parsePercent(center[0], zr.getWidth()),
|
| parsePercent(center[1], zr.getHeight()),
|
| ];
|
| }
|
|
|
| /**
|
| * 获取自适应半径
|
| */
|
| function parseRadius(zr, radius) {
|
| // 传数组实现环形图,[内半径,外半径],传单个则默认为外半径为
|
| if (!(radius instanceof Array)) {
|
| radius = [0, radius];
|
| }
|
| var zrSize = Math.min(zr.getWidth(), zr.getHeight()) / 2;
|
| return [
|
| parsePercent(radius[0], zrSize),
|
| parsePercent(radius[1], zrSize),
|
| ];
|
| }
|
|
|
| // 每三位默认加,格式化
|
| function addCommas(x){
|
| if (isNaN(x)) {
|
| return '-';
|
| }
|
| x = (x + '').split('.');
|
| return x[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,'$1,')
|
| + (x.length > 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 = 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 - (maxLength > 1 ? 1 : 0));
|
| var y = _location.height / (maxLength - (maxLength > 1 ? 1 : 0));
|
| 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 += '<br/>'
|
| + _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]) + '<br/>'
|
| + _encodeHTML(params[0][3]) + ' : '
|
| + self.numAddCommas(params[0][2]);
|
| for (var i = 1, l = params.length; i < l; i++) {
|
| formatter += '<br/>' + _encodeHTML(params[i][1])
|
| + '<br/>';
|
| 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) + '<br/>')
|
| : ''
|
| )
|
| + (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 === '' ? '' : '<br />';
|
| for (var i = 0 ; i < indicator.length; i ++) {
|
| html += _encodeHTML(indicator[i].text) + ' : '
|
| + self.numAddCommas(value[i]) + '<br />';
|
| }
|
| _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) + '<br/>')
|
| : '')
|
| + name1 + ' -> ' + name2
|
| + ' (' + self.numAddCommas(value) + ')'
|
| + '<br />'
|
| + name2 + ' -> ' + name1
|
| + ' (' + self.numAddCommas(special2) + ')';
|
| }
|
| }
|
| else {
|
| _tDom.innerHTML = (typeof serie.name != 'undefined'
|
| ? (_encodeHTML(serie.name) + '<br/>')
|
| : '')
|
| + _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, '"')
|
| .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]]
|
| : undefined,
|
| 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 = '<img style="vertical-align:middle" src="' + image
|
| + '" title="'
|
| + (!!(window.attachEvent
|
| && navigator.userAgent.indexOf('Opera') === -1)
|
| ? '右键->图片另存为'
|
| : (saveOption.lang ? saveOption.lang[0] : '点击保存'))
|
| + '"/>';
|
|
|
| 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 = '<p style="padding:8px 0;margin:0 0 10px 0;'
|
| + 'border-bottom:1px solid #eee">'
|
| + (lang[0] || _lang[0])
|
| + '</p>';
|
|
|
| _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.<number>} 直角坐标[x,y]
|
| */
|
| function polar2cartesian(r, theta) {
|
| return [r * zrMath.sin(theta), r*zrMath.cos(theta)];
|
| }
|
|
|
| /**
|
| * 直角坐标转极坐标
|
| *
|
| * @param {number} 横坐标
|
| * @param {number} 纵坐标
|
| *
|
| * @return {Array.<number>} 极坐标[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<Object>} 指标数组
|
| * @param {number} 分割线数量
|
| * @param {Array<number>} 中点坐标
|
| * @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<number>} 中点坐标
|
| *
|
| * @return {Array<Array<number>>} 返回绘制的点集
|
| */
|
| 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<Array<number>>} 绘制的点集
|
| * @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<number>} 原始坐标
|
| * @param {Array<number>} 中点坐标
|
| * @param {number} 缩小的倍数
|
| *
|
| * @return {Array<number>} 转换后的坐标
|
| */
|
| 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<Object>} 指标对象
|
| * @param {Array<number>} 中点坐标
|
| * @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<Object>} 需要处理的数据
|
| */
|
| 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<number>} 对应坐标
|
| */
|
| 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<number>} 坐标
|
| * @return {number} 返回polarindex 返回-1表示不在任何polar
|
| */
|
| function isInside(vector) {
|
| var polar = getNearestIndex(vector);
|
|
|
| if (polar) {
|
| return polar.polarIndex;
|
| }
|
| return -1;
|
| }
|
|
|
| /**
|
| * 如果一个点在网内,返回离它最近的数据轴的index
|
| * @param {Array<number>} 坐标
|
| * @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<Object>} 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.1';
|
| self.dependencies = {
|
| zrender : '1.1.2'
|
| };
|
| /**
|
| * 入口方法
|
| */
|
| 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 <ECharts>} 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 <ECharts>} 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<Object>} 处理的数据
|
| * @return {Array<Array<number>>} 点集
|
| */
|
| 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<Array<number>>} 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<Array<number>>} 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]*$)|(<![\\-\\-\\s\\w\\>\\/]*>)', '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 <arr1.length; i++) {
|
| if (arr1[i] !== arr2[i]) {
|
| return false;
|
| }
|
| }
|
| return true;
|
| }
|
|
|
| function broadcastErrorMsg(shape1, shape2) {
|
| return 'Shape ('
|
| + shape1.toString() + ') (' + shape2.toString()
|
| +') could not be broadcast together';
|
| }
|
|
|
| function axisOutofBoundsErrorMsg(axis) {
|
| return 'Axis ' + axis + ' out of bounds';
|
| }
|
|
|
| function indexOutofBoundsErrorMsg(idx) {
|
| return 'Index ' + idx + ' out of bounds';
|
| }
|
|
|
| return NDArray;
|
|
|
| }); |
| /**
|
| * echarts图表类:chord diagram
|
| *
|
| * @author pissang (https://github.com/pissang/)
|
| *
|
| */
|
|
|
| define('echarts/chart/chord',['require','../util/shape/chord','../component/base','./calculableBase','../util/ecData','zrender/tool/util','zrender/tool/vector','../util/ndarray','../chart'],function(require) {
|
|
|
| require('../util/shape/chord');
|
|
|
|
|
|
|
| var _devicePixelRatio = window.devicePixelRatio || 1;
|
|
|
| function Chord(ecConfig, messageCenter, zr, option, component) {
|
| var self = this;
|
|
|
| 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 zrUtil = require('zrender/tool/util');
|
| var vec2 = require('zrender/tool/vector');
|
| var NDArray = require('../util/ndarray');
|
|
|
| var legend;
|
| var getColor;
|
| var isSelected;
|
|
|
| var series;
|
| this.type = ecConfig.CHART_TYPE_CHORD;
|
|
|
| var _zlevelBase = self.getZlevelBase();
|
|
|
| var chordSerieSample;
|
| // Config
|
| var chordSeries = [];
|
| var groups;
|
| var startAngle;
|
| var clockWise;
|
| var innerRadius;
|
| var outerRadius;
|
| var padding;
|
| var sortGroups;
|
| var sortSubGroups;
|
| var center;
|
| var showScale;
|
| var showScaleText;
|
|
|
| var strokeFix = 0;
|
| // Adjacency matrix
|
| var dataMat;
|
|
|
| var sectorShapes = [];
|
| var chordShapes = [];
|
|
|
| var scaleLineLength = 4;
|
| var scaleUnitAngle = 4;
|
|
|
| function _buildShape() {
|
|
|
| self.selectedMap = {};
|
| chordSeries = [];
|
| chordSerieSample = null;
|
| var matrix = [];
|
| var serieNumber = 0;
|
| for (var i = 0, l = series.length; i < l; i++) {
|
| if (series[i].type === self.type) {
|
| // Use the config of first chord serie
|
| if (!chordSerieSample) {
|
| chordSerieSample = series[i];
|
| self.reformOption(chordSerieSample);
|
| }
|
|
|
| var _isSelected = isSelected(series[i].name);
|
| // Filter by selected serie
|
| self.selectedMap[series[i].name] = _isSelected;
|
| if (!_isSelected) {
|
| continue;
|
| }
|
| chordSeries.push(series[i]);
|
| self.buildMark(
|
| series[i],
|
| i,
|
| component
|
| );
|
| matrix.push(series[i].matrix);
|
| serieNumber++;
|
| }
|
| }
|
| if (!chordSerieSample) {
|
| return;
|
| }
|
| if (!chordSeries.length) {
|
| return;
|
| }
|
|
|
| var zrWidth = zr.getWidth();
|
| var zrHeight = zr.getHeight();
|
| var zrSize = Math.min(zrWidth, zrHeight);
|
|
|
| groups = chordSerieSample.data;
|
| startAngle = chordSerieSample.startAngle;
|
| // Constrain to [0, 360]
|
| startAngle = startAngle % 360;
|
| if (startAngle < 0) {
|
| startAngle = startAngle + 360;
|
| }
|
| clockWise = chordSerieSample.clockWise;
|
| innerRadius = self.parsePercent(
|
| chordSerieSample.radius[0],
|
| zrSize / 2
|
| );
|
| outerRadius = self.parsePercent(
|
| chordSerieSample.radius[1],
|
| zrSize / 2
|
| );
|
| padding = chordSerieSample.padding;
|
| sortGroups = chordSerieSample.sort;
|
| sortSubGroups = chordSerieSample.sortSub;
|
| showScale = chordSerieSample.showScale;
|
| showScaleText = chordSerieSample.showScaleText;
|
| center = [
|
| self.parsePercent(chordSerieSample.center[0], zrWidth),
|
| self.parsePercent(chordSerieSample.center[1], zrHeight)
|
| ];
|
| var fixSize =
|
| chordSerieSample.itemStyle.normal.chordStyle.lineStyle.width -
|
| chordSerieSample.itemStyle.normal.lineStyle.width;
|
| strokeFix =
|
| (fixSize / _devicePixelRatio) / innerRadius / Math.PI * 180;
|
|
|
|
|
| dataMat = new NDArray(matrix);
|
| dataMat = dataMat._transposelike([1, 2, 0]);
|
|
|
| // Filter the data by selected legend
|
| var res = _filterData(dataMat, groups);
|
| dataMat = res[0];
|
| groups = res[1];
|
|
|
| // Check if data is valid
|
| var shape = dataMat.shape();
|
| if (shape[0] !== shape[1] || shape[0] !== groups.length) {
|
| throw new Error('Data not valid');
|
| }
|
| if (shape[0] === 0 || shape[2] === 0) {
|
| return;
|
| }
|
|
|
| // Down to 2 dimension
|
| // More convenient for angle calculating and sort
|
| dataMat.reshape(shape[0], shape[1] * shape[2]);
|
|
|
| // Processing data
|
| var sumOut = dataMat.sum(1);
|
| var percents = sumOut.mul(1 / sumOut.sum());
|
|
|
| var groupNumber = shape[0];
|
| var subGroupNumber = shape[1] * shape[2];
|
|
|
| var groupAngles = percents.mul(360 - padding * groupNumber);
|
| var subGroupAngles = dataMat.div(
|
| dataMat.sum(1).reshape(groupNumber, 1)
|
| );
|
| subGroupAngles = subGroupAngles.mul(
|
| groupAngles.sub(strokeFix * 2).reshape(groupNumber, 1)
|
| );
|
|
|
| switch (sortGroups) {
|
| case 'ascending':
|
| case 'descending':
|
| var groupIndices = groupAngles
|
| .argsort(0, sortGroups);
|
| groupAngles['sort'](0, sortGroups);
|
| sumOut['sort'](0, sortGroups);
|
| break;
|
| default:
|
| var groupIndices = NDArray.range(shape[0]);
|
| }
|
|
|
| switch (sortSubGroups) {
|
| case 'ascending':
|
| case 'descending':
|
| var subGroupIndices = subGroupAngles
|
| .argsort(1, sortSubGroups);
|
| subGroupAngles['sort'](1, sortSubGroups);
|
| break;
|
| default:
|
| var subGroupIndices = NDArray
|
| .range(subGroupNumber)
|
| .reshape(1, subGroupNumber)
|
| .repeat(groupNumber, 0);
|
| }
|
|
|
| var groupIndicesArr = groupIndices.toArray();
|
| var groupAnglesArr = groupAngles.toArray();
|
| var subGroupIndicesArr = subGroupIndices.toArray();
|
| var subGroupAnglesArr = subGroupAngles.toArray();
|
| var sumOutArray = sumOut.toArray();
|
|
|
| var sectorAngles = [];
|
| var chordAngles = new NDArray(
|
| groupNumber, subGroupNumber
|
| ).toArray();
|
| var values = [];
|
| var start = 0;
|
| var end = 0;
|
| for (var i = 0; i < groupNumber; i++) {
|
| var sortedIdx = groupIndicesArr[i];
|
| values[sortedIdx] = sumOutArray[i];
|
|
|
| end = start + groupAnglesArr[i];
|
| sectorAngles[sortedIdx] = [start, end];
|
|
|
| // Sub Group
|
| var subStart = start + strokeFix;
|
| var subEnd = subStart;
|
| for (var j = 0; j < subGroupNumber; j++) {
|
| subEnd = subStart + subGroupAnglesArr[sortedIdx][j];
|
| var subSortedIndex = subGroupIndicesArr[sortedIdx][j];
|
| /*jshint maxlen : 200*/
|
| chordAngles[sortedIdx][subSortedIndex]
|
| = [subStart, subEnd];
|
| subStart = subEnd;
|
| }
|
|
|
| start = end + padding;
|
| }
|
|
|
| // reset data
|
| chordShapes = new NDArray(groupNumber, groupNumber, serieNumber)
|
| .toArray();
|
| sectorShapes = [];
|
|
|
| _buildSectors(sectorAngles, values);
|
|
|
| chordAngles = new NDArray(chordAngles).reshape(
|
| groupNumber, groupNumber, serieNumber, 2
|
| ).toArray();
|
| _buildChords(chordAngles, dataMat.reshape(shape).toArray());
|
|
|
| var res = normalizeValue(values);
|
| if (showScale) {
|
| _buildScales(
|
| res[0],
|
| res[1],
|
| sectorAngles,
|
| new NDArray(res[0]).sum() / (360 - padding * groupNumber)
|
| );
|
| }
|
| }
|
|
|
| function _filterData (dataMat, groups) {
|
| var indices = [];
|
| var groupsFilted = [];
|
| // Filter by selected group
|
| for (var i = 0; i < groups.length; i++) {
|
| var name = groups[i].name;
|
| self.selectedMap[name] = isSelected(name);
|
| if (!self.selectedMap[name]) {
|
| indices.push(i);
|
| } else {
|
| groupsFilted.push(groups[i]);
|
| }
|
| }
|
| if (indices.length) {
|
| dataMat = dataMat['delete'](indices, 0);
|
| dataMat = dataMat['delete'](indices, 1);
|
| }
|
| if (!dataMat.size()) {
|
| return [dataMat, groupsFilted];
|
| }
|
| // Empty data also need to be removed
|
| indices = [];
|
| var groupsFilted2 = [];
|
| var shape = dataMat.shape();
|
| dataMat.reshape(shape[0], shape[1] * shape[2]);
|
| var sumOutArray = dataMat.sum(1).toArray();
|
| dataMat.reshape(shape);
|
| for (var i = 0; i < groupsFilted.length; i++) {
|
| if (sumOutArray[i] === 0) {
|
| indices.push(i);
|
| } else {
|
| groupsFilted2.push(groupsFilted[i]);
|
| }
|
| }
|
| if (indices.length) {
|
| dataMat = dataMat['delete'](indices, 0);
|
| dataMat = dataMat['delete'](indices, 1);
|
| }
|
|
|
| return [dataMat, groupsFilted2];
|
| }
|
|
|
| function _buildSectors(angles, data) {
|
| var len = groups.length;
|
| var len2 = chordSeries.length;
|
|
|
| var timeout;
|
|
|
| var showLabel = self.query(
|
| chordSerieSample, 'itemStyle.normal.label.show'
|
| );
|
| var labelColor = self.query(
|
| chordSerieSample, 'itemStyle.normal.label.color'
|
| );
|
|
|
| function createMouseOver(idx) {
|
| return function() {
|
| if (timeout) {
|
| clearTimeout(timeout);
|
| }
|
| timeout = setTimeout(function(){
|
| for (var i = 0; i < len; i++) {
|
| sectorShapes[i].style.opacity
|
| = i === idx ? 1 : 0.1;
|
| zr.modShape(
|
| sectorShapes[i].id,
|
| sectorShapes[i]
|
| );
|
|
|
| for (var j = 0; j < len; j++) {
|
| for (var k = 0; k < len2; k++) {
|
| var chordShape = chordShapes[i][j][k];
|
| if (chordShape) {
|
| chordShape.style.opacity
|
| = (i === idx || j === idx)
|
| ? 0.5 : 0.03;
|
| zr.modShape(chordShape.id, chordShape);
|
| }
|
| }
|
| }
|
| }
|
| zr.refresh();
|
| }, 50);
|
| };
|
| }
|
|
|
| function createMouseOut() {
|
| return function() {
|
| if (timeout) {
|
| clearTimeout(timeout);
|
| }
|
| timeout = setTimeout(function(){
|
| for (var i = 0; i < len; i++) {
|
| sectorShapes[i].style.opacity = 1.0;
|
| zr.modShape(sectorShapes[i].id, sectorShapes[i]);
|
|
|
| for (var j = 0; j < len; j++) {
|
| for (var k = 0; k < len2; k++) {
|
| var chordShape = chordShapes[i][j][k];
|
| if (chordShape) {
|
| chordShape.style.opacity = 0.5;
|
| zr.modShape(chordShape.id, chordShape);
|
| }
|
| }
|
| }
|
| }
|
| zr.refresh();
|
| }, 50);
|
| };
|
| }
|
|
|
| for (var i = 0; i < len; i++) {
|
|
|
| var group = groups[i];
|
| var angle = angles[i];
|
| var _start = (clockWise ? (360 - angle[1]) : angle[0])
|
| + startAngle;
|
| var _end = (clockWise ? (360 - angle[0]) : angle[1])
|
| + startAngle;
|
|
|
| var sector = {
|
| id : zr.newShapeId(self.type),
|
| shape : 'sector',
|
| zlevel : _zlevelBase,
|
| style : {
|
| x : center[0],
|
| y : center[1],
|
| r0 : innerRadius,
|
| r : outerRadius,
|
| startAngle : _start,
|
| endAngle : _end,
|
| brushType : 'fill',
|
| opacity: 1,
|
| color : getColor(group.name)
|
| },
|
| highlightStyle : {
|
| brushType : 'fill'
|
| }
|
| };
|
| sector.style.lineWidth = self.deepQuery(
|
| [group, chordSerieSample],
|
| 'itemStyle.normal.lineStyle.width'
|
| );
|
| sector.highlightStyle.lineWidth = self.deepQuery(
|
| [group, chordSerieSample],
|
| 'itemStyle.emphasis.lineStyle.width'
|
| );
|
| sector.style.strokeColor = self.deepQuery(
|
| [group, chordSerieSample],
|
| 'itemStyle.normal.lineStyle.color'
|
| );
|
| sector.highlightStyle.strokeColor = self.deepQuery(
|
| [group, chordSerieSample],
|
| 'itemStyle.emphasis.lineStyle.color'
|
| );
|
| if (sector.style.lineWidth > 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":["@@nJUXUV°UÑnU@mlLVaVln@@bn@VU@xlb@lLnKlVIJUVxnI@lVL@b°VX@bxnVVUnVVnU@kX@VwV@al¥UUnUWa@@wĸULU¥lKUa@aUI@alLVaU¯anWkUKm@XV@VaXlW@aU_UWVUI¯@ma¯W¯I@UU@WWU@U@@UU@VkV@@WUUm@UaU@lK@IUKL@KWmXUWaXI@@a@a@U@U@KV¥lwk°b²JVIVKlV@UXlaUl`UVLVVVUJU@Lnm@_VK@KUIW@J@Xk@WW@UmmXmWk@kK@aUUVmmkUwUmWL@WmU@UJmUULkKWakLWVkIlwULW@X°lUJ@°ULWVwmJ@bmb¯Vkm@@WkWm¯wL@lkXWmXym¯UImJUbkV@Vn¯@V@lUb@mk@maUxmlUbULWn@JLmKUkWKkwUKbmXWxkVUKmLkVV@JUUWL@xkJUUV@X@VVlUbVX@xk¤x¼xWxnnn@Þ¼JVb°aVn@mlnXUJlbVlkz@lUlXJmxVxXnWxXÈ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°znWXlW@kK°xXnl@Xn@l°Una@anIxXUVK@¯VIkW¯X@VKxklJXUlKXblLVKnVVIV@Xn@XKVnVxlnnUlmV@²óUkVlWbln@VVVIn@lw@WVIXblV@ÈxaUaVIVVnKVLKln@b²K@»U£ÑķġÝÅbKa@Im@Û@kWÓkkmKÅnóJUÅ£W@wĕ@wĉţ¯¯UkK±l¯U¥UÑkÝUķ»Ý¥¯JIUVbUl¯ÈV¼VJU¼Vb@bkLUl@VJ@bUXÇ@lkVmXmKkLVxVL@VkVVVlzWkbmLUUUbVbUVlÒnJlUnLllUL@bUVxlLXVƦÈVU¦WJ"],"encodeOffsets":[[118834,31759]]}},{"type":"Feature","id":"3411","properties":{"name":"滁州市","cp":[118.1909,32.536],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@@`nnl@xK@X°KXVIXVlbXVWnXlL@È»LVan@VJêVVn@X@laÞbVayn@_xnWVXnWl@VnUVkI@lnXKVLVV@V@kW@LlVô@J@bVnnKnkVa@»lç@nwKmaUUUVÑ@nmWXalI@alVn@VwUaVU@nlaôJnUVVXlJaXXVK@UV@VWx@nXVWXVUlLUbVULVVnUVbUbVb@@aKÆnnKVK@U@UU@@a@V°¯ÈJVIlķ@aaUaVKU_@mkxUI@aUlyU@@wkKWmUbUnUVWbkJW_J@bn@Vm@@KULk@V@@bVbÅm@LW@UVVbkK@UkKWL@VULUKWIUJUbkK@_WVXUJka@XVa@ky@aVIUUW@@mUlLKWÑUKVan@UkVmmIXKaVaUwVU@UmykU¯@±UUL@WUIVUU@KkIWaaU@kUUaÇUó»mKk¯@y@kWK@bkI¯`mnl¯XWlkVUzUJlbUbVJl@nnm@VULV`XnWÆbmUUnJmUknJ¯km@yk@kUxL@VUbmnn¤lX@`z@JmaULUVl@Xn@xllkXWaaW@UVmUb@mVXWxXbWbUÒnVVnVVUL"],"encodeOffsets":[[120004,33520]]}},{"type":"Feature","id":"3418","properties":{"name":"宣城市","cp":[118.8062,30.6244],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@Vb@XLJXxlIXxlVlV@I²¤nlUnVU@VULWVUJ@Lnb@lV@UnV@@VVVlLnbnJUVkUUVWn@@anUVnVJVIV@@nUJVbUb@VUbVK@bn@VbnIlxkllXVlXKWUXUlL°¤UVVb@bUlkXWxXz@IlaUlnUlJVInVÆJULVUnVK°@VnlVnxV@XLlK@wVL@KnUlJXUbnKVLXlUw@VWlLXKm@@a@VLnmlIVVnKn@kVaVlwk@@a@k@VIUa@maUa@wna@kmWUUmVUIVÇ@aKmakUJ@InmUUaVaklX@Vk@m@VU@wnK@alKVUkUkKbmUkm@U£WVk@@UÝbbaÇx@b@WVUa¯@wVwUUV@VwnK@KWaÅ@KIUyUI@WmXóUbWaKm@km@IUyIUaWKx@zUKUL@llVUnkLVVkJWX@VUKUVIkVWakb@VWb@n@JkXUlmL@xkL@`VxLUÈUJ@Vm@@bmIUlUL@VUVVbknm@mKUwKVÈ@J@LV±kkJUIl"],"encodeOffsets":[[120803,31247]]}},{"type":"Feature","id":"3412","properties":{"name":"阜阳市","cp":[115.7629,32.9919],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@Vn@ak°a±@¥@UUI@aUmlwUUxb@¥XU@mmI@a@Kn@@_W@@WI@mUVVXUl@XaV@K@I@aLX@aVI°K@KVLUUwyXkK@kKÆbXnlK@k@aJlU@w@U@»@aXKWn_JXkVKn@°LlKXW@¯U@aUK@kmJUwVIUJkmLK@kka@wUVm@@am@UkUbkK@nmVÒ¯VUWVVmIULk@ma@kkK@nUbUamU`UUVUkKVkkW@@bkmnmUXVKXVL@VbUmbVXJ@nmKÅI@KWKUXVJUL@VUKUX@KUKWL@LUJmaXXm@kVVV@L@VUL@VlK@L@V@LUK@VUb@UUU@°@nVxU`Lkn@`@XVJ@XVmk@UKmV¯LVVn±Wm@Ub@JlLUl@VLk@lmVVn@bnV@V°IVaVJXI°K°V@XXVlVVUnKVlUbWXnV@bV`U@@m@@@nxmn@bXVlL@¤nbUl¦VVUnJVUVl@@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@aUIkWVlLXblVIUVV@mn@V_n@VaUK@I@UaanJVU@lVUVnnKVVlaUaI@wnKLnll@nVlk@wVKXkl@@bbUJ@VU@UUUyVk@aVUXwlWXXWU¹@aU@WUI@mlUnJ@Il@aXbV@VKl@XxVL@WIJlb@al@IUUm@@aVK@¥¯@mUķ¯bWk£Vm@akm@VaÅ@UVWa@UJWkJUbWbU@UlXk@amV@K¯nk@lU@Uxmz@bU`ÇbUbÅVm£U@Wwx@akLUK@UlakwUJWVkLmaUal@n_mVUnKVUUmÅXWa@kJmx@XUJ@bVLXxl@VVUVVUbkLWbU@@lUVVVVXK@XkJ@nU@@bV@VxUVlbU@xXLWn@UxVbVĊV@b@XV`mnkJ@kUKmbaU@VbnbÆx@XU@@`k@@bl@@bkL@WakXWaU@Vmkx@XWW@@wUUUbJU¯V@¯ÞU@WxXlL@bkb@lVlnbJW@kkU@mbkaWJIVlmz¯`UnU@mb@@`@bkVlnV@b@V@aVxn@VxKXnl@nbVKbVK@a_V@Vw@WLlwnK@UmIU@VW@UÈ@lKnalw@@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@VUJVnUJVzXJVxkVJlI²lU@K@IUÇLVxnLn@lmUaVU@UVKVknJ@an@@UVIVÇKUw@_lK@wnKVklW@I@mXa@UlaXblUJVUVL@UXWlIUUlKVmkU@kVKVL@ywXLVbJVz@Jln@nLXbVaônW@la@UVWUa@@a@mk@WIk@VwUa¯¥m@UUVK@ImK@aX£kKÅVa_@±akXWWLnU@@a@¯mK@LJUWwUVVmbXX@lWLn`mzUJUbLk@makVWmkXambkKkna@ab@U@Unm@WV@VbUbUJWIk@@lmL@°UVUVmn@@kmWkb@x_m@@aU@b@JlUzlWxXn@b²@l`IVlUlL@VKnVbUl@VlIn@@bbVWUk@@bX@Valb@bnb°Vn@xVKlbVnV@VxL@ln@UXVVL"],"encodeOffsets":[[120747,31095]]}},{"type":"Feature","id":"3414","properties":{"name":"巢湖市","cp":[117.7734,31.4978],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@VV@blL@XlWnnn@VXXl@@WIX@VJ@LxŎxln@bXJVblX@VVbUVn@VbUVlb@LnJVbVLVXLÒVLÒVbVIVylUXk°Wknm°_lJ@aXL@lz°@lnLô¼VÈVUUaVKU@WW@@UUa@knmVLlaV@a@kak±@UmwkKmkljÝUUkL@mlIVmnÝWkkUÝ@KƑĉa@»mma@mX¤¯Uw@@UU@bU±±L@akmLUKmLUUUJVbbÇw@kUWaUJ@Xkxm@UJUUm@kakXUVl±ô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@ankWXK@@V²VVIÈU@al@VaÈamK@wU@klaUV@XVUU»WUUbkmUkVmk@aÈw@mWU@VkIkVWKUÑķXȭºU¯l@kkLWmÅaL@lLWlzVxVUK@L¯LUJ@bWK@b@JLU@Wbk@WVUUV@nJ@XX@@`m@@L@bnJ@nWV@¦awVVkxVn@bVJ@V¦@²¯blb@mUU@¼¦XbUV`@nnxUxWLkUkVWKkV@XV@@VVL@VX@lVV@L@blL@`L@xXKVL@VnU@lwnU@ml@XnV@@UVW°LnalUI@aUK@aa@UkXW@I@mWL@UXK@UVW@U@@kWn@@V@XblaVxL@bVKXbIlJ"],"encodeOffsets":[[119183,34594]]}},{"type":"Feature","id":"3417","properties":{"name":"池州市","cp":[117.3889,30.2014],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@V°°ĊŤ@xĖ@xXƤVôIÆmnLllXÔ@lÜn@@JbLÆaĢÞĸ°VVUUKVanK@UV@VLVVnln@xnklxXamk@WV@Xa@naVkKlk@mkUWwkJWwIWK@UaUwWIUyVIUmVI@UXWmkkWKUUVWm@@kKw@UUUmkaULwm@¯Uma@akaUbW@@a@VlUXa@am@kJ@UVkUamL@UkKVUkJk_±@a@WmXwÇkkaVaUa±wV@VkwnyUaW@UU¯amLk@m@kmmU¯K@L@lUX¯WlkXVbbVUL@J@LVKnlJXnlb@`nXlalV@bnL@Vnb¼@lXbWlkLK@zUJmIUxUVUVmX","@@llUL@VlxL@a@UwXa¯@"],"encodeOffsets":[[119543,30781],[120061,31152]]}},{"type":"Feature","id":"3401","properties":{"name":"合肥市","cp":[117.29,32.0581],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@LxVĊLÞkVlVVXaWaXwWnU@anVVUX@bXblWkk@wWmk@VUVKnb@Iy@_kWm£nmVa@UKwlVl@zn@°lIlmnVIVmnVaXÅWmU_VK@Unmmk@UIVakaaUÑUKÑWKUUKUamI@KkaVUUam@VUUa@UkWUaWI@akmōwwUL@`mn@KVIUVUUUKVk_VkbW@VkUULUJ±I¯alkxU¦@L@V@V@b@b@WJXbWVXn@LKVL@JkLV@Vbn@VV@XU@UlV@@VV@V@XXV@@VJ°°Xnb°@JUVVXV`@bkXWUbU@Wn@VLXlm°bVUbkK@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@bnlUVllnVaXVV¼UVWU@V²wVV@Vl@VnwlI@XbÆWVnUVmLUVnm`k@VbnblKXUVIlxkb@VVLlK@bwXxV@n¤ÆUVaÈaV_@anyVwV@kl@°m@LnUbl@WVkV@XaaVIXlIV@XbVUÆ@XKWwUkmW@_UmnIlJXkWKXmV@w@_XV@Kl@kU@KlX@@UUUUKWLm@klJVUUmk@mXUWmXw`m@zUbÝakbW@m@UUéUIm@UbKǼ@kKWXmWUkaWUJWU¯L@WLwk@mm@_ÅlUVkmWUnV@VWLUbbƑĬ¯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¯IkVUVU@@b@lUXUWmbn@¼bƒĊLÞ@lVXlmÞUnkJ@nlKVVÞXklWVaVI@aUKn»lL@Kn@XXwlm@mn°@V@WywXlWVk@aUaVU¯£kKWVXVWLUkkWlkkwmJUam@@aULVa@UVaUaVI@m@UUJUIUmmV@bm@UXVVUlVmImakKUU@UU@VmU@@kma@KVIXUVK@UVmUkVm±£@JkU@nlkLUlmb@WbU@@XnlWb"],"encodeOffsets":[[120814,31585]]}},{"type":"Feature","id":"3406","properties":{"name":"淮北市","cp":[116.6968,33.6896],"childNum":3},"geometry":{"type":"MultiPolygon","coordinates":[["@@lnnK@¦n@@VV@@VV@nIVV@VW²a@b@bVnUVVV@Vz@l@°UVIVaVV@x@XX@WlwUnV@XblWb@XlK@a@k@al@@_V@@WÅwmaUaV@bnaVL@llInmU_@W@aUUĉUaVwm@XWK@wVkaVUUwU@@aV@@mlI@WLWUUUVU@kV@XalKVaUVUUUk@WwUK@aVI@WUk@@UUU±xkb@lV@xnLÇbUbk@@bÇVUJ±U@U@WLXml@bVVXL@lV@@LmbkLW`kbVxUn@LkxmV@bm@@VkV"],["@@VVVkV@¥@UV@U@VUUJkWakKUlXVJ@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@UUVmnXUlVÆkVKUUUmmUÑkUUÝlĉKUwKbU@UxW@@lmVUUVmUUmwaWkL¯K@mULWlIm`XWL@b@¼@V@xkVI@b@l@lkV°Ȯ¹ĸW"],"encodeOffsets":[[119543,33722]]}},{"type":"Feature","id":"3405","properties":{"name":"马鞍山市","cp":[118.6304,31.5363],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@NJnllLnxV@laXLVKmaaXbVIbVKVVVIVyn@n_W@@UnJlUVVXlLnaUWlV@VVIXW@_W@XK@K@UVUUwVamÑXmmwwKUnUKçU@JU¯@m@nknWxWm@@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@VUUl°JUkVm@U@UkK¯WVkKWkU@Ubakwmlwm@kUmUUKU@@VmLUbVLUV¯U"],["@@LllUL@VlxL@a@UwXamK"]],"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^IHWXITQCIY^AXGfRDXF`DJOLB~G\\DZIHHpErUVMhHb]\\MBVF@FTP`@zTbD\\@~M\\K`H^EVODWICAakAQXoIcCOCIgGYNWFWNGGKKGaJEGMEIKYJUT_J_Go@_SyQaSFMEGTcYOQLIIi@EKAUPCV[EEXQCW|aMUMAaYCYNIDGGACIMGGSKDQGaF_C[GaB@GOIiOKAYLmI@CN]F[SWWAcKKI@HMUimEKbeYQYISNUOcBKPIFBNgvDPGZYFSf]CMSIWGEUFgDIQ[MeDMJS@RR@LphFPCHaBAJKF@J]IBJO@HlO@@RKAMPJHCNDJTHFP@ZGNANBRFH@J_fM^ONJNF\\VTDJHDON@XRND\\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[WMCQ@WPMGCCIUSE[IMPMN]`e@IEGAQBMHM@YEOSGCIDMIGNOLB@QP@GkP@AI^J@ILEBIbADGEOog@KQQWSekWQQUOFKZLF@PUNmIaHIUeBCTSHENcJa@_IWSaGu`GLSBKJQFOXGDXVQVOBIHcDSJWBEFGTMH[^mLaXcHiKElTRKtFXZ`MHMPCNRDxZB\\ICIHK@KHbIVFZ@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@OVISKSJACEQNQbVIXGDIN@dMB[IIBcN]ZHNLP@XOWCFWCNRHTpATD@^NVNLED@Rh@jCEF}E[OOHUEW]W@QGGDIQSH_MmFmCUT_K]i@MHCMWFCFE{BMHMPOHKS]CFNGBELDH_@BcAKOACESAOBELaXAROB@FODMEDWJAG[aE@UM@DImEWJMC@OeCA{aE[@{L@MINUCQXKfUJORCHqJBF@TCXWNQX]M[EAJO@@KMBQJIC]EWMCCUBEBFHKDOTMBGNGF]MWDBRDdMDQVyE@LPVHDCP@JVVMTG~HNSH[CmRUvHPHBbA\\PTNRC\\YNJPRARPJDDR"],"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@UEaJG@LGLDJ[JAwYQCDMNONGY_EWLsSQFkMO[NWAIGaIYL@HMBOKiOQDWEUDMQSF_QIUBWdg@[NaAKQ@M]OQ@WhgLUMMFYQDIRCEUZOOCIOJ[KIUMKL@HIDKVEBM`HJAJSJUdBLGNEdMBMO[BYEWJSNKNaD]PE\\SjOT_RQVEZPpNQXfNA~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@CABAAEEDMGCH]A[M@CJWHJaUMRFRBDTITLUJ@PFJKLOVST@FSLENgKGFSCaCmF_ESQiOSFOT[HYPu@IH_[IoE_[]GUC[USB__CYQI@Gakg@qZeHQNMNV\\FVLPgJAFJPRLCH[XcPELUT[JiV_EELFTADBXRTRLJC@fHXHHbPd`fR@NfT`@TLplHMpCEJHJBVLF@JTVnG^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`RTCNFVXRCjPPLNA@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@IHJFCPEBACBIAAKDOABXARHPNEHGbQAAKQFGIAM[C@WHKaGiCEGOAHUKCIokSCUSOCYN[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@EFEG@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@CHFBHUNAJKADGECBCMAG^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":["@@ZJZRafFLjnVGNJ@LLBdXX\\T^EDMJ@nZKLBjPPJ@HbA\\H`DbERHLCFK^BZaFWXQLAGMHa\\OLO@SBIpBdCLVQfElO@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\\NNBNAkNU|]HMTMN@MZBLFFF@RIRUTBMFIEGaAGGAOIIUGTSFcYKS@MSLYPKRUBU]EWDOI]CKGASgW@MTWKIMCS@uMAKKADMECGAKVUTSDy@IjWLMNBF@hHEF@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"],["@@HUNAJKADGECBCMAG^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":["@@plDJVLGPBFHjDbHGL@X\\DBNHJREBLRBHaFGMGOBQAWPBLCBBAJBDFADOIEJGE@@EP@HCPWP@ZgfBRQJJ\\D@HLHLDVA@IVDFGSI@EGC@EBB@CN@@IZCAGHGaEqGJG@EjwJ]@K@GSA@e_I@NE@CA@Kg@KC@ENCFAKQAW@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@ig@@QFCMKMU@]SCoBGSMQDEXXDWPO@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@@OAEDQEW@BLEMD@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@AC@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@RFFCBFU@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@@bEVD@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@VLnJlxnbUU@IVK@lVIVwnJlU@n@J@L@Jn@l_nWVLVln@@blLmV@@xÔ`nxVÈLlxLVxVVV_U»VWn_m¥XwVmnX°lmUUVwÞaVk@a@mmIUa@mwk@m@@U¯a@UV@@K@ykkmwkV@kU@ÑVkKWLÅamaUm@kyU@WkU@UaIUaVaUUmUUa@aVLXKWa¯UUbmJXnWnX`l@@xkzWÆ@VLU¦x@b@JkIkJ@LmbUamJwm@óxnk@V@xVnUVmVUVUbVlUbkXW"],"encodeOffsets":[[110914,29695]]}},{"type":"Feature","id":"500236","properties":{"name":"奉节县","cp":[109.3909,30.9265],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@WVXbUnK@x@b²kxmKkl¯_VV°VU@bnKVVV@@nk@nbn@°@VLČU@°WV@VnU@InKVl@nUbKnXWlknLlKUwnalLaVlUXmWk@UU@UWWIUyķ¹XaWW@XKUIVmU@W@UVU@KV@n»VkUkÇmUmVIUmULUbm@wUaKkkm¯ÑUL@bWVnx@VmxUI@klmkkK@aK@IlJ@I¯k@mak@mnkJVL@bV@UbW`UUUVI@VU@VVbUJVLUVVbUXVVxk¦VJUnVxnVVUJV@Ubl@@bXV@L"],"encodeOffsets":[[111781,31658]]}},{"type":"Feature","id":"500238","properties":{"name":"巫溪县","cp":[109.3359,31.4813],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@nLWbXVLVUV@KIVl@b@lbUVnU@JÆU@V@n°KĢUl@VbÞKV@_VKXUU@KX@wlkkU@mWKUU@UôJ@XV@aVmÞIVaVL@»km@UkLU@aU@WWLUUUKkbwWa@KU@kaXmWLamVk@UmL@JmVUU@¯X@ċVUK¯@ÅnWKLkKULWK@UXK@wW@LkV@bVLlXn`¯xU°LnlV@n°Lnl"],"encodeOffsets":[[111488,32361]]}},{"type":"Feature","id":"500234","properties":{"name":"开县","cp":[108.4131,31.2561],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@n@naIw@@VVKLVbVxnVÆUnanKWXamKmk¯K@mkUm¯KV°w@Wm@UIUUlKUU@a¯KWanwmUXamKkUWUnU@KkUwWKXaWLUWkImaUUUKka±k@l¯wwmbUkXm@UJkIWXXbmUJXUV@°KllVXV@xmbnV@blV@VU`UL@Va@bULlb°VXbÜ@V@bL@JxnLVb@lVb@V@@zbXWXKVLV@@bUVVL@blVna@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@ÆlLUl`nVKU¼VxkbWnlUxlXX@°°WnnJ@VUn@Jk°L@VlV@nUJx@bVVVz@VnLlaKnalVlIU¼@nV@@anKUwVal@UlJlI@akU@UWXKVI¯Uak@@KmkXWÜkXWykIWwXw@laXamkVUUym_XmlkkmmakwmIUKU@Wak@kaW@kI¯WIk¦VUUmaUV@XkVUV±aUb¯b¯¥m@@ImJ@mmL@kUKUkkJbV¦"],"encodeOffsets":[[110408,29729]]}},{"type":"Feature","id":"500235","properties":{"name":"云阳县","cp":[108.8306,31.0089],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@lbLVVVnblJVXXKWbXLVxl@LmVXVVlnLWbnVmxXb°L@bVVkLVVVJn@@X_WmkUK@alUKX@@xWL@VXLVKlLKXLÆm@ma@ml@mU@UUmL@aVUU¯U°`lknLlw±@a@wmLVWaXU@KWU@ak@VaU@IUVmUUwVmUIl¥UwUVWUaVUUKVIUa@UUUUJUUmknl@@VWV@L¯aUbUlx@@b@VULUx@VUxVVU@bU@mxUU@mUVklkk@WxknlxK@amLKUK"],"encodeOffsets":[[111016,31742]]}},{"type":"Feature","id":"500101","properties":{"name":"万州区","cp":[108.3911,30.6958],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ĸĊVInaWWXlJVIn@lWVnax°xkl@²LVLnK@bLkwlmXw@lllkUnVV@VnwV@@aVUUVw@UVwVK@U@a@kwVVa°b@KXU@U@mkÇÑamlkUVmn@VULUm@kUVkUawUWm@Uw¯mKUUmVUUULUKUW@XbWVkaWwkUUk@maUbmbVlk¦xUVUIWVUkJVVkL@UmJUUVU@lLUVUlx@@VbJUL¯¤@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@ImVUVka@@aUkJ@LUUVUKmLmbÅVmUUwUaKUL@U@xJmbm@nVJ@X@VkVnlLXx@b@bUVLU`UnbU@@mVVX@JX@VLVVklV`@bUL@VLVKn@U@UJkn@lmLmK@X@Jn@mbnÞWVXnJkKČÑÆ@VK@knaÜmXlUČW°kôÇÆ@a@yÞ_VmUnU@K"],"encodeOffsets":[[111893,32513]]}},{"type":"Feature","id":"500116","properties":{"name":"江津区","cp":[106.2158,28.9874],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@InWUUlU@LValX@°²lÒXxlK@Ul@@Un@UaVJ@I@W@UUUVUwVIUKUaUUVwn@Üx@XUlnnbJ@¥VklKUUlk@ynU@kVUUVWnI@¥V£VWVIUKU@UVa@n@Vm@@nlUaVkUwJ@blLkLW@XWmXkmmLn@m@U@UVm@UVUUlakUVaVkV@@wnaWUk@VwklmVIkUUxmJ@U@KIkx±V@IUm@K@IUKkbWKUbnm@bmVnbmb@xkxUJ@ULW`@bX@WVXL@V¯mk¯@UJ@VmLUaWnX@WJ@nkKkxW@UIV@@KkImmkK@UW@XaWIU@UIkbWbxXlLVbnV@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@Vbn@VJVLnaVanbl@VlVXxlbXUWaX@VUUVwUUVm@I@WmI@amlLlK@alwnUV@kóVaÝk@UlbVK@VU»VUUVWU@U`ULkwm@@KmU@knK»VkJkUmbLkbmK@UUyUU@awm@@XXJ@VVLVVUbVnUJVX@Kk`WXXJWXUbmW@bkLUm`Xnb@JVL@LU@°VVXKVnUxVLUbmJ"],"encodeOffsets":[[110588,30769]]}},{"type":"Feature","id":"500237","properties":{"name":"巫山县","cp":[109.8853,31.1188],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@kVUbkKmbVxkLmKkllbV@@LXbxlaLVVVKXXV@@bVlKV@ln@¼°KXaU@Ulw°JXalIUaÝWXW@kVU@VUVWUUUamUw@aVamwn@VUUlLXWm£@wÇĉkKklmLUÒ¯Wn@ğ±kwmaWm¼U@@LUV@V@XVUnVJLW@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@xVn@nJ@LUVVX@lbUJV@@nn@VVVK@zV@nzVJVUlmX@@_VVVbnaVal@@knW@wnaVK@aVIJ@£kUVW@wXUVJam@Ik_X¥@WwkKkwmkUxnÅmm¥WV@Um@UlVL@JU@@X@UVkKVkKVkKkb@bmJVXUVVUbU@@`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@aVKXVanb£°mnIVaUKVwUmWLUU¯V@@KUK@IaWmn_VlK@anXVaXWWIXWl_@LUWVIUmVaUUUK@UWI@Wn@VI@mkU@U¯Kl@ImVÅLwU¤óbUU@wWXkmm@LU@@VUIWVUL@JUnax@JnbUIWVx@UXlV@¤IUJ@bULmb@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":["@@lwbVm@IVKXUVJ@UV@@KnnWlX@xVVôaV£xÆKnUVm@UmIXm¯¯@WkWVwmkXlaUwV»ULmk_VkK@ÅWa@aUU@mkaIb@n¼nm_@mmK@ULUVVmI@aUJ@XWJ@U`UIkm±kk@@lULmUmKUnVnlUVmI@VkVlxbkIVmLUxkKUXn¦ÆnmVwlnlxlLXx@W¦`"],"encodeOffsets":[[110262,30291]]}},{"type":"Feature","id":"500119","properties":{"name":"南川区","cp":[107.1716,29.1302],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VUbVJVUn@VLX@WVXVVI@VUVWxU@m@ĊX@@¼V°aVUX`@_V@VaUUVUWnI@alaLUlLUllLVU@@WV@@IUKVkn@@VlLVwnKUlJakwlU@UnJVUmkUVmXa@wVK@UUw@VVI@ak@alInwlKXUmaUW@wWLkKVak_ÇaUV@XbLVxUlWIk@UK@V@kU@VbUVUlVnLUV@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@VnbÆbXKlLUÒV@@llUnxll@z@LU@@V°b@Vn@l@VÑUnK@UU@aUakVm@K¯wklmnnUl`nI@almkIUwmWVkUakkJmUUa@K@aU@@_m@@wUyVUUa@Um@awl@Wka±UkUykIWVb@bUVk@aU@UXUUIWakUWmUxUV@nUVWb@XXVVmXX@VbVLkVWx"],"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@VXVXV@@W@UIVK@kUKna@£VWUaVUUalIVJVIUW_lm@bXKV@mn@JUUw@KnIVll@VanLVmUkVKXLVKUIVamw@UaU_lwKlwUWV_Ua@aUa@KUwm_Ó@wU@nkK@am@UkUKmXk`m@@I@K@I@mkVmIUxUJ@kUL@JVVlnklWnn`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":["@@XKVXlKVL@UnV@aValXXKU@WVwUaVU@IV@@aVWL@U@anVV@@bVK@UVL@bnJWL@VnUnb@@JnIlVl@@bXIWbn@UKVLVKXLlaV@VVnK@bVLmIV@KmknUUWVI@aVJ@_WU_VmUwU@KVak@am¯mJU_UJUkU@WkIV`UI@JV@LmmU@@mbUzÅ@VK@nUKbakb@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":["@@@¦@XlVX@@UVKlVUX@lanVlUVbXWVXVVVUnKVUlwUwU@UJ@nmVkUVlwXam@VaUUUw@W@kk»mV@UmKkwVKVUU@@LUKVI@mV@XVWxnXVKUUUK@wWU@UUWnUlLXamUIam@wI@K@amImUUkI@makUkKWUUan@wamLVxk@UVmUUL@Vm@kV@I@ak@@bWVXJlLVbVL@@bn@@`Un@WbUKULWVXb@UVmbXWVb@bVmxUKUV@Un@V@V@nmnKlnnWWXX@lKkK@aIVxUlVbk@mn@@U@mbVUV@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²mlVUllVnI@VlKUUlIVXUVJVUwl¥UkUKUIm@aU@mUna@XUWmkK@aVIUa@aUVmIXa@Kl@UUVKUIUJmwU@@aWInUVa»k@@l¯n¤mabWUUL@bnl@bÝWVnbU@mLUWk@Wbka@WVUU@UmUmVkUULVlVUxl@L@VbÈÒlb"],"encodeOffsets":[[110239,31146]]}},{"type":"Feature","id":"500228","properties":{"name":"梁平县","cp":[107.7429,30.6519],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XLV@VV@b°°nnkb@bnJWVXblIUVxWnUJnVVLVUJlUnLVK@UnUVJ²nKVbVKla@aXlJkKlb@U°£KVIUa@@kwVVUkKV@VUkkUVk±n@xkl@U@»@XVÝĉUJnxWb@UXKkVUbUKWUkVmkkLU`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_VJlnVlnb²VVVJVVmUUkĕUamçU@»W@@ĉnV@XwVU@UUJWUXUW@UKm@UVUIVaUUVmLUVUUUWWXUakVmUkbW@UVkUL@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@bUbxUxVbXJVbUVWIUVU@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ÜnWVLXlxVVxXxlVn@@bVblK@a@UnLVJV@@UnLVU@VXaVKVX@n`WUÿ@IUKlaUUUkWyUÛÅÝ@mmkUKUwW@Xk@amUUakKWwXaK@VVLklXVlkxVUL@bm@Vxn`IVxUVkLVUl@@lkXmmVUn@VV@Xb"],"encodeOffsets":[[108192,30038]]}},{"type":"Feature","id":"500231","properties":{"name":"垫江县","cp":[107.4573,30.2454],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@Ċ°¤nÒ¼aV_lKnllUXVVLValULVW@XamwVIUKkaÇÑa@U@KkVwkUUVKlVnU@aU@VIka@akU@KVL@WÝçUV@Vmbů@LKnnJWVkxlL@VX@VxmnXVWxUb@bkn"],"encodeOffsets":[[109812,30961]]}},{"type":"Feature","id":"500112","properties":{"name":"渝北区","cp":[106.7212,29.8499],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@@bVVXLa@lnbWn@L@XVlK@VVLUVlbkLUKVVVL@VnXVL@VV@UbVb@x@¦UxVb@bUJL@LVVxlK@nk@U@WUVLlKXV@VblU@UUKVU@wn@VJVanLlkX@VaVK¯@a@U@U@VaUKkUU±maUkm@UUkbm@@Vk@@JwU@Ub@I@JmwUL@a@@KkVÇLkWk@kUU@@xUVmKUnllUb"],"encodeOffsets":[[109013,30381]]}},{"type":"Feature","id":"500115","properties":{"name":"长寿区","cp":[107.1606,29.9762],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VVUbXlX¥l@XnVmlxUx@@blVnnôĀlm@aVaXwWUnmUwW@@UkKlwUXmImL@KÆ°na@UUImyU@@yULUUm@@mU@VIkaW@UUV@KI@mmUw@mKUnUUIlVLUb@@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@UXLlUJXa@_@@aVKÅWVkwWawUa@am@kUWLU@kWmX@ykI@W@UV@na@LlLV@UkwWUKmXX`mIVl@bXLWVkbkkx@`VXm@@J@U@UUKUxk@WbUIVl@VXLWJUkUlUImxXlmb@X@VUJUnVbW@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@LlklVLkxWK@bXb@Vbk@Vb@ll@@nVlnIlmXblaXl@W@_Ü@UUalU@aXL@VlabaVL@mUL@UUÇXUWX_WaU»m_@UWULWb@UUVmK@VU@UImK@V@bkLxXblxXUÆUL@b@@`WbIkVWK@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@WnaWknwVJVkVlIXWK@UUkVJXal@VwVL@V@V@In@UW@_wlllaXUWK@aUknJW_Û@aWaU@@UVmUUaUImJVnÅUmVUm`kUUVWLnVU@VVmXK@nxmULkxImJ@nU`@X@Vkn@`@nlV@nVJVaXVLnK@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¼VXbW`XWVÈVVVkV@@UXa@alK@IU@UKWUyUI@wVUUWVak@VUkW¹@WXI@yVIUK@kWwkѯ±W@kUb@KkVVVmXJ"],"encodeOffsets":[[108585,30032]]}},{"type":"Feature","id":"500109","properties":{"name":"北碚区","cp":[106.5674,29.8883],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XVLV@@JkL@bWb@VU@UlÆVya@nV@nn@KU@IVJU_lJXV@VlVIV`nIn°@blUbKVI@aUaVw@¥@wUaVaU@@UUKWm@UUKUUVLlKkaVUUK@UkLWU@@KXmma@kbWKUU@aUamLnÞ@VWLk@@Wm@ULU@@UKUVWI"],"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@kVUKUmVkUa@I@KW@@bk@@mU@m@k@a@aIUxmJk@wULwkKmVVX@VXV@xVLVVULmWXwWUU@@nUJVL@KV@UVULlxnL@VnUl¼@l@XVxVVUbn@WbkxUlVnU@m"],"encodeOffsets":[[109452,29779]]}},{"type":"Feature","id":"500107","properties":{"name":"九龙坡区","cp":[106.3586,29.4049],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XKL@V@XbV@lW@UV@@VXIV@UVKlL@KnnJ@VV@VU@I@@mVUVWUUmL@V¯LUK@UV@UU@a@U@yU@WLUK@X@KUVmL@@aXI@w@ammVk@WÛwm@UxVVVbVLUJVxVUV@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ºlUVl@UbVXUV@xVJVzXJVUL@VV@VKn@@Xl@XK@UmÝnKVbVakkVm@kUK@UmIm@LkKULVU@WJ@UU@@VkXU@Wa@@UKWL"],"encodeOffsets":[[108799,30241]]}},{"type":"Feature","id":"500108","properties":{"name":"南岸区","cp":[106.6663,29.5367],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VVJVL@bUVVnl`XIlwXJlw°nnlIXW@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@mkUIm`k@WXJmk¯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¥WKkVkImUmwa@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@aUKIUU@@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":["@@@knyk@KU¥wV@nkWzUmk@@lKUa@aVI@UKUamKUUVaUI@X@UV@K±IUVVlUbUbUL@KWUXmWk@KkXmmkÅKUa@amUbkUkKWUnwUÇwVUUÝUKV£U@nKWwXLVKm¥@wUXkmWk@@wX@lU@yVImaXwV@knU@mbk@mlUXmU@mV@n@bnW@bUIWJImVUKWbUK@nkKaU@W_VUUmWmL@UU@bUWUL@V@bmVUz@`mUUVVbXL@VL@lmLUxmVamXkW@xWbUVbUxkU±@ÅUmmkLUbW@@`kLknVlV@lbXxlVUXVVUU@UbWkIWVUUUJkI@llbUxVL@VVUU°ULUmWXUV@VULWb@xm@UaVLVKUa@w@VbkmVambUUm@@VkK@@bxlxX@n¤@X@@lkLWV@nVkb@bWJXLWx@nkxmmbXn@VWVUn@VnJ@bVXl@VJXnWbX`lLUlJVI@@VXV@Vl@bn@@Æmn@VxXU@mVIlxVnIl@nVJaXI@mlU@aXkVm°klmnVV_na°@V@xܦXKVnnUlVXbVKLXKV@naV@@VVl@@lXblXWnLlbVK²n@@VLUnlV@lXxô°V@UnaUUlKXLVUVVUbVVlUnJVX@VW@an@lb@nl@VU@anUVW@kaUm@InVVKVU@kUW@Uam@km@kVa@a@nwU@WlI@mVI@WXaW_n@nlkkW@U¥@kV@Uw@wU@@IXK¥VIn@nU@`@Xl@VVLnaWbVaUwnU@VIKlV"],"encodeOffsets":[[122119,28086]]}},{"type":"Feature","id":"3504","properties":{"name":"三明市","cp":[117.5317,26.3013],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@lL@Un@VVnabnUla@Ux@VbULUKVbn@w@XaVK@UVUXWVnVKV¯VU@UUKVwka@klJVIVVXUlJXVaV@VUUVWkUWwkaU@UklmlK@_X@ValKnnÆV²@lVVwUaVXa@wlXnWbnUVwnK@kK@UWKUaVUnV@_VynU@a@UVKVXaV@@VnKnXVVUX`V@blL@mVLXaVLnUJXIVJ@amX@a@mnUV@nVWnkl@naV@ml@@KmKUam@UU@@UlKUVkUK@aVaUwVU¥UIkJ@wmI@mbkwkVW@UXKULU`IVKUa@LkkVmUU@WlULUWÅU@I@WWnU@@w@a@Uam_XyVIVWkk@mwVKXUV@nwVXkWÅU@aU¯KUnK@¯mULXVLnWVbVbUVm@Ub¯¼W@am`kbamLUUUaUXV`@x@XmJ@n@L@xkJUU@kU@mWm@kUUwUUVWl@VUkIy@kkaVUUmIWVXbWxU@kmVkK@nWVX¦WxU@@bkx@VU@Wk@kUbmJUUmkUW@_kKWK@knV¤kIUKWLUbV@Wbk@@VWL@VkI@lUXVxUVU@@mWIV@a¯nUaaUV@Jb@bÞ°VbU@XaUVmL@VXblnV°n@Vnx@VUUUlK@InJVb@Vlnn@VL@VWJUx@XlJUVVVl@LUUUJ@L@lUL°¦kVVnV@xVl@blLnlLVaXll@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":["@@aI@VUbVb°m@bUXJ@nV@VUUwVW@klJ@UXK@Ul@Xa@UVaXKVLlJU£lm@XLlL@`VXnlVVnIVall@XV@@Ulw@aV@XwW¥XU@mlLnUlV@XwWaXUJVnUVlb@lzlJUVk@UXVVVxlVn@nXV@@lVVlI@w@K@mnI@W@wU_VWbVVVnKbla_nbX@°»Van@VUUaUamXUKWK@a@Uk@wWkXWW@wUUKw@_lywUkU@@U@kamVmXaUVUka@Wk@»UUUVKkbWUVUbk@mkxkKnIVUmW@kUKmXUmVaU@kU@m@KUWVkIWJ@U@UI@wUUUa@KW»nU@mVkUmm@XwWU@UUmL@w@mnVUU@aWak@@amxU@UxULWVXbVLU`mbUImVUbnV@@bVn@bnVWxLmyUbIUK@aVmakbVUXWUlKWbkV@WLUlk@@nbb@lkKmU@UIWJkw¯UUVVxm@@XkbWxXKlUzWJkUUL@bmKkV@@VUIUlWV@XK@VkbWx°xUb@LUbk@@VWb@LXJ@VWXU@@bUVVVVn@VVlLn@l@xk¦Vx@bVJXbn@JlnXxV@@nJ@X@V@lmxbUn@xVL@VVKlL@lnLVaVL@xkl@LxVl°XWVXVlJWnxlJ"],"encodeOffsets":[[119194,26657]]}},{"type":"Feature","id":"3509","properties":{"name":"宁德市","cp":[119.6521,26.9824],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@@LVKVaVaUkVU²J@LVU@@WVJUbVVnLVbL@VUJ@bVbkL@l@VnyXmlU@xV¦L@lmz@lnL@bVVbVb@lnKVkVl¤@zXV@l@XJVLVKnXVKVnU@wUm@KU@UlVlw@U@U@UaUKlU@kXKlmXIWKXaVIVUVK@KU@@kJVUnLVJUL@VIVa@VnLKUnl`VbVV@Vbn@Vzn@lKnVlIVVKUalkXJl@XXVWVLVUUmVU@Unm£lK@Uk@WUXK@U@WVwVkĠkĢÇ°aUÅUwmaţɱUÇaw±V¹XalKôx@UVaÜʓͿVóbÅLJm¯Vk¦k@mamXkKUULakbk@mV@LkJWb@VkmXk@UVmaUV@amLUKUamI@KUaU@WbU@UUUUIWJUkm@wKkVJm@kxÇVUK@mUVUkmlkkVm@amwLVWU@UbVLkUb@VmK@XaVWU_VJnwV@@kUmWakx@kwWakIWxnbUJz@kVW@@x@XllnVW@xn¦ULWKXxmL@VU¤VLÞVVUÈxVmxXVlLlVanV@bbVLlÆ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¦UVxUb@bLVUlVkL@V@VVn@VbLn@LUlJXblx@lwXbVn@lU@mxUIV`UXWb@nLU@ValUKVaV@UXKnxbn@lUkllnUVnV@VLUÈlwn@UIlLxn@VlXIVJVVVV@XaV@Vb@LnJVbVLnK@bVUnbVUl@nWl@UXalI@KnUl@labVKVlLnWnbl@l¥°UnIÆKôaUa@UUwÇWǓIUWUÅVkƨm@@£@KmLU¤ULˣJkUVǟUUķ@ĉVKUk@Ñ°wôÇç@īé@Åţ¥mīÛkm¼Å@VķVó°ō¦U°n@bVJXVVL@bUakLmx@xmxXzW`XbWnXV@bWLÛ@a@aXbWVkaÝwU@mlWKkLWWkLUKULW@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@bVVUm@nx@nKVV@XVWxn@VnUl@nmVX¼@LVbVV@xVJV@@XIlJXUV@Ln@lVV@UbVnnWVL@lnXUVmJLlwnll@VaUXVlaLVUVV@¼Xl@lbUVVWbnnUlb@@VV@aVUmlUaUny@kU@Wkk@WaUVk@@ammk@@U@UlU@aUa@wl@mXLllnLU@anVnU@L@VVV@KlXnWVnVanUw@w@wmnÅ@waUam@UkmUl@@aa@U@¥kôKwȯ°w@ŻkwǕaKÑÛk@ĕōřċ£ĵUKW»kÅŻLU@Ulġw@¤VzVUbkKUbmLmlULU¼UxmbXl@bWVb@bUnVUVbULU@@VkbVL@`U@WX@XV@b°@b¯@¤@Xm@@b@`UVVUL"],"encodeOffsets":[[119712,24953]]}},{"type":"Feature","id":"3505","properties":{"name":"泉州市","cp":[118.3228,25.1147],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@Vlxkz@`xLVV@xXXWXl@xl@V@bnV°@LVm°LVbV@ÆXWlUmxU@WVULnx@llUXUJWzn`Vb@@b@xV@mXX@@JÆVVXVKXkV@nVlUl@KVbULJV_VKLVWX@lUVkIU¥lIVyVU@wm£nUVWU@am@UmWw@UX@@amVUn@@aUUlUVanaWUXWmUnkK@VUlVVUUw@XLWWXma@knmbVbVXbVL@XJlInlLwmXów@çV»ÇçŋaķƧóƅóKġ°nÅUķƑUÇW@¯xÇ°öÆlVn@lla@Lb`@VXVVx@V@bULVJUkÇ@¼XUKk@mmULkaWbk@x@UkL@a@K@U@UmKmbU@kV@UmVUbUmmXkW@LUU@U@KmVmU@bVmKkkWKnk@@xVb@bkV@V@Vl@nn@bl@VUXbl@XlV@@lmzVVbknUVb"],"encodeOffsets":[[120398,25797]]}},{"type":"Feature","id":"3503","properties":{"name":"莆田市","cp":[119.0918,25.3455],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@VbÞVVnUlUX@VKVLlKXXlKXLnkV@ÞxlbXUWab@bÜ@XK@aWUXmWaX_Wynw@wnwlKbV@aUKWUUI@amV¯Ŏ¥ô¯ĸUUÆ@n»¯aƿé@ţ¯nĉĬÝKóó@ÑU¼@èxWônxKmkkJWI@UKWaUUaamn@lnbWXXWK@VxUVkUV@ULmlnVWXXVmbUbkVVV@bm@UVn@bW@@VXxn@Vn@bVUX"],"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@Vwl@XalbVKnnl@VLW»È@lVUIVK@a@UUwWUU@_aK@bkkm@UkõÅxóLl@¦@Vb@bk@VnVln@Vbb@xmÆn@x@xx"],"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±JkkUwyÞIČxĊĕĊ¯¥ÆUkţUÅÓ±¼IUx¯UÒƑÝÅ°KÝnğ°ÅU@@Vn@þ¼¯WnŎ°XLWlnVnbWnVXxmbabóUlǕUUaIUmlU¥k¥ĉwkkÝɛa@¯U¯°mVkVnKlōÑÇÑU@klUġkUŻnUW@¯k»mWV£UKnUmUww@UIVaXwm»Èmmwn¯ċ¯LĉUJUalka±Va@Uk@ÛѯWmnUaɝ¤Ûmn¯m±x@wóxÛLġÒUx¯VÈJUbózÝÇKĉ¯ōlÝUÅWl¯nťbÝ@¯ǩLġmV@ƯĢkÆmĊkVťLɃmÝXó°@ĢbVóVݦɱ@ƧaġUVĠÇÈV¼UVţwmbJÇwˋaXmǯKkkmbXm¼V¼ǬŚ²¤ôŰÆƴô̐ŤǪnɆӨ¼ɆLÆłUĊxŎƞȘǔˎǬǪnƨŮǬö°»ġÞÜÆĸÒĊǀbƾèôÈ@¼¯þŤĸƧ°VĀ¯b@lÈĊʠń̐ȘKǀֲॗţÿǕý@ʊǓƨóÆÑǖŃôw@ʈƆÅÈVVĊVóĊÅ@ÞƒĬV@Þī@°V@ĸĢ°XτƜĠ@ÈaÜ¥ŐƅnğóĕVġUůƿŋĕa±VUťÇğÑ"],"encodeOffsets":[[101892,40821]]}},{"type":"Feature","id":"6207","properties":{"name":"张掖市","cp":[99.7998,38.7433],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@ÈÒŎÒkmLUlU¯nV°@°ɜbÞĠaÈ»ĸlLVUÈ@Ċ@ýUm@@ÆVĠ¯ÞmLƯރѰVVwJ²»ÆÔVlŤÅV¦ĉ°ĉĖċwÝJzVxll²IVVVþX¤źV°¦VĊ@ÆbÈmǔLĸĠ¯Ģaô¯ĸmÆÛUlÇĸk°XyĊUǔVǩnmV»a@ýnK°n@l¥@»żĊ¤mç@£ČU@mmVkÞUƐ±²¹°ĠwÅƑŃU¯V¯aÈŁÇ»ġn_°xŎKlxklx@Þw@Æm²bDzLlkWXať¯ĊaÑK±w@wUÅçV±Uk@@¯¯xU±±UU°ōxVxÅÔō°ó¯UݦóbÝþ@ĉÈóUVUx@VUVÝ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":["@@ÞnKlnwX¥WÝXkxÞUn°aĊVnUUKlÞĶWXnĠ¥ô»@nmVL@¤°VzJanU@aÆwna@kU¯yX_aĉbwéXkWwÅa¯V¥m¯UI@@mb°aÈçU¥@»knwɜƇ°I°ÑÈmVU¯Xa@wW@wV¯Č¥l¯Uwnm@kaUaóKkk@Çab@ÒWa¯IÇxÛam¼VUxÒl@zÝÒ¯bÝaĉVĉwÇWzJmJn²mܯU¯ĉ@ġ¤Åb@²nml@@ULVxVU¼Ålmab@°l@WIU¯@m@ó@UzţyXÇUÇVUUVLkbWakVWmUbkkKUÆ»n°Knk@aUVmnk»l¯Ģlw@_kKVU@na@lUk@¯¥mV@kmbWb¯Åõa@mkU@kÇkU@`@óóbl¼Uxn¼lVÈx@blVkVVn`XÈġÈ@ÇK£ÝJmUUnUĖmlUmKUnVÅaUwUĉ`¯n¯wW¼nxV@bĉnkIċŘkXU±ÒxÈ@X°`lVIȯĊVVVan@VaUVażVmblkÈWWIXaalL@wVbV¦lL@lĠnÒUnkL@ÆÞkÞKbñþW¦ÛċVULUºkÈlŎUxÆxÞUUxÒx@XbL@lÆ@ÒlXVln@bm¼J@Ånx@bnĠmxVXmbÈè@Ċ£ČWw"],"encodeOffsets":[[105210,36349]]}},{"type":"Feature","id":"6206","properties":{"name":"武威市","cp":[103.0188,38.1061],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@±¯¥@klwU»ÞÝmwKm¯ç@kVÇUL¯lVUKġġm@a@U@X£°l°LŎÇ@aōVÝwÔKUÅWJ¯lm@ÛVWa@klĉUmaLUanak¯J±KkXóÜÅx²Ç@nUÒĊb°@ÆkLXÇÆ@xÝnxWxţ¯¤I@ÆnVVVlU²ÆèV@x²xLÒĉbŦ°WbXklÞ@l¤XĊ`wl@ĢÈŎm@bnVUb@ÈÆÛ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`UmV¼@nnÆwVlnVVaLVÈ_ÿÞ@naxÆ@l_@VxnK@llLnxmÈŎJnbUxI°l@n¦lÈIlmX¥k°@kJk²é@klaUaVaU@@ÝnIWnmnxkºÞaV°V@nwKxôbÞ£VUbþLn»mVwIJ°@nb@°°IġUkÇKV@ů»lLnm£@anK@ÑÜn@»mL@£ykUUmbUÞÝ@kyÇbó»XUxWVzb±mÝbXawUamL¯»@wUKVwm¯ĵJ°ÅUWVkKVk°wÈVVÑlU¥kmVamknUw¯¯bċ¥ÅKkKkVċVk£kKVwÑa@kóyÛ¯ÇVkówXō¥Ç¼ów¯U±k@xIĉÒÅVmÈnÜ@n°bUbÝVUnnJ¯Į@m¦nVÜ@L°JXbÑ@aÈb@llôLVbb@lmnVxk°ċ¦U°@xX@xWb°UVÇn¯Ò¯Jɛƈmxl@¼"],"encodeOffsets":[[106527,34943]]}},{"type":"Feature","id":"6210","properties":{"name":"庆阳市","cp":[107.5342,36.2],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@kwĉ»VamV¯wIóVkl¯KmVō¯ÝWkL@bÝKō¦@@Lx@b@la@km@@l¯nm@UaÅ@óWUXm¥nw`@UUxķôÇ°ğ¦@VJ_nIVnalxkXJWn¯nVLxl¤nnVbklVX@xnxmV@bUK@nm@@xV°±aÅnkUWnUax@mn@¯LmUĀlU@lV@blLUblxklkIÇx¯°UXbaVUnV@°LUlnbX@`°nVmbnÆmVkLmK¦U@Xy@kl@U°K@¼XbW@bWnLVaVVz@xlVČ¥lbUxÞlVU@nÆWôn²VJlUƧLnmÜLXan@mw@wlUlV²mblwVÈlLÞ±@lVnUlxnkma@mkJ@kXVU@mn@¼VXUVlLnmVbôaVnWV»ÈUl°È¯ÆInÆU@kk»mKkÆġk¯@»mk¯@óÇlÇ@VykklUml¯Þ@w"],"encodeOffsets":[[111229,36383]]}},{"type":"Feature","id":"6204","properties":{"name":"白银市","cp":[104.8645,36.5076],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@VKUÈl@è°nLnxÝÞV¼kx@l¦²°ĊóĠĊ»@ÈxaĊxlwÈVŤa@¯²aÇ£Jk£lnUÞ@°ô@ywl»lIX¥Ǫnw@ÑÞWlaÅlL@Uwĉakl@¯mwna°JV¯nUVÓÞÑm£²óWaUÇ@óÝUçV»ÈkkW@¯xV@XlK@wX@Vmm_@wÈÝKU¯ÇwVwÅK¯VkJXkWVaIm¯UkÇlVĀV°mxók@¼óWxĉÜU@UbzÛJÇk@ÆnVlÔ@kxô@ĬWL¯K@aÛImm@IUa@UÇêU¤VÒÇx¯ÒVlk@Wbĉ¦UbkWV_y¯Laók@b@nmbkx°"],"encodeOffsets":[[106077,37885]]}},{"type":"Feature","id":"6211","properties":{"name":"定西市","cp":[104.5569,35.0848],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@aV²wVJV_@LlanÅllŦçÜÓ_lnWaôkxUbmV@È°lènk°l¦`@nnL@ÈlÜIyVaV@ĊÛXwô@»lônwU¯ÿUÈkl°VnJUblXWIl°UV@aVVVmnL@lUUwmk£bV¥VUVwÛlaÇÝÞmk£LUy¯L@WlkKW_XaWmġU@akakXkmVwmŹVUbWónmwnWW£KÈnV¥¥Æ_klWbU¯V°aôbnaVwmaōInÇmwkK@kmLUw@`kÅ@wb@mÝĀÇ`UKUbmUUkÅxmm@»nUVk_Ý@ǦVÇè¯ban@@JV°nU¦°ÆbXxWlêxĊabW`zV°@lmbÅx@bmVbI`¦@ÒUVUI@ÆL@b¼@@lmxnL°ULÞğÞ°kLUL°xVnKVl@zX@"],"encodeOffsets":[[106122,36794]]}},{"type":"Feature","id":"6205","properties":{"name":"天水市","cp":[105.6445,34.6289],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@UyÈVVUnn@VU`UblzJnk@VbKU°lwW°nkVUÈl£°V@n¥VklkU±Unlw¯UkwmKUlmkUmnkym@Å@UmWÈU°l°anlJkUKlU¯Èm@kmWV»kkÝLUWUx±b@¯ma@¯IJUxnm¼KýaVUݤóawLmxU@¯UbݹlmwmnXmJ@ÞV@UbVbkbl@±êlIl¯@lW¦knÇJkm¥k@¯Jmbóa¯bUV°akXlÅ`¦U¦ÇmLX¤mXnxmôXaVźUnUxlnlWbl@bĢVnXWbX`lLXk@°KVzKl¤nÞÝÈkbÜ"],"encodeOffsets":[[108180,35984]]}},{"type":"Feature","id":"6201","properties":{"name":"兰州市","cp":[103.5901,36.3043],"childNum":5},"geometry":{"type":"MultiPolygon","coordinates":[["@@lW²L°IlmbVbKnbĊVlk@XbÜU@kn°XIÆVLÓÞxŎUlôb°KzU`lXVaĊ¥Xal@kU°ÑÈwUÑV£ÈéV@VbJ@nnÜJ@bL°XK@īówl@kÓmUÅmK@m_k¥l¯mkçǯ@nUaVwólXbmk`ÛÔťèkkmÆkbK@U`UI±xUbWlXmbVbÅÒólkIWJk@zKŻ¼@xUxó¯LWb@ÅÒ±¦U`nbťĀUVbLU"],["@@¯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ĊÆwnJmwUxaUkw@V@waVmlLXÝl@XVĢmV°@nl@UUUWK@wÿVI²Òlm@nÝĊýVV@nJ°Ułm@kV¼nKĢȤôKblnKllVk²aĠ¥È¯ĸóVw@V_xmn¦VWôXÆ@Vbn@°m@kn@@lb@ka@wK@@UlKVaWXW²¹lÓw@_°n@@_lKÅķW@mLUWn»Û@l_Ç`Ûmm°ÅbWb@VWbUUKÇÅaġlmkUġl»LlUm¦@¯U¤ÇkVUml¯Xx¯kVLUa@mlIkyVa_UV@mmUVUÇVzUxUVU¦a¤lnVxVk@mKUnUU@bU","@@@ż@mlkġk"],"encodeOffsets":[[107877,36338],[108439,36265]]}},{"type":"Feature","id":"6229","properties":{"name":"临夏回族自治州","cp":[103.2715,35.5737],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@@ż»Ly@lXIJlôkÆÑUanaWXkW@yk@ULmUw¯KVlK¯ĠÝÝVK¯mKnwk@@»@aK@ÅVJVU@Ñ¥_Uy¯@£UKmn@ó¼ğ¦WmĵXÝkVLmVĉU¯bmÝVwWlXÞW¦xkmmLݱU@VÞ@ÅÈW°XܼƨyUĮnWnXÝxUx°lVXJlôV"],"encodeOffsets":[[105548,37075]]}},{"type":"Feature","id":"6203","properties":{"name":"金昌市","cp":[102.074,38.5126],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@ĢÈ¼Çł°bU°VƒńÆǖŰnÆōĬǔaʠůĭ_kķÆ¥VÑÈçÜKÅ@ÇVaUm@aōnġÇk@xĉ_Wk£@ݱKȱaÅn@Ýx@kwlkwō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¦kVVnJVbǖVkôVabnaWwUXmmamUXkWKō¯Xm°»ĉÇ@UVKķ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¥ÆÇIlxmnbUxlUôl°kWl@ôVwUanUl@xVkaX¥kU»a¯±@kka@UwmUkwJk±k@L@ÝWUwVÝxÇU¯ÇX@mÅ@@yĉ£VmUwȗ»ÇUnlUnWU¯`Uk@@x@bÇxX¼VV¯LĀkÝL¯@VĀ¯lnĊW¦kVÇôkUÇUK@ţU@aóÜUU»@¦k@VxKVbn@Æl@xbWnlUlxÈlVÈ°Æ@¼@xWxŎVK°¥nÆkŎ@ÈÑmK@¥k@ô@nôV"],"encodeOffsets":[[115707,25527]]}},{"type":"Feature","id":"4402","properties":{"name":"韶关市","cp":[113.7964,24.7028],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@WXk±Ñ@UwmUwĉwlmn@Æwn£mkI¥ÇÅ@¥aón£nWWw£V`Þ@nVml@xô¼IV¥kUmkamUkVWwÛ»mó£UVÅKmn@x@kbmm¯aXkaVĉaUbݲlIlxnVVx@lb@l²°bV¼lW¦bUlwk@mVVbUxó@kX¯lókVkwVmankwJÅȦÇVUbU°blĀ°kÈ@x¦ÆÜ°@°¦óaVUôlUlbXl@nÜVnKlnIVÞ°W°U@bnm@¥IV²Ul°VnalzXyl_Vyƒ¦lLlx@ÞbKmknVWanwÑVwČº@n_ÞVaVÜIl@KÈVJ@a£È@@kmaV¯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@aUUċlkJk@wVJXUWk°W@nKnwlUl²blU@lIl@XbWxnm@lW@wwUJX¯VU°`ŎóˋkÝÝkÅ@ÇmğÈřmwaĵVxUÛ»°ĠǷnýmóX¥ɅĵҏÇ@°²ĊUĖ±ĮU¤Ç°Ā¯ɐnżUĊĊĬV@è@ÔÒU¼l¤nĠbêVĠ°ÈyzVaVnUÆLabVlwÆ@"],"encodeOffsets":[[113040,22416]]}},{"type":"Feature","id":"4414","properties":{"name":"梅州市","cp":[116.1255,24.1534],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@nÔlW¼x¦@lVllLkèa@z¤Ė¼UxlnUKUbÝlU¼lb@VxVklJÈwV¯@ĠlÛĖnbkÆźÞUÈôklmL¥LWnKUkVa°Vx@IVV@x°bUkaa@mV@@ywLÑUwVUVUbÞVVann@XwÇÿ¯²aVamkXaÆ»@»nw@¥UXakbWa¯KUw@¥m@kwmLU»UUJ@kmU@UUWU@yanwmçÛl¯¯UmKUmwVkmÝXbW@XWÝbk¯@±w@»U@W¯Å@Ç¥UU@IUakJĀê°þ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£@¦Ģklynn¼lW°zW°VbÈV@lÆbnnJkXVÆaÅW@UUw@kaV»ÞkVaVLkmVw»ĕ£@yblçkKkU@k¥wX»kmÓ@Wn¯I`@nlbWý¯éÿlI@XUmWUw@@UJUÇmKUV@xţk¯¯LWnUxK@ű»Vwa¯@¤WX@Û¦@¤ÇIȼWxX@WxwUnVbÅèmVa±²UWl@klȤnôܼXxlUnVlbVnlU¦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ôÛ@bV@ŤVLÈlVÈólUX¥mĉ°kÿU°@ÞKlÿ°KUUW»Èw@aw@@nm@w£kÓVUVnKk¥£Vam@nkKkbÆǫmakmLU¥UmÛwmVUmUJÇaUxÇIn`mb@Þ¯b@nJ@nlUVlVULW¯Û`Ç_¯`m¯IbĉWċzx±Jx¯ÆU_k@J@UmbXôlLn¦@¼ĊxlUXxUbLĠUnVĊwlUb@lWXm²@ÞWxXUnb"],"encodeOffsets":[[114627,24818]]}},{"type":"Feature","id":"4413","properties":{"name":"惠州市","cp":[114.6204,23.1647],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@lbW°bnnla@@wnmÆLVUkÇl@XkV²±bnUÆçUaVmxXw@WXwÇ»ÈJ@£Ü¥@XW@£°bUx²¼@ÆLVwmX°K°Ťl@wVUnLÈVVIky±wkKU¯ÅkXġÑÛlwUwlm@mnKWaÅm¯óÇmğb¯alĉUwķbmb@lÞÒVnmĀŹ@VbVUnmakLm`@xĉkklVÔVJVnlVUnmJmaLUblzmkLaō@@zV¦UV²kJnÜU@VXUL@lJL@bݤUnVb@xVnlK²Vx°VxlIlkVl²k¤@n"],"encodeOffsets":[[116776,24492]]}},{"type":"Feature","id":"4409","properties":{"name":"茂名市","cp":[111.0059,22.0221],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@LnÇlkKnkÆLUmÈxlUJló°n@ana@@X_@mÝóóU@aaU¯mL¯kV¯ÇVwkw@V±Ŏ£@@alw±Vk@mÅm¯ÿÅƧIÇ`ōô¯_UVW°IVx@xkX@mnwXWa@kkJ@kVa±kkVmxmL@¯XXlWVUI@xlIklVČV@blW@@nUxVblVxkôlxnynIƻưaXwlKbVnXbL¤kLèVV¼²IlĠVXynz°KVx°@VlLlblK"],"encodeOffsets":[[113761,23237]]}},{"type":"Feature","id":"4407","properties":{"name":"江门市","cp":[112.6318,22.1484],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@lUXx°JWnnÆXVWX@ºVLV¯nUVnbôxaXmWXIUb°xlKl¯KxXÞ°XÈ¥Ü@ĉÞUç»nóVmax¯UÅU¥Ý¯@ç@ș@çĉÅUmUç±ĉKÝxÝ_ÅJk¯»ó¯nmèkǀWx¼mnUÜġ°@¦@xLkÇaVnUxVVlnIlbnÆÆ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Þô@nVlÒôÆUnlnn@lmkmVkaÈkÆÆk¥ÅÞ»ÆKXkW¥ÅLmÅkamJUkUVwUmÈblKw@@¥Ģ¯VÛnm»Xwlƿ@kbWaʵ@óLl¯ƽ@Ln°Æ@nUl²kxb@@ō¤U²@lxUxÈU°l"],"encodeOffsets":[[114053,22782]]}},{"type":"Feature","id":"4453","properties":{"name":"云浮市","cp":[111.7859,22.8516],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@@VIl@`V°Åw²IwČyĊXa°Jn°_È`Ü_°XKVkUUVk@mmI@°a@Ýnam_ÈJVwlĉX@lUómaUmVU°UK¹@WXUWmÅXm¯IWwkVWlÅLݼÆl¦ÅÅÇlbUllnknm@kmVmóÅkÑUW`@@bmb@¯mkôIkVÇwnVÅKmlLklmÈKVĊK°²`n¤nUbWlxVxLUx@°nXm`VklVxmnnx"],"encodeOffsets":[[114053,23873]]}},{"type":"Feature","id":"4401","properties":{"name":"广州市","cp":[113.5107,23.2196],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@Ș¼VxUnĊ¤@z@Æ@nÈW°ÈVwUÞVxÞX@Kl@ÞVaĊbU@ml£k±lUkkJw¯UUw±kLUm@waUVmÞ£@aKkI@KVUW@ÛVmlIU±VU¥@yğzƧÇƽĠřÅnī±m@²¯l°@nÝÆóUll@XnÝVU¦mVV°V¼Jnb@°mbn@²¯¯wVw@@nmxX¤¯L@VLUm@@l"],"encodeOffsets":[[115673,24019]]}},{"type":"Feature","id":"4415","properties":{"name":"汕尾市","cp":[115.5762,23.0438],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@@@VxnXWV@bVJV@ÞÅU¥Ċx£UWUwÅUU¥WVUkĊÇnkV`°LVwnU@lbĊ¯Vnal@@çkUÝ¥ġaó¯ÅaÅLŻÆUýmy¯ó@ĉÆóȯwÆXbmL@nknVxkxÜĢÒWÆlV°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ÞWlnUxVnnL°V@kmĢl@ak@mlk°aX±nwm±²¯JV²@wW_maV»U@m¯ĉUÑJlabVnlĸLlƅÛDZwÝ@ĉxó@è@kmbUĉ°ka@mVxU¯KU_mlĉÈVlXUV¦ÆVxVVX¤ĉwV¦ÝÆ"],"encodeOffsets":[[118384,24036]]}},{"type":"Feature","id":"4404","properties":{"name":"珠海市","cp":[113.7305,22.1155],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@è@Þ°V¦VÆ°wnbUÆ»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":["@@ÈbInVVnUÜxnVV¦nKlnbÅǬlalL@mnUb¤l¦LUmUVlÔ¤@xmnVl°_XVVmkVmÈ@kn@VUK@°KW£nw@m@Ux°x°@±mna@¯amIU»U¯nUV¥ÞUWmk@Vk¯UknÑWÝĊÛ@ǦW¯WÝwLk°kL¯wVaWJXWnbwkVW@kĊ"],"encodeOffsets":[[115088,23316]]}},{"type":"Feature","id":"4451","properties":{"name":"潮州市","cp":[116.7847,23.8293],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@°Üknèmxbz@VVX@VnV@lIVVV¼nKlxn@@¦Vx°LXblaWbV°£¯W@nW@aUñVwW»@¥ŤÅUÝǓÝóV@ńÇkUVmIUwÅVWÇX¹@W¯bkl@nlb@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ÈÆUVxJUnlVÈ@ŃôUǔÞVçn»VyĢÛVm@»kaÝUǼóÛÈķKċ¥X¥Wwğk¯@wķKkUmabkIVÒ°Ċ@nVU¼bn`Xx"],"encodeOffsets":[[119251,24059]]}},{"type":"Feature","id":"4403","properties":{"name":"深圳市","cp":[114.5435,22.5439],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ÞL@xbVVK°X°Kô¥Vw@anUèlkĊl@wn_lKnbVmUaUź@nÿUmÝѯUbk@ÆkxŻ@aÇXwJ¯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":["@@Ŏ@blKnykVaKnbnIVmUkUmUIUÓçmV@bUxó¦¯LW¯LUUa@wÝKğŚƾƨÈĠy"],"encodeOffsets":[[116573,23670]]}},{"type":"Feature","id":"4420","properties":{"name":"中山市","cp":[113.4229,22.478],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@XÒlmV°ôÞÅ@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@VIl@XnJn@VUUalk@mK@kny@UlU@a°UU@VmaU@Ua@UWw@n@KmLm@alkmnIm@an@VIUamWÅImwU@@a@KX@JVLUVmUaVkUa@m@@Ulmkk°UaVUlKXbVwVIkaVmUk@KVk@aaW¯m@w¥laX@KmakVmnUl@nxVKInU@yVaVIV@na°KlxX@@_lmXUV`VIVV@n@lbn@@WUkValK@²yl@VUV@@K°L@KU@@UVaXIVVV@naVkVa@K@UUK@UUaLWaw@m@K@UVV@mVUUVKnLmVLKbVK@UUIkmI@mUIVK@IUK@VkL@WU@mU@WmUk@I@VJk@WwX_@amK@UUWkIK@LVb@mVmakL@J@bU@Ux@xbmI@`Iwm@UbmKUaUWa¯UkJWV@XJUU¯LUmV@ma@kkamKwLUUmWVkkm@aVUUkVKnVVUmXK@UW@km@Ukkm@@W@UkUy@I@aUUmb¤U@kUmL@bmJU@Ua@wkLWWkL@U@VaU@LUakKWbkUWVkKkLVLUV@JVbz@V@VmUU@kVmK¯@VU_VWakVmIUKUaU@@bml@XU@@V@LmKUVmVUKKbkaUXKUL@x@V@l@mxU¦V@lL@V@Ln@@VV@nlKUaV@nLUbmJnL@VWLkbmV@@LWXLlxVVIVV@x@V²blUVmLVUK@kWWXUlV@Xl`LXl@@Vn@VnbV@lVUVUÈVb@@`UXU`l@@XUVm@k@xmVknUJVXUbmKULmbx@VlJ@LVbkKUbVLÇUUVUVmU@VaUkUKVUwmLkUUVVlbkaXmwKUVVU@@V±Uk@VWUUm»XamUbKk`U@UnWW_kKmbUVUVmnUV@nJVUlUbU@UV@n@JmI@VmbnVUXlx¯kKmnVV@L@VbkVUmm@Ub¯LmlUL@VWLkmkLmmn£WmnKU_mWbnbmx@U¦UJU@Xmlk¦@mnUUm@@Jn@lVÔVJnIVWI@aÆK@I@aVKIlÞnnl@nl`nbÆX²l@xV@llbVn²VVl@nnV@IlW@Un@@kVa°KnÈmVaVXUlaVÈUVlwôUlynIVaan@lVXbI@n¥la@K_n@bÆx@XnJVnKVz@`VXVU`@b¦UV@VIlxUnVKXÈbVllbVbnVn@"],"encodeOffsets":[[109126,25684]]}},{"type":"Feature","id":"4512","properties":{"name":"河池市","cp":[107.8638,24.5819],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@lLVlbVV@nXVlI@JVXmnW°bIVV@ln@nalVUbnW@kVkÒlbVKn²°bUlV²@X@`nbaUI@°wlU@aXJVI@aVK@wUamIXm@XUV@@bV@VmImnUUwVaVKXUnVK@akVwV@nL@UV`n@@XlnIUJl@X¦V@aUIVm@anV@UwnL@VlbVL@KVVXUWwUUVUka@UVJnUlbnalbVVn@°LV`Þ@XVxV@@bVlUVVbXnWlXnml@XXWVXJmbUI@VllUVkn@@VWV@Vnb@VXUJVnn`lLVka»lVLnw@WV@lInw@WnU@U@mknUVóKwUmUXUU@@wVJVIl@XKVVVbVIJ@Un@lVLnmb@U@Ul@nU°VUVJnnVJV@@mVU@@wkUVwkKWkyUUkU@alkÈ@lJ@xIl@UUWVkUw@Kn@@kmaVUlUULÇUUKl@UUmL@aXU@mlUUwmKkUUVKVUaKUnK@U@Vl@XUWUKlwX@b@K@XkV@UwWJka@aUwmV@U@@U@wUm@»kLWVkIWXnmV@VkbmKLUbkVa@aa@@aVU@aVak£@±UkVU¯VUUJVUI@kxmUmWUbLw@K@aU@@aVU@Kma@aka@_VWkk@UWVUKULWKULU@KUnwVaUKxU@UmaLm@kVmVa@UkmI@@KmIkxU@@KU@mmakI@VLkmWkkJ_U@V@L@nxXbKVb@VVL@V@LUbUlmbU@UUWJUb@VV@@L¯K@LU@UVk@±z@kLUbVl@Xm@akm@U@UUJU_VWkn@`W@kw¯LmbU@UJUb@zmVJULmwk@mVUnlnb@LWkb¦@x°nXb@bUl@LVlUnlbUJUxWakLUVVb¯llkn@V@@nVbUlVbUnVUK@IW@L@bV@nxÆJnXVbUJm@@bnmJnkl@bnnK@Lm@Xx@VVbV@nb@UVV¯@bkV@Vmz@lnLl@kVbUVm@mI@WkJ@UWKkXkl"],"encodeOffsets":[[109126,25684]]}},{"type":"Feature","id":"4503","properties":{"name":"桂林市","cp":[110.5554,25.318],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@nU@JX@`XLm¦Vb`lVXXW@VblČnVlanLnmVLK@_Va¥@kUa@VmVbaV@XVVzlVVK@knKVmX£VKLlbn@b@llL@xĊôXaV@°È@¤bnV@@Wl_VU@WnVamwwVbn@KVLX@VmVUxlV@nVV_nK@mI@Wn@@IUĊ@@wVWX@@I°VVm@wmU@m@IUVklkUmmkÅV@@aV@@Wn_UKla@kaVlVanb@k@@KlVn@@aV@nIWWUUaVU@kKmwU@UImKk@UU@w@W@k@UkW@mk_W@Ua@a@¯mV£@mUUam@kWakVama@UUm@nw@alaUmnUlVlIVLVyk£Vm@k@UUJkK@kmKUwKkWK@UXImyVwnI@mkUlkUKkUVmw@kkJWUÈm@_k@@aaW@UUJUwU@@IWKkmUUV@nVl@bVb@bUUXakw@WUkbkKbm@xUlkLm@@wmKUX@UaVWXVmU@@UUUxkmWXkKkUWaUaUbL@`UL@LV`UXmK@VmakLVbkLxUJUIVbUVVb¯KV@Xnl@lVXbmÒnV@L@VWKkVUIWJkIUamUUbm@UkU@JUbW@XWxUam@kbVVUnUJmUUV@bU@UUV@Vk@bmULV¦U@VU`VLUL@xVbn@UJ@nWJXXVVV@bkxVbUxL@x¦@UlXUVVlULV@@nUb@xlnJVnlVknUlVUbmU@bVx"],"encodeOffsets":[[112399,26500]]}},{"type":"Feature","id":"4501","properties":{"name":"南宁市","cp":[108.479,23.1152],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@lKnbnU@Ua@KLlJVX@VnL@bW`Xxl@I@UJl@nV@XV@nXV@lK@UVL@JULVJ@nnJlVJ@VULaLUKnmKULVVU@nU`lIXllnK@UlJnb@nV@LV@lwnJ@L@nJl@VUbUn@lnKnbVV@wVLUbxVm@LVVKXLVKVLXU@VllUX@`lb@bnbL@UV@bV@@b@LxKVanXVUUmVUUUaVUkyUUaImK@mUUVUkKU_@W@UVVVIUWUVaVU@UUKn@k@al@ll@bnL@bVUVX@V@@bKnblmn@V_@aUalL@a@akK@kVKUKlwUUnV¥VmU_VWVIVaX@VaalÅK@LVJnalL@LnKwlVUwmX@VXlLUVnblaUmVUVwXU@Wm¯Va@ÞKnw@wmk»UVW²a@_mW@U@IyLVUUKW@@LX@VUV@@yVU@UV@nwUUmJka@IU@mVkaW@UwUX@`@kLWUk@mkUUm@kUUWkUkWxk@@VK@nV@UVaUUJmIkV@UamLUbkVmamLka@kmL¯WI@wJmwx@akU@aUKmbkaW_nW@_U@Wm@a@wkwUKmk@bkbw@mKUkkU@J@bW@kVWz@bVUaVUx@ULkJWbXVVX`@mJUVU@@Lk@WbU@UJlnXlmVx@Ln@b@KLXWJUUW@kaUVUbmV@nnV@n@lVLVmLXmXkV±@kxÅLUbJWIÅJ@ImXalkUamKkkL±aVwKUU@mÞnbWJXm@lbmKULWUUVkabnn@Vl@VVV@VbVbnLWLXJWxXLV@@VV"],"encodeOffsets":[[109958,23806]]}},{"type":"Feature","id":"4502","properties":{"name":"柳州市","cp":[109.3799,24.9774],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@wUaV@nVaUVklmkUUmmIk@waVm@U@VKUkVUkWV@¥@wKVwUalw@aUUUWWXI@mVIm@Ua@wVKUKV_UV@U¥VKnal@U@VU@VV@aVUnVVIVmUUlan@VbXwWX@Va@IlVVn@VanVVblJXIVJlUXL@U@KmUnÑWakU@mkJUI@mk@wUmmUV@JXaWIXWmaUIJkk@WnJ@aUak@kkJ@kUKU_@myUóWUkm¥kUmL@KUKm@k_UmVa@k@@UmU@mm_JWIUVUWLUlbVUJÇVUIVwKUVk@mU@n@lUL@Km@@l@LVzJmUU¤m@UbV²U`U@@¼Vn@x@V@@VnUVx@blbXIVxU@Wl@@LaW@kxLXVWVk@@U@VmLVLbUVULVVlnLVxkV@nWV@bnKVVk@VLVÈVKVVkUnb@lm@@LVxUlVX@VkJ@wkIÇ@kl@blVVVzXllLUxlV@x@UV@nU@UImmUIUV¯mVk@@V@VamnUKkm@@VIUJUaUUWLk@UJUI@xV@VVWVnxLUômVV@VkVVVUnV@UVkL@VVV@bVxla@bkXVJVn`nU@bb@bVL@VnJ@l@VaU@@_lW@UUU@Unlll@XLl@@UX@°bVWVanLlknVV@VVX@VVnUVLmbXJ@nllXX@`VXlmaXVWk@WkwJ@VL@JbnU@bn@@bVKUnVJVIVVVL²a@bV@@Vl@nUVakalmUL@VUL@Va@mXl@nK@UlKL@Vl@@nkllb@Vnn@nVV°lVInwlKXxlU°n@@I@UnVlakUJWkUK@anUWK@_ÞJ@U"],"encodeOffsets":[[112399,26500]]}},{"type":"Feature","id":"4514","properties":{"name":"崇左市","cp":[107.3364,22.4725],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@@JVzl@V@Xn@ll@VlnX@@VWLnUVmUULVlUV@blnUlnXVVKxnLlb@lnbU@Vn°KVVI@WXUlI°VXbVVbnLVan@xJ@_nJa@wVwV@@a@IU@UU@WKXwWIXKmKUaa@UUUUk@@UmmalbVUXVVKnLa@knWXImanÝV@VLUx²blKlnLVbklWbn@JÆIXJIVaÆKlw²@lUnWWnKUUK@k@mmU@mnUVaVUb@lVXVXIWK@Lam@@KUwnWkkmVIV@Xal@@KV@VUnI@_UWWUkam@kkm@ka@mk@wkJWIUU@WXkWXkWWLUU@UakLWXV±VIVWUU@anUWaUK@IU@Vak@@UUKWa@m@ak@@wUkla@mUaUklakwV¯¯@WWUkLkKmakLUnV`UxWX@Jkn@bmlakkk@b@l¯bmbJb@VXnbVV@bJUkkKWVU@mÛVUUW@UVUJWXkVkKmUL@WW@UVl@XXKWXJ@XVlmbUxnnm@UlVnV@XVm¦VJb@mLkKÇbXblVkn@l@bWnX`V@@IVV@VV°n@@_naÆVVbUVVbUJnzlVUlXkV@Vlx@XVnxbKUK@b¯VVUVL"],"encodeOffsets":[[109227,23440]]}},{"type":"Feature","id":"4513","properties":{"name":"来宾市","cp":[109.7095,23.8403],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@nVlw@VJUIVVUV°lU²V@l¤Ub@bUV@b@b@bUblVaKnLla@UnUWmXlJXUlKV@V_U±Van@V£nVIyU@K@kn@@LVK@k@mnVl@VULUxVJÈUVIUaVkXKVVUXJIn`@nnV@Vl@@UbVnl`n@VL@LnKlVn¦VlôXVnz@V`VL@llIll@Vbb@mIXl@lIVJnbWXXJWb@IUnVVn@xl@nVJI@WU°LUaVUUaVJVIwlKUalKnb@UnLVWU_@KVK@_KVa@VKU¯VLVKn@laaUkU@maVUJ@k@Um@XmbkyVaUIUU@KV@laVn@KXKWUkUk@aWUUVw@aXKmVaUUkmIlUU@wUaxUmmU¯U@WLUmVIUym@UVmUa@wmw@çm@aWLUJUIUamKmL@ax¯¥kU¥U@±kUVmKU_mJUbkKmLÅÇ_@WWUXUmaVUkKUWW@nVxkUxmL@KkKmbUI@KLkÆbUbW@UbUJUXV`UnU¦mVVkxVLUL@llL@b@bkKVb@bU`m@knmaL@a@@UWVUU@amK@akkk@@b@lmVL@VUVUbVVXUJUU@V@XV`lLUVVV@nnLJVbVlzUVVbVVnUVVU"],"encodeOffsets":[[111083,24599]]}},{"type":"Feature","id":"4509","properties":{"name":"玉林市","cp":[110.2148,22.3792],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@VJUXVVXlWX@VxVnX@@`ULWUXÅbWK@mULUUmJ@n¯b@l@VULVxxXU`VXXJVIV@nm`@nUVXn@lWVn@b@Jn@nU@Lm`@Xn@WJ¦U@@VnLlV@@Xl`nIlJnkVLw@KVK@UaVL@bVKXlUUKVK@IVLa@U@WLUlVL@bU@@blb@VlbUxVbXUVJ@xVLUlV@VUbVLnKlXJ@Lb@an@VanL@`VLKV_UWl@U_a@WVInlVUUUVm@I@W@wVakIWm@U@XwlaVbnI@m»Va@aXaVLU»@aVa@kKkL@KmU@WzUK@wU@VWUUVUUKUa@mKmbUK@_nWVaUkVaUaVUVLXKVVUVmVI@UkKkLm`UkW@UwWW_UaU@WakXmK@xUXJkUUWUk@WlmJ@km@@aUKzmyVka@kkWVUU¯lmU@@wkkmV@Vk@mÅIUka@Ub@m@UUU`mUbWaWmbXXKWIXUWm@Å@y@UkIUJUUWLUWL@UkVUxW@kaWbKWnXxW¦nm`XLVlUbVbUxI@JmLUKUb@VW@@bkL@b@VlU@xk@L@lxXxWXX°V@VVVbUVV@UVVbULVnVJUb²baUb@VVVVInlV@VnXaVUlIVUb"],"encodeOffsets":[[112478,22872]]}},{"type":"Feature","id":"4504","properties":{"name":"梧州市","cp":[110.9949,23.5052],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@VbXblVlLXWlnwVV@VV@UnWUXVb@VWXa@kVKUaVaVkUlyX@VaVmUwUaVU@UÈymI@aU°@nWV@VaVaw@IV@VmnLVK@kmmna@VbVI@aV@XbW`ULUVVx@VbUV@bl@VLXblJn¦lL°°@n@K@UlLnKa°LWbnJ¦UÒVUllLlVnKnbWnnV`w@@Xa±nl@XKV_WVkVa@kVyUa@wU£UW@UIVW@@awWaX_WKkVmUULmak@UJUI@±m»k@m»VyUImnmmwnkUmVaVIUn_mW@»Vk@VwkmmUXa@IaVmm@Wm_U@mIUWóLmUk@laXmmkUK@UmKULUUmWUL@VakU@Ub@b¼VUKWb@bUbn¼@mJUakbWx@@VXnlJUb@x@X@JUnVVUVmkUJ@XbV`k@VXU`LUK@_mKUbm@@b@U`@nlV@bUnbVbn@@`VbUbVV¯bm@@mJXb@bVnUllVXUlbUl@LU¦VVmkLVb@bl@V@XlK@V@nUJUz°mwmLmlXbWVU@UUUlIU@VVmV@@¦bXbWxXWlXVWL@LUmkbU@@LVVVJUblzna@WVn@@lIUVnbV@Vlbkbm@ULUKV°UL@"],"encodeOffsets":[[112973,24863]]}},{"type":"Feature","id":"4511","properties":{"name":"贺州市","cp":[111.3135,24.4006],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@nL@xn@lKVkwn@alLlaXV@lxbVWV@aUa@aUk@mVUnVlXL@JV@VxVIVX@b@bl@@`ÇnXVlI@lxUnlVVLkllV@nmJUxnzWJ@VXLlLVxnL@lLlVI@V@lUnl¤UzK@Vl@LlLnb@VnVVU@kaKnxn@VkVJ@ÅUlakmWIUaVanm@_UK@UVWUa@klXamU@VmVIXW@lUVknVlKVLXVXW@b@VlnnVL@KXLKn@lb@UnW°@VaXWVb°aVa@I¯aUkUaVKVwaXk@aa@wkm@alanUVw@alK@Umkw@UaUmU@WXUaUK@UW@UaVWI@¥Xa@w@WWVXwU@mKUXUWVU@a¯kl@akU@UULmK¯VUVW@U_m`U@@xVbUz@lUbUlXU`WLk@m²Wb@@xU_mXmmamLkUkKVkUVÑ¥mIXa¯KbmLkK@V@Lm¯@¯kKm¥kIWaUKk@@aVUUa@UwVUKVX_WaU@@bUJUa@mbnn@lULmKUnU@@JxUbUbU@mX¯@V@bnJÇz@VUVVbVxUnUbW@kzVUlUbVbUL@lWb"],"encodeOffsets":[[113220,24947]]}},{"type":"Feature","id":"4507","properties":{"name":"钦州市","cp":[109.0283,22.0935],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@@IlVVlnL@xlaal@nVLlx@x@bXnV@@`mXX`lbnaVL@blV@bwnxI@xXJ°nKl@lbnKnblUVanKVb@lUnJVIVUb@VU@mL@Ul@XwllVVXV@lVnlVnl@XVlK@@_VWVxX@lbUnV@@JlbnIlmnVV@UwVK@U@k°a@mnIVVVK@nXLÆaVWXVK@_W@Umw@UXWWkUUVWUIVaUkJUVWbUmU@mkUJUU@UVab±aVaUIUmVKUaVUU@VUUaUUU@W¯XWWww@k@Kl@wkV@U@alK@aX@@UmIUWUI@mmkXU`U_WJUnUJmUk@@amLU@UVW@UkU@@VbUWVUk@@wmKkUWLUWX@JmIlUkkKWKkLWU@UKWa@bU@@a@_UKWUUUmJmw@nV_@ġğKóLmbU¼VÆ@xUX@Um@wklVnUnlkaUV@lV²WVklWXXbWlkVkIm`UULUU@UWx@XU@@lWLU@kbUbV`UXllUV@bmb@LnKVbULmnVVIV`X@"],"encodeOffsets":[[110881,22742]]}},{"type":"Feature","id":"4508","properties":{"name":"贵港市","cp":[109.9402,23.3459],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@n@VzUJnVK@XV°nVVnwVb@xVVknJlVVUbnWL@bUxVVXbl@lVXkWXwWaa@¥@nUUUV@JVkVVV@XUWanknKxn¯VyVI@m@UkL@W@Uk@aUalKnUUV¥@KVkkaWVkUVkUm@aWanI@n@°aUUVaUa@_m@UamaV@akU@mV_@a@KWIkmLUKaUVU@kVUK@wUIWVUaVwka@Uka@aV@@aUKVkK@X@VbKU@JULVLkVWUL@aUKb@VUL@LxUKmlkImJk_@WU@kmK@UV@¥XIm@@Wn_@KmVm@@I@aUmkXm@UWV@mn_@mUUJWIUWV_WwU@mUknVVmxU@@VUV@zU@UVW@K@X@VLUVKz@J@VnX@`±bUXV¼ln@xmxÝL@Ubn°@XWVUxUVVnkbWVXV@X`ÆÈKnlLVanIV`nLVUl²V@V¦l°¦wb@nKnLVbVJIVXK@bn@ènx@xVbUnV"],"encodeOffsets":[[112568,24255]]}},{"type":"Feature","id":"4506","properties":{"name":"防城港市","cp":[108.0505,21.9287],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@XV@X°°UlxkbVlVb@nkbVl@xl@@b@nXbVL@Vl@UbV@@JVLXbmV@bVVUXUJU²WXlKVb@VVXKlXWlXXWV@VXJlI@xl@nlbn@lln@lbXalIVK@VwUVbU@aXylUX@@aW@U_UJmUnVKUamL@Kna@aVUkkVWU_ValaV@XK@kV@@WwVXV@VKVVn_lJlUXkWaXWlkXU±kU@VUlbkVmUmlk¯ÝW@mb@¦VxULmkJUU@ma¯wmkX@VóJ±bUVUXÝWklWXXlxUabIğÇ@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@IJVwUaVaUkWKn_mX¥WwXmLXalbU£UyVÅ@Ýwm@°lLÅUmkmwÛaƑLÝUUm@ȣÆV_Ó@£UUV¼U°W̄ÞVbXbôx@b@bmV@ÇUÝ@@ĢU`m@nxnIVVVXVL@`@bV@@aXbVL@XVlKXLlLVlknJ@IWVXXKlVnL@xl@UVVXa@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":[["@@@UnUlJnwJU°VL@bnVUwlJ@XXVlU@klVUJknlUllL@bUJ@xULUlUblVkblbnwUXmla@wV@VK@L@UXaVKVLXWUVa@U@Im@@W@£UKUakKWIXU@al@@llUnL@W@Un@@VlUV@VIUanKl@Xb@lmxVb@b°bb@nlJVVnnJ@b@LV@ln@LmV@Vx@blnVKnlJXIlwJ@Òb@nlK@Un@UL@VVVVUUUVKl@VUVLJ@UVUUw@Wm@UVÈVlbUb@JLlX@@xLmk@@nlx@bUJUzVJ@@LVxUV@bWxnLnVVK@_K²xVbV@n¥@aVI@b@l@VaKnb@n`nmmýW@U_wV@VlVV@Vn@n@nI@Jn@°¦VaUU@mVVWVaUÅU@aVKnVbVUmmU@a@kUwm@aUUmUUJ¯lakUaXaWUUaVkkamkmUnVlULVlJ@XU@UJWUUwk@aU@WbkWL@U@WU@@XUKmV@aUVwUĕUJUamUUVUÑmnIVJ@kl@XalJVn@KVL¥@UWIXWmU@mVUKnUWLUKUaWUUKVU@U@anUny@UlUkK@w@a@aVU»UkVw@WmkJÅmUUVmwXalLXWWUnam@XkJ@UVU@U@W@@U@I@Wl@Ènlw@KXLWblVUkalKUUVVaV@@wnIlaUmkUKWU@KkUkLWaKUUWUn@VK@LnnWJUIVkUWVnV@V@@XK@VUIUJ@IWJkX@VVJIVkK@I@UVaUWk@m@wnUWKk@mxk@@lV@bxmb@x@VUmLkUJ@nVV@b@VkLVbU`¯Il@U_UW@UU@K¯wm@xL¯¥kI@bkb@Ua@m@kkW@XVbmV@kV@bWbUbV@¦xXlmVk@¦bkaWL@KUImK@wUK@VUIb@bmK@LÅy@akXW@kbWlXblL@ULUb`@UkUymX¯@mUJUUJL@Lm@@WX@lUVlXll@l@Èk°V°X@VU@UVll@XUJVXUVm@@VXLWlnV@Xk@mVULnxV@@bmkL@VWLUbU@UVm@b@ķ¥UnmJ@UUVkkJUlÔU`UIW@°kLUlUI@WVIU@mWKkXk@WU@bXW@J@xX@l@LVl@xLVxXX@xKnxVknbKVV@ULWlXU`@nUlX@llVXVUKlkUKlI@anKVLXKVaUIVWV_VK@VnLlU»VKVLm"],["@@@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@bL@LV@UVlUI@aKULVb@bkJmxlLVxknVJkxnKmnnL@bn`WIXlWLU@UxVbUVmKVXI@JVIVJ@UL@W@@UmUXUlVUVJXImm@KL@UVmVXVLXblKlV@LXVLlVVnkbmJ@xnXl@bXa@VanaÒLmVnIlÞ¦°k@b@@lVnJlUnVX_@lVlKVUUxVLVWVIXJUlnnWlI@KUaUUVKn@VaVXV@na@mw¯@mUkJUamI@lk@@am@@IUmVImUUw@anUVaUU@LU@WaWUXWWwV@VwnU@L@ynbl@@X@aJ@nW@@Vn@lVLlxnIl@@UWKUnIlJXIVllIVV¼XK@aVIV@@bn@VKXLVKVVVInwJ@UWI@mX@WKnI@KmUUVJUL@VKW@@k@aU@@W@InJWUXwWI@W@¯wkaVaUIl@nValIXWWI@UUm@anwWkXWWIUbk@UJmIUamKVUUUVVama¯VkIVVUlKnXVwX@@WVaUUVa@IlaVmknawkUU@U@mUVUVwl°LVbnJVU¯la@mX@@UWKXU@aV_V@@JlkU¯@VnK@km¯kU@WUW@mmU@kmlU@wkL@WUkL@VmLJ@b@V@bknUUVK@UVKUK@Uk@Wa@LUVVnUbmVk@@UU@@aV¯K@U@UU@WmUL@aU@WVw@IxXll@UXK@KXXVJna@wWa£naUKVm@UU@mUmalm@@XkVm@U@VLmWU@kkWxU@@bVV@VkXVlV@UUk@@mI@KUwm@UmVUUwU@lwkV@IUa@mUaVIVKVa@w@U@UJkb@n@bmJ@XmlVUxWXkJmUkUUVWxUlU@aULUmbU@@WXkmL@xUV@nUxÇm@XLWbnlnVnnUVUnVVz@lbUVVlULVb@V@nUJkwm@Ux@bWbUK@UULkaJbUU@U@lUK@XUJmnJ@bU@UwWax@zkJWnUJUUVVV@bXn@xVb@JLm@Xw@`@bkb@VmXUV¯L@mW@@n@V@L@KIW@@aaUx¯@Um@XbW@@LV@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@kW@Xn@@KKVIVVIn°@nWVzl@V_VaVK@kKWaXklaX@lW@bÆz@KnL@aaVJ@UVL@xnLVJ@LXKlba¥l@nUWkw¥U@VaXa@amLkUKm¯kmkIUaKUIWkKm@anw@mlwXImUk¯@a@amU`kkKWVkxmUUak_mJmw@wmXUW¯X_@WnI@aVwkWWýÅU@WLkUaUbVV@lUVVnm@kUmV¯kKLwmVUUaWVaaWw¯wÈ@VULUVUUK@nWJkIl@Umxnbm@kbUJa¯bUbVxmLUVaU@VUUWxkVVV@bUV@XWbnlUbbUJlbUV¯b@z`WbXnmbawUwVWUbUxmbU@Uam@VkVawVaUWI@mUKóz@lUlÅ@WIb@xXxml@XklULWKUmwUa¯KUXWJkaULmKkLWbkKUVImWa@kUaULW¯LK¯@kbL@bx@J@bmnnlUlzU`U@@Ub@mn¦°bUVx@bkVm¼mx@mkmVV@bkxVnaVV@bU@mL@b²`lIVV@lXLlbVxn@@bl@XllIVnbVn°°wlbXw@mVa°lVnU@mVLVbn@@b@@WVnUV@Xlxn`VznJVb@L@bV`V@UnwU@WUXKV@UUlmUUlaXalLmbIVbnJVIlVVaUUnWVXnVLk@nWnblnlb²xxVKVXlVXLVWLlUVJna@wVL¼@JVX@`@nnx@nWJU@Vx@XXKUblxU°LVKVVlL@KnbVUnJIlUnKl£VWxIlJ@nVÞUVVnbVX@V_°lnK","@@@UmWUwkU@Um@@VkL@V@VVkV@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@@KUaVIVVLlaVbVWnX@@LnUlxl@naVLXVVaVUJ@lUUanWWI@VlV@Xbb@Vn@VmVVbk@kU@VV@XJ@zn`ULW@kK@_WVUK@LUb@Jlxn@nnWlU@@bx@XVVU@UbVb@n`VI@VVLUlUIUV@KmL@VV@XIV@@lVLVmXV@WLXLW@U`nkb@Vl@UL@VVVLllX@`lIXbJIXWLaVL@XXWĢb@bmK@L@°@VnxmxnK@xVn@VkL@VLakbl`VnnxVnUlV@@VVXV`@k°JV_UalK@U@aUU@mIlVnKV@U@wnaw@akU@l@nwl@XLmV@xnl@VXUb@V@JlLUJUI@UlWUnLVUUaVwV@XKWkXJm_@amKnmmLwlUIlmUwkKnwlI@aUaVKL@bVJkVUU@@KK@a@I@ama@UUaV»XIVa@alU@WUU¯IWVUbkVUKWLUwUJ@zmWm@@amVUaUIU`VbULmU@KU@@UmJ@kÅb@akUVylLXUmU@aU@KX@Wan@V°@Vwb@bX@J@LK@@U@mX@@n°KVUnW@Ula@a@_x@WnK@IUa@wWm@aUUUVVVIXmlI@ywXbVxV@@aInmVI@WVL@k@VVVaIlbVK@VVLXa@aVwn@lxVI@m@UUaVKUkVUka@UymUVVUmmUmmkXaWK@ÈnVw@mVU@wKlnXW@V@naVVKUk@KVIUW@mk@KXU@Um@@lVk@UVJna@UWaL@a@Xa@kmmVUUk@mkkamJImJUUmIm±aUUkambkamVUU@VlbUbVVxXWVUU@VUakU@UmUVU@mnUVVnUbVJ@bUW¥kLVamVkUaWJU_UVWKk@@nlUVVJUXm@Vm@UnVlmbnmJUbULU@@UUKWVIWxnJVb@xUL@bUJWIkxbkb@xVJbmU@kW±LkKUkVa@a¯am¥ULkalÑlKXUWXaVakImV@ka@UUJ¯aXmmbKWU@wUUaUaKmU@UXlWb¼WLUKUb°UlVbkbVL@VJ@nVlUbUXmJ@VX@lbUbU@@bWb@VnLVJ@bVVUzVL@lnL@bVVVULmKUkJkbm@xVb@VkKVnnV@b@WXUnVlVVXVJUXlVXbWV@VU@Ubk@@KWbUUmL@JnXV°XJ@_`UbkXVVlÆkb@VLXVV@V@kKXX@`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@aVKnVVVUlyX¹lWVa@UVnUVU@m@mUl@mÞw@xnIVbna@KVIJ@kwV¥UXÇVkVW@kkKWU@aXUWmnIVa°VXbmL@VVbnVVVUbVbJVbVKXkVKVanU@aWnWUWa@Unk@mVIVK@wXxlLXbVJVlKbl@VI@maXalVVVbX@@aalnkx@b@Vb@Vnx@bVVUXn¤WXn@Vl@Vlzn@`@I@KUU@V£namVkXa@aVKnnU@anVlKa@UUU@amk@»kU¯@aVWnkWmkImU@akaVm@»VUV@UKnkW¯XWlkUKnIWa@nmlIXmWUnwUwWm@wULmaUJkIUaaWaklwkwmJmU@bkJ@XUJ¯W@XbWbUKUkWJUUVKnn@UmmXUWa@mU@@UI@WmXVykwm@kaULWwU@¯lKUUVU@mU@UkmaUbmV@bxVnVUJVn@Jn@@bl@@knJVblInV°@nx@mbU@UWUbm@ULVVVb@LkJmXkmVWIUJUXUKVwVUkLkU@W`UmkVmIU@k@@a¯lÝ¥kmJUnKÑmbUb@Wbak@mWU@UbUVVkLlbUVkXaWK@LkxÇmk@@X@J@V@@X@VUV@VIWln@mbXVWXkKWbnxVUnVÆInl@XUxVl¼UV@b@b@xlLkV@VmzmV@b@VUVVLXVVbVLXKmVVLU@nnVWXXJ@V¦UK@LUmkIWbk@@lUImJnVÒVUnVVbVIVĖUxV@bnUVL@WV@@X@VKlXXaV@@blVxXVVIV@@WkIUVKUkVmlnnbllUVbXVWbblVkb°VInVVV@bnVx@l@bnVVnUUamUL@bVVÆUbUXUn@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@XlKVVnUVlL@baVbb@xX°ÔUxV@kbm@VxkxWJV¦@ÈnVKxWXJmV@nÒ@xVbn@@blLk`VX@bla²JVUlnn@U±lw@wnw@mlwVIX@@m@klKnkaKnwmmXkÆVmU¥l@nb°n@aVwVmVIVnI@a¯@mU°l@@VnI@JV@UV@b@IUbVJmXöºzllUbVa@aXUl@U@llLnKVaUa@UmK@UwVbnKV@VwVK@UXV@Vbn@w@UWnX@a@mI@UUKlaUaVk¯VaVLXK»XaWk¯mkğwmW@mIVkwJUIÇVwUUkVKkm@UkmU@WÅwm£Vm¤¯IkJWa_lUbmJzÝJkUÇVU@bUÝnm¯LUb@`mL@VkL@VUmmk@UU±Umka@kU@ķymUkk@mmkÝmUaUakImV@V@VÅL¦JUXmJXWb@n°Æx¼nV@LlbUUbmL¯@Þ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@nXJVUbxbUlU@nVbV@naVwaVUXVxxbnaWmXa_@y°aVUkaVIaVamkXa@WVU@aUUlUXwVV@UVbVUnKUwVa°abVIlan@manw@VklJXI@mLVVVUVK@UÇk@KUa@UkaVU@UVWV_XWVXVWlLXKlLXaÆKwVL@akKm@Uw@@XUVk@VUI@wWK@aUVI@UkK@mLW@kImJUÅVmkXUW@UJkx@nmx@xkxV²m@kmUV±Ikb@aUWl_kK@am@Ua@wÑ@mnUWIXwULm@ÇU¥XIlwUwn@laU@Vw¯ÓW@waUab@akKUmVUUkL@WmXUaUV@lWX@Jk@@UUKULmLUJmzkKmVX°VUnWKULL@mU@UnVJ@b@UV@X`m_@l@@bmbXJmnn@°wnn@VLX@V@nVl@nk@@bl@nn°WlXzW`XXVKnUlxVbUb@VXb@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@bUKxÅLWbkKWLkKUXUWWXU`UX@VUVlb@VVb@Ll°xXxbbXUVbVnUxKlL°nUlVn@UmVU@kUUVablVXKV@ÆXþlXUxnU@mVK@_@ml@UU@blU@KnLVyUw@@UmkWVw@UVK@VXzVK@nVVUUW@kVJnla@nKWkaWL@Uõb@JU@mU@@_WWL@lUU@WUUK@lakÅUUlWVa_@`WIU¯mW@InKVVXa@Ll@VaV@@UXUWakUVWUIUWUkUmVXW@@amUUmLl@UUawn@laIVlnLVKUUU@amK@kUKVyUU@aUImK@UXa@aV@VakaW@@UnIVWVaUkb@mWX@Vxm@UaU@W@VULUxU@mLaUx@VnL@VVbUbmLkK@kVk@WV@bUbVakkyõ¹nWUIVa@J@aVUU@@ImJ@Uk@¯V@n°@bmJUUJUnUxbm@¯mak@¦VUnÅWlnnmxLbmlkL@l@nWVnlÆUVnIlJ@XnK@lL@VJVU@bXL@xVJUl@VU@W@Vxn@"],"encodeOffsets":[[108237,26792]]}},{"type":"Feature","id":"5201","properties":{"name":"贵阳市","cp":[106.6992,26.7682],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@nlLXVJLVblJn°lnLlVnKlU@nUUa@WlX@ln@Vb@la@alJ°¦Kwn@°xLVkUmmwUmk_labK@UlK@UUm@wLmnwmw@U@¯@KnL@aaġXWW@UKbKWXJIWakJ@_kWkKUU@UVKk@@UlamV_X@WKXK@WUUnUK@kU@WJU@@UnK@LVUVJVkUK@UUJm_@UaVaV@UU@Ww@aV@Xkmmm@kw@IVa@KVLXU@`lLX@VKm_@yI@WU@UlVl@UanU@Um@UaWaU@Uk@XJmXVbkV@IUVUbWUUKmbk@kwmV@K@mWUXUakbKUUUJVb@LU@@VkL@VXKlbXmL@kbmUI@lVXUVU@mULWy@UUL@VUxXnl@V@VxUzmK@LkVa@VVk@@n@`UL@nmV@bmJ@X`WX°WVn@xnxnIl`VbnVlwXUlLl_nV@b@bl°VnWJkx@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[FMbECZS@KKS[FDWsCeRuU_DUQNOE[LKGUBM¨EDQP@HWHGDImXCog_~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ìwGF~Z^Ab[¹ZYöpFº lN®D´INQQk]U[GSU©S_c}aoSiA£cÅ¡©EiQeUqWoESKSSOmwćõ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^JOHLh@NNBnHP`\\xH@NBRLJTlNv_^CTLd@bNDVFbxdFVUPBTKOGEOUO@OEBXQP[H_EI\\EbeYa@UO_JMEJ_IEDKJUGMDcNUd_FMTEJSGoZ]EIYGO[YWgEQ]a@WHEDQKUSDUGAbYBUpSCYNiWqOSQEoF[UcQISWWNMSDe_cLQ_UBiKQOOASQAWgSā]ZaSPÝ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`TCNXMTXRJVdE\\FpTRrPjXZMTDVoZABaVHTCLVCRGF@X^bFRhZXP\\ZHHMA[^wBWXJlW¤EJ[bCTOFWWMm@ILMGWQ@DQ^QNWFSHEbF`OXNbOVNKTEPDTLTCCVTREfvfEHNbRAENH^RJXCFHNFRpVGHWISDOTMVCZeGamaLoLÛD¹¹ėgsia{OųETtlÉwr}jR±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":["@@bRFnHNbHgN@NPEnbXP@bND`NT\\@\\QZb@`@J]V@XhDpWnCJGHGXO@CR§FANHVKLF\\MPVR`CvVfQtDPKpGHG@S`WJP~^dSTHWX\\RHTFACQTIAUPOU@MG__IaYSFQKNSbORHXCZeTFJgB`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":["@@ºxJYZQIYXLl@dR\\WZEn]bA\\S~F`KXaDeTiNO^EEKWEDQXITBXaWaDQMUJOIaTWf@NJV@dSxGZFu_@WMKAU}AQ@MwG_[GOAmMMg@GKP]IUcaFKG[JSCoLGMqGEOYIMSWMSBucIeYA_HUKGFBLOFGPQBcMOF_@KO©UAtERadwZQ\\@ÊJÒgòUĪRlR°KĮVLJ"],"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¤@[ïKLÑIÏ]ÇE±I{uYś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@LYTDaFENF\\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`eJ`}@W^U@I@_Ya[R[@MSC_aMO@aWFmMOM@haGGMEmaQ[@MESHaIQJQ
MckBIw[AOSKKAMPSDSLOAV_@@`KJRbKRDfMdHZERgAWVsDMTUHqOUr@VQXTT@TfgL^NH\\@heTCZaESNObHPHeZF\\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[fYGGOPaTMbFDYfS@g[MGK]he@SSSRW@UVqrPVGNStCXUhBFQGYNcCeLQQaLI@_`@EUwcEaCUaMc@SK]Du`MSkKI~BVNL@X`EvYwHcTU@MIe@SXJbIPNVCRXbWbSAWJCRXFFL]FMPSjCfWb_L}E[TaBm^YF[XcQk@WKZJYRIZw¹ "],"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ǯ@aKmaeWuCº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\\CSFQK[LqDMACiUa@[QiFBRIHYCHkGSBS[oSOqBIE^QHCRWHIXsHU\\UC}JEjMNAN_ZAIhSEYfWDQGaPMTLERZTJb``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]EYyMKoO_QEIIKiNSMa[LqOKOaVMWMGMDY\\_IKrL\\ERT[DEPYOUA@nNTUHINkRBVMdNvGTxzRF^U`BD\\@tfNDNOJ@Z{TeTJZ@VUcB[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\\GZYHTPBHRCPTdH\\K\\@HXiBJILJJAVNTOZJNtFPC`YxDPWci@IBgbGKaTOIM@KNKrP@_hE@QbgKWUMJoWAQMFEKM@wTONCJWRCZDHSAM_UD_GWMKeCITSCGIQBGXUHQoMEEGWDQIG]FMQBMaFGueFeSQDUSDSKOCSFMLUaPWM_PaEGFETMX]RCRR@HXKN@JNnXXESPaDI\\£FkXWIAX]xB\\GN"],"encodeOffsets":[[112031,19071]]}},{"type":"Feature","id":"469001","properties":{"name":"五指山市","cp":[109.5282,18.8299],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@TCNOLBTLBPx\\AJdlNRRIbJTGNF\\@RcIYbmHoLQdKN_fCJYbDRRXKZFVEZVXBXIJBXMdESW[CUYHUVQFQAqsEIMPYMSBUIIJKAIjGW[@[LGScDOGQOAGSYZ[HSd[HFNVD@XmJFG[OWiWKNqGKN_MAMO[HoM[BoRewo@Y^HpITSFENc`MVCdHNIVCLJFI`NFIP`@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ÈÞ@kxnX°VÈa°V@kôwbJVkXlVUx@lL@xkVV°VbxlVUnVxk@KkVbIl@°kVl@lÆnkll@@VVX@V²bUlVlVUVÇn@nkJlkVb@x²V@n°VUnlKUn`@n°bWLnVUblVUVVbknV`°kkl@@V°@nzJ@XxlWXb°n@bĠlbXbbVbJ@Vba@@lbUbVmn@lVmnIW@WbÞ@n@x°@ĢaƐéϚnlČ¯ĠŻÈwm@ôçUmm£Xy°UV@wÈ£Ǫ¯kõÝçUÑUķĢkVÑÆÞU°nŎ¥ČUĊx°m°¦żVƐx°Ç£@yUônÞÆ@Èĉ°Kô¦WkWUbÇ»@ÈĕWÇÈ£ŤU@n£ÆUUKVamanwÅmÝJ¯k@JIkaVaUUÇbkaÆÑkWmÝUÛÝ@wnU±@kkV¯KUkJ¼U¦Å@ówķaķůV¥Uaó@Åwm_kVwĉĉmmn_V»a@UVwķóU¦LǫéóXÇmōLǓÇķxÝkĉkmakbUĶ°@W¼@bÈÆ@ĖLl@°J¯mkl¯LݱLamJ@¼VƧUóUXċb¯ńVbkÆÝI@llxk°V²V@UxÞL@b@b`Çzkókݤ@ğ¯WLĉÇLmmnċVkbUaL@¯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¯@@wmÝ@XV@Ill@bUxl¯VlVbV@ULVlUV_kxVVVÈÝJ@¯Ulm¯x@xóÒĉ¼m¯Wxţ@Uz¯WwnUwť@knW£óVUUwğyó¦WIVmmI@±kwÇ@@b@ĉ¼ó@¯wó@¯aó¼KÅaUwmWUwÅI@aKó@UaLaVÅwō¼UUÝl±I¤VxÇx@zkJmnnmbnzxll¯ČkJl°@kbmx@x@kêmVnWxôXxU°bWLóJnÇWĵV¦UUbbÆġKk¯VU±aXmċÑUwĉKġkVxkÇKkbIÛXWl¯bX¯KbĊÞVÆnĸ²lxU°n°òÈb¦xVb@¯Vx@¯VķÞČlĊ°KĸȘI°¤ČIôò»ƨnȰKǬ¦ôWŎÈƨwlnKVXmbX`lbwkVWXXL°aƾaĊ£n°@°¥ŎzÞ¥»alwôkƒJa@Ķ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@alUwwĢřk@wÆWXUWXWam@_ƒ»ÇéXaĸwVa@ÝKkUWkXkKXxn@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¦°JUnLôlnŤ@@ÈaUÒVbkbl¤zk°ÇVÛô°IlVUVôUxÆU@bźĀº@¦b@l²UVl@°ÒĠxnXxÆVô¼Þ@Üx²KÞlVÑ°UȰôlwô@²ĸ°lanV@VŎUll@bÈnÜmwĢ@la@ÝÞb°UXblŎ²ÆkVI@nJnĠ°knÜbĢwna@akÞKƒĀaIVbU¥wĠwkôxnLċVçkaU±IUmnġW°WôĉalÞÅĵ¯@W¹XÝab¯a±X¯ºLaVmkLóbkaVUKVkkKV_@aÝykk±L@ÅU@yV_aU¥ówÇx@UkVn@lkÅlwWVwUkĉmkklW@abVwnWWwWL@UUÇLÇm@wJĉL¥@Ý_@a¯yUWw¯¯Uġx¯aÝXVmaU£ó±¯nwa¯óÅVXmanUlUXkWa@mkIğamIklÇUkĊzkKlUōĬl@nX°@llUxŹ²mKĉVWwk@UbUK@bmVmIVmwaWxXlWČmºÞÆbUxV@ĵńWÆĉLkWUbaWzkbĉ`U±LklōwUVÝ£UW`Uwk@mk¯VkaõVX@WbLK@XƧºWzxK@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ČUmnnKĊÈKX°Ġ@Þ£ôllÈy_@a@aKÝVwU@±¯Ulkw@kÞJlÅUa°ŃČaWVôƨVU@»nIb²KÞ°Klkn°¯I@kK@ĕÇÅ@aX»¯@VĵlaÿVamI@aÅÝउýĊȗJôȁÅkmƑÛ@kxġ@@laVk¯»īŹak¥Å¯JUaWU@@wa»KUkÆkUmUmwÛ±±UUbUUXwWwÆÝklkUanaWwnKlkal¯kaƽakÅxa¯@amb¯VlÇwÛĀV@xmêVÆVVaôVwÈx@ˌx¦VÞ¯VlmX@L@¯Ua¯LmV@°XċKV@UÈ@¥@wġIUkm¥Źw¦¯lmn@°kxVV@¦óamn¦l@nxlĉVómxnÒĉĀĊ¼þǔêÞ°ˌĠÞÒ°ĀɲĀƨźˤȤƨĊ°w@£nymwnkUUV¥ôÑVmkÆmUUVamVIkmôlxkXÞþbll@kVƆVxV@¼VÒ@UnnÞJ"],"encodeOffsets":[[127744,50102]]}},{"type":"Feature","id":"2310","properties":{"name":"牡丹江市","cp":[129.7815,44.7089],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@U`lLUlVLUlbaôlKnUbK°¹²W°baÞbknyUlUkamř²L@m°@lm²n`ôÅlKxÜKnxV@l@ÅXyW_k@wmŹĕmX»Ûl°ôÈ»ôô_WW@Ual»wU@@wUV@VXI@wĢ͑ÞȻaU_@mUkly@¯óV»XmWUXUWmnm¥nUUaWLk»Æ²IÇawÅaÝ°¯nUa±a@¦õÆğ@@ÅbxUÜnÇłlb¯¦ôó»m@±Uk@Wwa¯xUV°xXbÇÅUVK@¹KUaȯ@ōÝXallÛkalÇUǫÇÅÇakbÝƆ¯nl¯@¼VUx@x¯W¼Æ¯mĖĬ¯ČVkķÅmx°ô²V¤bUnÞW°bĢw°V°XxV°z@bÞ`@¦KĊI@xnÈÈKV@VXKxXmXUxab@kXllĊnVlUxXkxlÆkm@UVl@È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@VbU¼m`nnĊĊxlUmkaVÿLw@°»UmbKmÝUwUmVknKUUl¯KUUÈnK@ĠkX±lX°L@¯¥@wV_mĵ¯WwL¯UkōÇVUlwVó±¯aVka°wVk°mÞ¯ŦřÆl²ŎkU@mUkb¯ķ±ó@kxȯó¯VUÒkݱLÛwÝ@ó»ÅUWwmğw¯Ñ@UkV±@ka@¥¹Źÿ@aÅVwóVVUkU¯JÜóÈUl¯yk£laUaVÑÇb@ţ@kmómKV¯IU¥@@kVI`@ô¼blUlbÈb@xÇKkĢɳaÅɆō@VK@z@@¥ÆKnÜ@@aÛUwwnUķ@_V°@klVnULVVÞbVl@°@nxn°LÅÆlVÈmU²@VmĠLxn¯xkWzJwnLmbXbW°Æ²@x@JVxLĀ²Æ°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ÇVVLk°VVmLUlVnxVnÞLnaV¯¼@xKUĀlbn`nÆxô@VbU¦ĸŰĸbôxÆ@V¥»IVl°LUll@²mVx@ÞÜÞVnlXÅÒlbÈaVVUblbJ@I°lÞInÆmxnbUbVLÅVm¤@ţVǤXÈÇĖ@ȼaXVÜaXbWnzŎařKôbUlw@¯naÆKnUU¯Üa@mkkVUĊmżÝǖK°L²lÆI@¯¥ĉƛVaÞk@ÝVaĠlnUVwóma@wĉ@aVxamX@a@UaÅLaVW_nWm£nWm_ÅV¯m@mó¤Ý¦¯ÅalmX£VWUÅwmÇ@@IVWUw@aI@k@wŎ»WÅVaKIka@¥lUkUlwÅwVyÈwWU@a¯U°mÇ@UçaVa¯mV»ÅwÝUlUkV@kmUkX£w°@@ÇaÝIamÛam¯lğmmI@JUl±ÅōkWa¯VÝa@Þkbġ@xÛnÇm@akkōVōl±kÅťŚÝ°¯nUl¯xlbU°b²ôUxkVÈUŎVl°KXxĶ°nU`@x°¦@"],"encodeOffsets":[[131637,48556]]}},{"type":"Feature","id":"2308","properties":{"name":"佳木斯市","cp":[133.0005,47.5763],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@nbÞJb@ȯ@xW¤Vln@lUVlkÞVÆxU¼°nUbbVèÈ@nIn@ĢmlUw°żVUn@lnL@VôbwĊlJķĸĢlwôwƨxVVUŦxLźÈ°`nnĠwŎJÞĶwôJ@¤XnÜĸln°¼È°lUbx@l@ÞÞÈm°lôwL°¼ĸ°Þ²nĠ@ôwÞ`ŤIVÒĠU@VJĸbƲ@°ĊKJĶaĢȰ@ô¥°n¤bČU@VxmUw@aÝţÇķ@ĕķīU¯²@ÆmVÑô¯X¥ċç@ĉ»U¥ÝţKWVÅkUVÝŎUmÇÝx¯aķxÛUóL¯a±óōb¯ÑÅVÿ_Åķa@UK@wm@Van@UmmLVa@VImmXUWÝUÅKUwÝUUkVk@l¯XÅ_J¯kJmÅLa@¥U@¯Vz¯@`@¼mxƥŏKÛk@±laÛ@@Xm@@xƽ@WŎnˣĕÅ@@aÅ@@nÝbǯ@_UkUWkbwÝU@çWlw@anI¯lyX°m°VaÛm@mVwÞK°XlaXmm_@UkwÝK@VIXmV»I@a¯ğWbġaU_¯JU¯ġĉkō`±nÝÆkbóĊ¯XĢXmVn²JVlbUèČmKwlóğxxV¦UaJbƑÿÝLl@bmbġx"],"encodeOffsets":[[132615,47740]]}},{"type":"Feature","id":"2303","properties":{"name":"鸡西市","cp":[132.7917,45.7361],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@LKVVnkbVÈb²U°VnklVlaÈL@anU°ÜmXV`nôLèxlLXL²aVVmÈX@ķlnUÈl`ȹ@Ť°U@xKnnVmlnnUllVnnaŎwlVÞÒ@n¦LV°lwVkLaÞlnÒ@xmLÞ¤Wn¼WÈLVVUxlÈôWVaU_VKKXUÆbnnôKbÞw°bÆWXamVwKUw¯WUkUlJUwVUa@@kmyzmĉw@kVwkW¯ÅKU_VmxU@aW@@kK@wa@K@@kVUaky°_Vmkna¯K@Lwġk@@IÇóXwVakmV@mwXUWanlĉ@ÇUwKóܛNJÛm°@wÅ@±b¯W¹WVwŹĕ¯kVmōb¯w@awmVUUbVIkaVwķxk¼b@VXXó`ó¼Çó¯kܼWnźĖnxl@X`WzÆ"],"encodeOffsets":[[133921,46716]]}},{"type":"Feature","id":"2305","properties":{"name":"双鸭山市","cp":[133.5938,46.7523],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@UUwómÑÞÑUÝÝUkmmÅyV¯ī¥Uÿĉ¯mÇkaWbÅX¯aÝxaóLmmÅaWVLULV`UbXókÇVwUUÇKX»XmÝ£nK@wmÑkÝbKUlx¯kUKm¥@ÝÑkUōxmbUmkVkmmnkUmmL@w¯Vţ@Ǻk_ÇmVk@ĸVxVÈ°lLkllUbōwnVW¼nlUx¯XmWUnÝ@xÝUó¼¯J@LVbkJWnkbW¯ÝLUxn@nÜb¯U¯nWkz°mJ@bkxX@èÞVxlaXlVV`°@ÈÞa@mÆ@@bÆ@ˤĖmXōƾ@@wn@@WÜ@kb@²ÜlŐLƦnw@»_°@y°UV@@¦bÆKnI°lIÆ`°W@kllUVÞVVxLÆÞVXWVnnUJ@UbnKVnm@Ubn@@xL@VbÆĸ`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±ÅÿKUwI@w@±ÅX¯WanamKxIylX°wmwğKUn±@nVÇUÅkƯKmmw@@¯UkÝaUUVKmUlk@¯U`ĸ@VmxVxÜ@bÛ@mÅL@¦@@yLUŎ@ÆɅɴblġÈL@wÇaakkVa»@ó¯_ÝJwÇaÅXnyU¯¥Å@wbÝaLmm@@VUlbğVm¯Xm_`¯_UxmLa¯b@maó¦Çk¤V@bóJknVxVXx±aLUbVxkLVlLWl@nX@VÅbWlÈnxbWÅbm@xbml°bXbWXVmnn`Lmnbmb@k@mwU@@¯Jlbk°lbkmLXxmbVbkllÅÞxXxVWVVa²VܲnxVVnÅlVlL¼b@xV@XVbIÆ°¦lźbĬ°¼Ulb@kĢ@lw@ƒÜlnȂÆóȘIĉ"],"encodeOffsets":[[128352,48421]]}},{"type":"Feature","id":"2304","properties":{"name":"鹤岗市","cp":[130.4407,47.7081],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@Þ¥ô£nn@°ÆUn`mXn¤mX`UXbÆKVb@@bnWbwUbĊ@x@nbWVm_mm@ó»UmÅWXkĠ»²¯¯nķwŎ@ĊŎK°bĸUnÑKȦĠÈbÆknJÆUĢV°IVƾwaVkǯ¯»mķkÛWm@£óIĵxÝōIğxmm¯_ÇŹKwťUVUƧwóxxġkĸķIkĉxóa@UmK@kVmUŻ¯Vxkġn@mmJ¯n°V@bXVÇxUzÆxkxlVkV@¦lbJLUbÆXō¼@xl@J@bVxXU@JÈ@nxVÆUXW¤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`ĢbaĠX°@bJU¼WnUJ@ÞLlxV@n`lIUa@K°Iô»ÞVwÞ@VmnX°WVwmkX»UmŎxVaklkkKǯUUwÇWUnU±bKWKkwçóKmU_nW¯ÛmV@bÇKkbkUml¯U±VÇaUamlUULKk@U@mwÛLwkLóÆm_±nk¯@@n±KnŚlbkVVmzlWXº@Ķ°"],"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":["@@lLnlmxnIVVlUnb@VVxXJWL@LÞVnnVJ_@wkmKbxwXkWXXKlb²K@nVVVbL@WlU²lKVnUJVz@VVb@lżmVUVnbôaVX@°Ub@lWbX@b@bVb°x@VxÈLVlaÆ@Þb²k°@lVU@Xn@VWLXb@¤VXKVVVLnm°_ƨ¤@aUIVaalkX°kV@alwUVyU@kó°na°UVUUmUÆw@mkLVUWVIWLnn@xlVnKmyU@U°UXaV@U¥U@UÆ@aVUkWU¯aU@WLUV@bkbmKULmKkUVUkmVIUwlWV²Uml°U@WLUwVm@UUK@_KUUÜaXw@VKUU@mVIUUlmnIVVVbÈVlKnbVK@nI@nVnwVLVKKVnb@aUIVW@In°@lVnI@lWĢ@°UVL@b@VyUUa@w@WUnU@WǯK@UkkJWaÛbmk@mVaÞU@amkW@mXUKkÿ£@akl@Um°UXwlaal@nmlXnW°znW@awV@akbĉ¥VmU@IVUJkUmWUKbmkUaKkUVU@KV@@klwWaU@kmXVènbmlUUKX¯JkbI@JmIUWU@Lml@XkJ@UkK@aVKwWaIWwmU@mU@J@UaċUaUUVkI±k@UU@UbVVm@UVKLlkIWaULUWXUJU@WbUb@lkXUxm@@JVn@J@bnb@Vkx@bLUÆnJaVXnKVVmzX°V@_lJXxWXK¯bÅamU@lUIbñJ@LÇKkIÇ`kxWL@@@bUVUb¯xWKkÅVlULW@n¦Ul@IlmUUUVm@kWnkKma¯XUKWmnwVwÝLmVUbUVWb@LnxmxVmbXx¦@nb@`V@kbLUmVUlkbVXkº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¹UWlaVknUVKla@U@_ma@¥WwnaUwnmw@KXaVUVaUnmWUk°lnUVUXWVwIWVóKUI@WXxUU@mma@kUKWLkw@yk@aVkUUċaUU@Wk@Unm@UVmLm±IUkJkW@aI@m@UVUla@VXVXmVwnkWKKU_k@m¥mX_JmnU@km@U@KmUVU@U@Umk@@LmW@Û£Wka@wk@aI@mmk@mUa@UmUIwW@aWUbU@kbÇ@kw@makVUkU@am@aU@mxkUbKUXU±KXVWLUK@wkU@V@WXUa@WbUxJI@¦VèVVX@±ê¯KUI`¯UULVx@V@UKIVkLmVkKm@nUJÝbkIUJVXVVxVbUVJUn°bVmlU°XnK@Ul@lVÈVUXx@W@VXVKÞbn@VnbVm`UxkW@UVkLKm¼@lUnUJVnVXV@Vm@@LVklIkl@VWlULWKUL@mJ@blbUVUlmzUJUxm@UUbċÜk@Ub@VLVV¦ôbVmUKUkU@m@VlVn¼WbUJ¯@@°nIllÈl@nXWlLkJ@bkxlxkxlXUlklJXL@bWn`@nÆXxlL@xl@XbLKlVlIXblVUbUJW@lX@VL@VVXJwn@WnL°KbVbl@VI@K@U@nmVmV@XUWI@aXm@VUUkWmn@lmUUk@mUmK@UnwVĉ@mU_V@XJôVVULVUn@llUnJl_n@ml@XlLlw²LVJUL@VmbVblVXmVnl@Ť¦nn@Ü@bl@@XV`Unb@VlLVb²JXn¥ÆÑ@¥Þ@"],"encodeOffsets":[[118868,42784]]}},{"type":"Feature","id":"1306","properties":{"name":"保定市","cp":[115.0488,39.0948],"childNum":23},"geometry":{"type":"Polygon","coordinates":["@@VbXW@@UlV@xVLXKWU²LVVWLalVnwV@@bn@bVVllUnb@lxÈ@laV@aXV@bXxJnV@VVb@nnl@nJ@bll@aU_VWUwVUkUmUkb±mVwU@VIUW@UWk@VU@ynLm@IV@bnKLVaVmnIlaXwV@@WVL°@@xnX@V`V@VbUVVLVKnwnL@ll@@_V@VVnaÆ@KVXÆ@n@wKmUWm@km@kÜKXU@ÑW±nIUwVKla@I°wU±kkmm¯m_JnawW@IVaUama@wUmU@mVw@aXk@mWa@£km@a_kVmUnWW@¯bkUmk@VÇm@@kUUKUU@UVUamVUaWIkb@xU@@amUkKVkam@@kVUkUWmKmUkLUb@xmJU@UImVÛVmnUwJU@VX@UWm@Ub°¦UmxklmX@`ULU@@UW@@xkn¯@makVUmxUb°lUbUbnUJUUVaLkbUUJUU@mUUUJka@xUIWJUnJ@Vz@kb@`@bln@lb@X@@@XlbnbVb@VJlInlbVw@UKl@lbnan@VbJôLnUzlV@lÈLVbVK@LVxVWXX`WxXzbV`UXV¤nx@bVlVnVlUL"],"encodeOffsets":[[117304,40512]]}},{"type":"Feature","id":"1302","properties":{"name":"唐山市","cp":[118.4766,39.6826],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@@VVl@²lJUVVbČVVb@@InV@VnXxJXbxUL@bLl@VlI@WnkKV@VXnJ@IJla°IWLVVnkmaUçWVkôaܯ@nV°wnJlaV@VUnUUaW¯wXWWwna@£UaWKU¯¯@aVUkKUamUUn»anIVwUWlk@LlWVakU@K_lbÞU°@y°n@KÈkWWţ¥ĉōkġWUw¯£¯Çwţw@kK@k¥ÝwÅbÇ¤ÛťVlW°@ĸx@VVVULVLkl@V@X`Ub@Xm@UWbk@ÆVbnLWV@lnXUbl@X¯lmUVkKWLkK@_UK@U@UmmUxmVXLWVULkU@`W@ULUK@XlJXzV@@xml@VU@UX@Kk@WbUK@Xn`XmJnmkxUVbUVlVVxUbV@nKlLkVKÞbVKXI°KVmVUIUKULVxVJVLkV@V@UbU@WUU@UbUK@b@nV@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@Vnl°aX@mXnVlU`@bln@¤Xb@nWl@bUx@nnVV@xnbVbUb@JXxbmXa@kUVwlWkKôVm@wkkK@kl»ÈmVKXkla°@XVV@VI@ml@@Vn@VX@V@J@VxUzVV²blVk¦@Ġ@@»@VK@VÈLlK@XnJ@alIUlaVVb@n@aU@WUIV@mUn@mKXml@lL@LnWb@XV@@aVVbV@VVIVWÈbIÈ»ƒǟlWaVUÅUUm@kVUWVkaUwmaóUJUU¯ÑU¥mk¯UaKÅnÇyóXmWÛX¯aċbÛaJWÝU¯»aóóUm@IVVl@bLUJWLX@@xXUxl¤V@VnVUVXVbV@@@VVn°V@ţU¯VUmUWV@mUXabUKUwUaÇKnVk¦Wb@VnLmV@bkV@nxW`Å_UVV@bUklVX@VmlUx@VVL@xVWVL@VW@UUm@"],"encodeOffsets":[[118485,39280]]}},{"type":"Feature","id":"1301","properties":{"name":"石家庄市","cp":[114.4995,38.1006],"childNum":19},"geometry":{"type":"Polygon","coordinates":["@@la@y@UImVXIVJw@lbIVVnV@VVIVVlaKbVUVVImVaaVk¯VanwVlUnb°@lm@wX@@VV@VK@_nWlknwV¯¥Van@VX@W@UVIVxnmÜUnUVJV@nI@wValKnV@kmU£na@mVk°KLVa@UU@UmknWWkXU@aWW@@km@UaU@@klK@UkaWaUnamm@Ua¯wWU@UkL@Un@xVlUXVJUbLmU@aUWUkmKkLUUm@mWXammkkWUm@@U¯JUUmkU¯@mKĉxÝwÝ¥LUómwkUUUWVkKmkKmLXlxVLVxXJ@nVJnz@VWL@`nX@x@kVUUmJmIXxJVnUV@UVV@LU`UXVVlXL@l@b@VmX@bxn°UbkKWLXlW@@bKmKULmakLUlmb@Xb@xmXU`Vb@`lLx@nWVXL@°WlXnlbKVKXVb@X@l_lJ@V@XnI"],"encodeOffsets":[[116562,39691]]}},{"type":"Feature","id":"1305","properties":{"name":"邢台市","cp":[114.8071,37.2821],"childNum":18},"geometry":{"type":"Polygon","coordinates":["@@nKlLnlLXUVVlVnxôVKÞ¦ÞxĊwnL°@lVnVV°I@Vn@VlXnlnbWnXn@VVlKnLVlVX@bnVKVaUIVWkU@wVm@¯@U¥VmU_°lKkw@LXVaU@wUUUKlUóW@UVUUl°KwlKU_naKVnlKkkWWa@IJVa@IlJnU@KVUUmVlaXUl@lm@kXWÝÑnk±k@wğ@@U@mKĉLmVJ@zmlnWLUÝJU_@@mJkXUVlbklÝ@Ýab¯@¯±JÅwġaUU@kU@mVI±bUKLWUXJkaLóKULWbUVkKmnk@@bmLUl@b@mnmJkUULabnmn@lVV@¦n@l@bznx@`Vz@bxnV@xllbnKVx"],"encodeOffsets":[[116764,38346]]}},{"type":"Feature","id":"1304","properties":{"name":"邯郸市","cp":[114.4775,36.535],"childNum":18},"geometry":{"type":"Polygon","coordinates":["@@bVKlVnInm@@akVnK@al@nmlLVUXaVKôLKlbIVWXKVL²aJnU@lV@VVĢbÆx²I°°@aÞbÞ@lkkaVUlWnI@@V`ÞIVXKmnk@yInUĊKÇkUUamUUk@aU@Uk@WUwVkVJVkkw°a@mK@UX@VVLVW@wwVa@¯Xm@@lUIWaU@UWkXWmU@UwmUkKmn@lkV²VaULUVmJUUUwLma@UmkIUmLmVmx@bLUamKÅL@VmbkU¯KÝamzkJUb±VkbL@lU@WIkJzkKmKnUalWkkKW@@nkbk@WW¯XUVUJ@XlJ@X@XlWLkU`VUnaWaUV@UVIaUxUUmVK@I@W@ÇU@@U@b@nmKXmx@UxkVWUX@`VLlL@`zXÝb@b@VUVkIUJVz°KVlnLlKnLxlLVVUVlXUJ@nnI@mVUlbn@@m@bVnV"],"encodeOffsets":[[116528,37885]]}},{"type":"Feature","id":"1303","properties":{"name":"秦皇岛市","cp":[119.2126,40.0232],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@lnV@Xbkx@lU@@LUVlVLVbnlaLXVVnlIVUJV@UnĊ¦lab@nJ°UmV@wn@VUJVI°bnWlXnWVLVK²bakklI@aUaVUwVUUalaVwnUVak¥X@WkLVÓmmUK@_lW@n_UK@alÅ@ğÅƑŃÝm@ÑţÇlL@¯mz¯@ÝVak`@LlVUbkXK@klVXUxJmbm¼VnVVblLUV@b°V°XLVb@¤mbXxWX°xXVbmVUVU@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°xb@VnnmbVXblb@VkL@lV@Vbn@@l@XX@bWVXlmXnlVV@@VUbK¯LUl@nmbV¤n@lLXnlVUV@ln@lbUlLnV@bV@@wlaXJVbnUVbVU@VVLVVn@VVX@@UKXUU@wUK@UwVnk@UUWlkV@aUVUÆ`X_w@mlU@anUmK@UXal¥UmÈLVbVxVLabVW@nXUVnV°UŤV@U¯Um@U@@UUaWVUmUUU@k£VwW@wW@XKIUa@wU@@al@UK@_mKXKbUU@aVKm@Xm±@kbÇakLğVaUw@a@mkUJk@ykw@£WX@lknk@WVkbUVnUVL@mVkI@JUbI@JXbXllkLUmLmbV`kLx¯LkVUV@VôXkVVLVV@xVUbW@KxlL¯kV`UnV¦°@"],"encodeOffsets":[[118024,38549]]}},{"type":"Feature","id":"1310","properties":{"name":"廊坊市","cp":[116.521,39.0509],"childNum":9},"geometry":{"type":"MultiPolygon","coordinates":[["@@laU@UnL@VWbklWxnIVVV@XJlbUlXVbn@@KmV@@X°WVInJmn²@lmVbnL@amKV_kwlmX@@LVamaXaaVU@UnJVanLlUkaW@UaVakK@IlKUU@an@ln@alKUkIVa@a@klaUKUV@UkUV¯KVV@kUmU@@a¯ImJUU@VV@UL@U@@WXUWa@Ukwm@X@@w@al@@aVIUmVUUUVWUknK@I@l¥kU±aUUVyUw@@I@UUWm@@Uk@@nUJU@WU¯@kbWlULnÇk¼@llLl@xUnóLlkXUxV@lWbI`°nnnllV²¯x@JkbLUVxmJX²@ÒWVÛL@lln@XnnVL"],["@@@kX@Valaa@KWI@UXW@WanaUIW@UaUKķk_W@UVUKU@b@UamxVXnJUbWVXLVbn@W°kb@U@Wó¼mIU¼k`V@bVbl@lX@lUôVlUIV`lXVn@lUlVn@l@UVaIUWl£UmVWU@@UUKlUUUnVL@KUnLVWUa@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@VVnmnLLXx@VLlKVUIXWÜ@Člbl@XUĊUlwnWLÞwm@ÞUVmnVl@nXJXLm@VnnJlaI@VkxVb@VlnJ@knKVn@°aVanal@XK°b@¯VJXIVK@al@nVk@nKab@XL@blVVKVLXK@VaVI°mVaX@V_@a@yUkVwVIVaJ°@anIlaV@nKnXÆm@wUUV±UUWUKnaWwXUWmůVam@kakImUK»lan@VXXaW@@UlUUa@a@UlwUV@Xal@@anIVaUK@VXmwVmUmVLXl@nalLnal@nKlkV@@UnJUXnl@nVl¦V@@VnJ@nUVVVVIn@VaJÆn@@K@mka@kmWVaUI@a@k@@aUL@mmaVIUKUV@@IU@mUmmL@K@UUUU@mW@@nU@ğ»mVmbk@klW@UXnV@LJmlUnUJUUUW@UnkKxmLa@@@lUUbmUVWk@@nkUmam@UakJU_Vm@ÅlÇLUVmVUwULKU@k@UVUlU@@U@UaUUWaÅzJaWLklb@bmL@kKabWUV_@mV@b¯JmXUbUK¤ÇLUU@b@JkLWmkUWIkJ@VmX@JUbVXU`¯VV¯blK@LXKlUV@Um@@Uk@kxWkbL@KkbmL@UXmaU@@l@x@blX@xUJ@bULUlULÇ@@VnU`W@@nÛ¼U@@VmKUkm@VVX@@xÇ@bUbVb@VX@@xLUb@l¼XLlbUlVVUUb@n"],"encodeOffsets":[[113671,34364]]}},{"type":"Feature","id":"4115","properties":{"name":"信阳市","cp":[114.8291,32.0197],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@VllInJlknJVkVU@mXlUÞ`VnVVU@U@y@nXlKVnJVkXKWaXIb@yVkVUkVwn@K@nW@kKlUXVVUlbnUV`n@V_V@llX@@Vb@bV@@nlVUb¯WLnbmb@nLnKbUbVWnLlaX@VVUX@Vln@`kL@ll@VXVJÈIVl@XÞJ°UnaLlylU@UXKlnn@lanLWWnbVI@KXKVL@LVWVL@UVKUIVWX@@XÆJ@In`@lJVI@aWÛnK@UlK@UU@VKnlmnXalUllLUbVVknJ@nV@Vm@al@@xnVlJVUU@w@ak@XW@_mWnUlŁUmVKV@VXwW»XWaUwnkWUkVUU@@@WlaUkkaIWVkm¯xmIUmLUVaUIó»m@mmwXk@amk¯¯l@wmkLmmU@UbkUWJ@XUbJ@b@l@znÆmK@Xk@Ub@lm@I@akmVKUUVUkU@U±JUbk@IWmkxa@UUVUWVkIUaW@UlLWn@VkJI@VkK@L@bmKkJmUUaUKWXk¼VxnJ@V@@VULV¼@@UkaUlWL@U@W@IkKmL@KULUWULWKUXUJmIbK²UWnWKUUkLUmUUam@UU@mUL@xkV@VV@bmV@Vk@mwkUVUx@mbXÇnVbUL¯WnUVLVb@xnlWnU@UVUVVUbVVlVkn@llVUXUWUXVbUJ@bmLUJnb@nVK@bl@@@bVJUbnX@lb"],"encodeOffsets":[[116551,33385]]}},{"type":"Feature","id":"4103","properties":{"name":"洛阳市","cp":[112.0605,34.3158],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@VVUllLXl@LWn@J@bKUVmnL@`VblLnbV@b@JmL@LnV@VV@¯VJVnXL@nm@aÞ@ak@mImVbXLynLk°@°aVJnUV@UVVXk@WJ@VXLlUnJVnn°U@»°Uwl@bWmUXÆ@VLXU@m@Ua@Imkba@naWW@_@WXUV@@U²@K@I±U@¥kKWLóLla@£Um@kWKXU@mlLXUVKUU±J¯_@`UL¯Wmk@WakklUnVUVaU@KUU@mmK@_a@KX@VaUIm±kaVKVUkw@kaW@kbkL±UUaK@UUKVak£@UmmL@lIkmU@Ualw@UJkbmIUmn@WKImWk@mUUnÝV@nÝxKmXkxĉVWVk@kaċÛ@WXJUV@zmVWnbUbVbLlUnlUÒnWVVWnk@@Vm@kxm@Unl@Ll@@V@XnkJVV@nlVXxU@ln@a@VLnWĊ¦nx@lbVKXLl@ÞVLXJl@XXl`lIXVl@XlXUVKwV@lanxzUbVJ@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Ü@VLm@n@na@Jm@k@lVVxXX@V`lLVXVV@VVÞLVV°²@labnxV@@bLmlm_VWnIWUna@lLbnV°VL@KVLVUVaVLXK@mÆXna@wVma@Xw@KlL@a@Va@wUkaWnIVla@Kn@Vn@VUl@nKVnJ@LnK@aVkVUUW@VakUVanI²XW@UUU°KnUVLl@XaVK@aU@KUI@W@_lm@KkLUKV_U@»@UVJ@XV@@mVL@K@U@Kk@VwUUm@kmWL@VkVkzKmb¯VÝI@WUkÇJUIUWk@@klK@_km@UVWUUW@kbmKUXaVamLmK@namaXK°VakU@mU@@aa@UW@kkU@U`m@U_mVkaUVWUkVL@lmX@Lm@UxVlUUl@zaWJXbWLUlmIUkLmW@@z@VUVUUmÝ_kVW@nUVUlmIklmIkJUkl@n@Lm@ÅIUbm@UJUUVU@mmI@UU@k¥mUk@WmVmI@VU@klmLk@mbkKmb@WkKUVnUnnxW@UVLUbmJ@bk@WbU@Vkx@V@bVbkV@V@XWbUWm@kb¼VLnlJlb"],"encodeOffsets":[[115920,33863]]}},{"type":"Feature","id":"4116","properties":{"name":"周口市","cp":[114.873,33.6951],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@lnb@xlJ@UnLlKXUlJl_KnV@xVL@bkbVVUè@Wb@UbmkVmbXVJnUl@a°@@bLVblXxInmnLVwanJÆw²IlmnXVl°VVbÈaVb@lkn@VWnLlUVmÞUUklkVkUaVaVaUwK@kkaVWmw_l@nUVVb@baV@VV@zXJl@@kl@lk°WVnÆbnbUVJI@VKVm@kK@_kK@a@aU@@wW@@k@aUW@IUWVUnLlUlVXKVwmk@W@VWa¥@k@lnUIÇKUaU@UUVmIUVUk¥Vma@¯k@Wanwm@@n@@m@UIVkUVamUXWaVU_@mUVUImW@aUIĉK@VmIb@lU@@nJkU@KIUmmLk@UVm@Um@@LkbUmJXlbV@xUb@@bkK@LWx@bUn@xmbÅW@nWLUKUbUVKU@LUK¯mU@VV@xULUVL@bU`WUz¯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»UanWX@VaÆÇô@ÈaVX@xVJXUÞUaVLĸbXKlV@m°Vn_nyXX»mUk¥lK@a_@yInaVKVa°_@WXI@@KVnIlbnaV@l@a@_w@lwUKmXa@UV@»Vw@kUKVUUm@w±VUXUKUwmJUU@km@@±mXkmUI@mmKUwkbWakLWaUIkJmX@l@@VUX@JWbX@VbULWblUVULknlV@bVJkmb¯KknWmk@@nmVkx@VmU¯KUnUL@JUIVmaÅaUm¯Xlkk@@lk@WI@yUUU@b@aUaUmVk@`nxUXlb@lLVxUbUbVbUllkVlÝVUnkVmKUXm@kl@nUx@xnxn@`VX@V²x@V@b@Wl@zU`VUVVbL@VbW@bkXllkLWV@V@VVÈwlV@@XK²LlbWnnÆ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@IaU@makKUa@_KnmVUL@a@IXm@KWkkKVkUU@aUW@UUIVaymwkbU@xLVUWWkk@WUkJk_WWk@WIUKÝk@WKULka@mwĉ¥mXUK@@bm@kVWwkU@mUUlIWm@@Uk@@KkVmn@lwn@@Ul@XmUXUmVÑkmkVKUaVamaUXn@ykLUK@WwKmKnUm@UmaU@mUk@kL@lxċxUnkVmnXxWb@`kzWJ@VLmVUnlmUL@lW@Ub@VXUb`VLUbUJ@nmnUlUUm@@bUJlnUU@lxkb@@XJUn@kb¯VVVmlXXlJlzn@VlkVW@bkKbmkUbVblXVxKÈnwÞlĊKlVnKlwX@lL@xlUnVn@l@lmX@ÆÈb°¼ÈwVJlx_°xalUÈxlUnbVxnL@lllbmn@nb@@VL@V@@VLJnIVVlKnV_"],"encodeOffsets":[[114661,35911]]}},{"type":"Feature","id":"4107","properties":{"name":"新乡市","cp":[114.2029,35.3595],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@XVlLK°bUblbUbl@nX@WXVVKVk@@mb@UbnW`kLLV@VVLnKlVXIlV@@a@l£nWlkVa@°bnUlLVlnabnUVUXKlU@@lk@aI°y@ôkUU@wmônkWakmlUkVmkUlmUUm@nkUKWanamULXW@UVnUln`lblL°KXV@ĠJ@L°JUVwanK@UUImmkK@¯±Um@IVmUmmÅnWaUK¯aUkw@W±kVxUVwnÅJUIWaÝJóIbm`ÝbÅImJUI¯¥¯@mU¯UJmnUVóUkl±V@zXlbWVXL@bmmº@@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@VLVb²VlKlaX@lb@lxUVULbln²VJUbW@@Lb@`nL@nVV@LVUbUVmkVllXbl@Xn°VK@_°`²IVVV@VUVJnInaWK@U@KLÆ@nmlXXWVUUw@klKVa@knyVkVanIJXUl@XbVUl@@aa@mXkbnK@UlK@UUUVaXaWmkUm¥nWmXaWakl@VmÞbKVL@aVI@mUwVm@KÅméULKVaUk@kUK@UWXI@VlKXU@VVnInVV@VLlK@UUkKU_@WWUwU@kln@@Imb@@mnUKÛ@mKUkWVXxmbVLXVVU²VV@xÅnmWmLU@kbmJ@b¯IUbJUUxVl@z@bU`W@Ub¯nUJUb@WLUKULkU@aWK@abmL@lmUk@@bULWJUI°@¯aWLk@mbUb¯b"],"encodeOffsets":[[114942,34527]]}},{"type":"Feature","id":"4101","properties":{"name":"郑州市","cp":[113.4668,34.6234],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@@nWVUKÅ@WnVnIV@kÆwV@nn@lxÞlnôJzXJl@nalUČVll@²UlkôVVUnmI°VnV°@°¦VJnIÆJÞan_VmU@ama@kU¥kaUklw@UIV¥kVUI@mmUÅmUlwVU@amUJWbUakVVé¯Im`k@wVWmLkU¯XkWmLmx@UUbm@@xJ@LbW@UUVWUkVK@kaIUamKUkkmmLUkJUVWXkWmnÅ@KL@@VXLmbmJUIUVU@ULWVkK@nWVXL@lVn@¤bkôKXKlL@¦²V@JL±@@VU@WV@X@`XXmb@blan@Jb@V"],"encodeOffsets":[[115617,35584]]}},{"type":"Feature","id":"4105","properties":{"name":"安阳市","cp":[114.5325,36.0022],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@°kVaV¥kVmUkWkWVkVKUwkkmKUU@awWWXWakKWkXmlaIVmX¥U@a@WnK@kVI¯@KğI@WU¯LkKak_kmmVU@VWXKnVmbXbVLmln@VVknlVUnVlklnXbmlmlXblnÈlWbn@@nK@VLbVV°VVzln@VxIbU@WLUa¯VUkWõ@¯kkmxk¼lXUlVbVLnlULmU@lLkVUlX@xW@¯mU@UmIUWL@aXakU¯anWk°@kkKmmUIWaambUkkKmV¯a@UblkmXk¤@@b@UbULWVnb@lUVVnmnVVUJ@bWXX@WJkL@blVU°UV@XlWnXUbW@UVkVVWbnLUJWLUK@Lnn@blVUnUblxVUVJXUa@UbLnUVV@mVIVVn@UbV@XbmbUV_lVXUWanJVI@WkI@WVIVU°WXXl@la@mX@lLXlkVbmXylIXJV@@kKla²UVaIVyÞb°LlVna@UÆKnLVbK@anwU"],"encodeOffsets":[[117676,36917]]}},{"type":"Feature","id":"4102","properties":{"name":"开封市","cp":[114.5764,34.6124],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@lUVbXaInV@bUVxknVVÆnn@VJlUU¦VJ@kxVllb¦lV@nb@bVUnaôJÞIXbVJÆImxUVwU²l@XxVl°bVLXb`XklUnmVblL@lmx°LVK@UXIVaWlL@Uk°KkVaVUXmmI@UÅKmmXka±KL@W@kUÇxUU@@UXUlKkklW@aXa@UKUaVUUV_@yXk@@a@U±w@UUW@_mmw@wVwmUaÇbUa¯UUkmWkn±JÅxmIbUxmKmnJWwkUaK@a¯@bk@mVUIWLmwm@Ua@WJUb@LUl@UUmLUbWJ@VL@VmXWWzUJUê"],"encodeOffsets":[[116641,35280]]}},{"type":"Feature","id":"4108","properties":{"name":"焦作市","cp":[112.8406,35.1508],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@V@VL@x@bXWV@XklUWX@J@nI@KlLKUVaV@JlL@KUk@KÞLl²_@nWlLUVV@nLWVUJVn@anV@awÞUVLVxb@lW@lbXnVn@@¼L°mKVn@bnl@nVK@blbLWU@VWLXV@nlKn@lVVbXw°nV_@¥Vl@XI@mlkkV¯VWnI@W@n¹n@aWKXUaWk@yk@kċUkVmbk@WIyóImÝkkwm@mU@xÅlU@mJXak@x¯V@¼¯VmUmmIkVWK@UXIl@UWVUU@mVUI¯b¯@lmKzWKUanJ@nlbÝ@@b"],"encodeOffsets":[[114728,35888]]}},{"type":"Feature","id":"4110","properties":{"name":"许昌市","cp":[113.6975,34.0466],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@lIVnKlnVlnLVbJlb@ULVlUXVVX@a@KI@wn@aVV@nwnKlXW°lVnKUXx@ln_°JVIXyXnW@UK@UXIVanKVV@Vk@KVaXI@Vbn@nxKnaUlnVa@Xa@VçUUla@aUK@wmULk`kIWVkLmK@V@XUln@JXV@nmbUóImUa±@@ÑóVUUk@UlKVU@akWVUUlUUaUK@UUKWbUkÅJ@XWa@XbmJ@nUJ@bUKLÝaUnk@lXbWbXnmn¦lVXnWbUbVV@VkL@VmLaWl@nb@bk@UVWak@WVImJUbUlmz@lUbkL@lVx"],"encodeOffsets":[[115797,35089]]}},{"type":"Feature","id":"4109","properties":{"name":"濮阳市","cp":[115.1917,35.799],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@lLXbWXXx@bVVnLllVxULUlXXlVlUnlU¦Ub¯lnK@VbVb@XbVLKVxVVnIlaba¥lU@wnalLnVVlVLXnlWVXn@@lVI@WnU@mÅW¥aW_k@WwXy@km@wUm¦lUxVLV@UwJ°x@VX@Vb@`VX@VX@llIVbnJlIbVlJ@mѯLóa@KUakX@UK@wU@lWUUݯImW¯aLUKU@k»k@mwa@UnKWI@UU@akVWKk@a±bóUWKXUmkKUmLbUx@lmLX@@bVW¦UnJkbWnXl"],"encodeOffsets":[[117642,36501]]}},{"type":"Feature","id":"4111","properties":{"name":"漯河市","cp":[113.8733,33.6951],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@@LUnVxnIWa@Xb@WÆIVlXaVL@VVLVbkVVUVlX@bUVkLVl@VVôU@Ò²@VbnôJVan@mWU@ImVk@WkI@wmak@wlW@w@VbnLVb°bVyXV_@aUKVVK@wUU@aK@kmbXVmJUX`knnK@aU@mwakb±@¯UUÝKUUU@WU@VkLUKU@mUmJUU@WVkL@UWJX@VVL@lVlUbLVKnêÆ"],"encodeOffsets":[[116348,34431]]}},{"type":"Feature","id":"4106","properties":{"name":"鹤壁市","cp":[114.3787,35.744],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@ón@xVVól@¯zJ@bkl@@kVWLUVmVXbVJnnlLl¯@Xlm°bVlWb@bKVXnJ@VV°nX@@wWVklUK@knVVKmkUKUaVkWkl»nwl°lö@lXV°UVbXKV@aJw@UmkUy¯UUUaK@UL@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":["@@VKbX@lbUVnL°@VlVnUl@VUX@aVmaXlaUUU@wmaVUn@Vnmmk@mU@knaaU¥VamX_@WUmW@_kVaVKnLl@VVal@k¥@kUW@kUKVUlUVÑW@kÇaU»ValmkUVUVak@aV¯_@WUkmVUlU@aalI@akkVWUaWXUWwWVbÆ@lalIVK@Um@UUW@al²a¯UağÇm@bkk@w@@WaULmxIUb¯@U`UXJmL¯aKXWUL@aknmK@aWUXaWm@I@UÅmVU@aUV@bVI@WkUbXkm@VakwUKULWKXmJ@XUK@mL@KUwVaUI@KU@mmnmXka@»V@@UUaw¯yVk@UUVmmkÛÈU@mWUnmxmlUbV¦UlbWVUL@UUIUmÇKVVbUVVxknLUxV`VX@kJVVUXWaUVVlUnmKUbkI@WULmK@L@LVlLnmUIWV@akn`VXUJIVlUVVbUX@¤mbnLmm@UXk@mm@Uka¥@kV@@KkU@aUKWbkLWVkIVk@UbVlmX@bU@@mmL@bn`@Ln@llVLVk@XVVU@`VXU¼k`VULka@VllVIn¤VU@@blÜbkx@bkLkKn@bn@@b@JUnV`UnVbVKlVXUlbn@°Vx@@bnVbUllVn@VVK@UnW@UVUlnkVÈÞxVbVVIxVaÆ@@aka@UVaU@@ak@Wl@nbVIÆ@Jk@L@VlXnlla@VJnw@UmwXU@aVK°ÒnllnLlbxnKVaV@l¦²nVl@llLx@XVVĶ@nax@U@alXUVaLÈþV°XxWXkK@mLnlUb@bxnLVlVVkb@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@WkLaVmwV@anK@UlIXmWkk@@mmLkWlwk@U_mKXwWK@U¯K@UU@VUakmkIyUUVUmanU@mlwk@_mWXaUWU@Ç@U@aUaVwUKUIVkK@UWIXmaV@k@Vm@UnwlUamk@V@ULUamxUJkU@I`WkkK¯XWak@@W@IUVLWJkXkaÇVUK@kUmbmUUUKbkKWUkI@kKÝ@@aUm»nI@mU@UnWV_@aUmWbkLUl¯b@akkk@WkkJm_k@UV±@J@bnU@@WÝIUJVbXL@nlJkx@Wn@VkJmbLmU`VbUL@xVn@XV@mVVnnJVbUx@VnVUbVVx@nbUK@b@bJm²VUlbXzVJVJVbn@@Xmb@V@bVJÈ@Vnkn@°aVVV@XKnalLVmUnnVKVlnLWlXXKlk°XWkLUVVV@nU@ml¯nmbk@W`Å@mbLWm¯UxnêVèk@mbVnUK@kKmXk@@JUIlÛLllnbVnlJ@LULnlÆaVLnV@nkVJ@lkô@²bÆm°wLWV@VXKVXI@W°ÆVKb°UJVIVV¦XKVL@lInaVÝnUl@@bX@nmVL@lVLlVLVUnbVW@xXnbU°¤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@blUbUVlVknUbV¼Èb@lXUÒkVUVVL@lVX@ll¦k@UbU@kmKULUbl@`nXV@XW`nUbV¦bmb@lV@nnlmnUm@UVnb@xVVVkbWnbVnVa@an@UaVUJXnWlXX@l¦@lKÆXbXV@VV@°¯°xXxXV@nV°UVWU_VWXkmaVnWVkn@lln@lb@UVLXWlnX@aXUmaVK@UXUU@WVIWXXVU@¥VK@UÞa²LlV@kV@UanKma@UVUnK@UVLXyVLknJ@UV@@UXKWUXaV@Vb@mVLnKWm@aUUm@@UkK@UlaLXKWaXI@alKlmUk@wVKXL@m@WWn@UVa@K@wna@aW_XWWkXbVW@k@U¯WWwka@UUaVIVkU@m±@U@@wVKka_@VV@XUVwU¥yUkm@V±ÈUKk»ÇLmmLk@ó£kmWwm@UIkWKXwWU@kLwkbmabkK@VLkmWIUKkUUÇIǫJXÅJULVÇLUV@UK@kI@WVI@UaWmXVVUL`±kÅLmKkkÅ@UaXXxWVXVbUXll@bkJb@bkVUVlnV@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@@UnlVbkmx@VUnl@U@nbWXJ@VlLUVJVLUxVb@b@VÈ@XVVWbnX@`lkx@nmVnbUVVVzlJnlVbUV@@V°L@VXLWxnLV`l@kxlXnK@nl@XlWn`Xnl@@UVa@VÈK£VLVanW°U@UVU@`VInmV@nV@Xa@aVW@UalkXKblIyÆXnlJXbl@@VV@nklU@`nVKLVKVb@VU@UÈKUVKIlUX@V`lIVbn@nblVVmV@@XXJUVV@knKVn@`@XVnKwlLVmUUU@U@aXL@WlU@UUW@UmU@KkLWaXkWmXUWm@U@nk@UmK@U@UaUVUUKV_@al@namWUI@KUK@aV@WUIb¥ULUJkImK@U@KV@U@a@UkU@K@wVaUwlU@mUULmKUkV@@anIWmUK@I¯mKkl@LUb±lUakLmk@WwUKÝVUIm`¯n@Uk@makJU_@Jma¯ImwUVkKbaUÅ@wWaU@VU@mXIVmmUkJkwm@mIlUKWzUK@VmLUV@VnbmLVbU@@lkU±KbÝV@UL@¦VWUWXUJ@XVWV@VULnbWVbW@kmWXUK@Vkam@kkm@UlmXUnbWlUXV`UX¯VmUU@Ul@Lll@nnJ@LnWmbm@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@VXV@@IVJUn@V@L@KlIVlVanLVbnVlIn@@a@Kl@@IJlI@aXU@KlKkVblJXUVlU@VbVkVKXn@VlxVa²I@VlVUxln@bJXklaVWnLmÅ@y@k@aI@W@aXIlVVaV@nnlKnLVW@IUa@a@KUVVlI@wXKVV@IUla@lUXwWnnalLlxXLll°@XwVKVaXIlnb@nln@Va@U@k°UmÆUVaXIJV¯ÇUmmkU@WaKmakVm@U@aVKkkmKkVmIkÇ°£@aUUVaVVnKlkXmk@lUVaX@@Um@UmlUXVUVU@wK²¥Ua@I@UVl@UV±UIUÇ°»VkUmVI@a@Umĉ¯V±bŹĖğaÇL¯lmkX@óĀ@mÝêb±WkLn@xXx@@b@V@LW@UblţX`kxWnXô¯¦ÆV@L@JVLxkK@V@bkz°llXz@JUlVla@XUVbVKXnW`XXV@laVV@VX@V¯xx@xULVbUJ@n@LU@VmmakbUK@bIWWUUVkUmkLm@VJkb@nUJ@`V@kXaUaVmmLkUmJ@Uk@U±lkzmJUb@bVUxVXU¤L@JX@VlL@JkLUVU@mnUl¦@V"],"encodeOffsets":[[117181,32063]]}},{"type":"Feature","id":"4210","properties":{"name":"荆州市","cp":[113.291,30.0092],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ÈJVlVVLXJlnK@UlLanblaxlK@XVWxXLlJ@VnXxlnô¤l@nKnÈKl¼VL²ÇUn@VlzV¦UxWVU@@U`lbUL@xV@²@@nlVUUJVb@VlbXx°XVWX_VKUwVKVa@UVKUUVk@KnblaUU@wnWl@UX@lÆ@@aIVmUkxVJUbÜ@Uk@WWnk@VVm@I@m@Un@mXUlVlUnJ@knJVU°@@aÆLX@llL@¦nJV@XblLVa²U@UlW@VX@`@LV@@bXJlIXml_lJU°bKÆLnVVl@öVmXaVIĢllUlVnLVlX@@bannxVLbn@°ÆXmmkĉ¯w±Uċ@KÝÅƧŃÝçUw¯m¯k@WkV@¯UIUJW¼kbUwk@W`@¦Uônb@VÆlÈ@VU@£UWWnUÆUnmJkUÇ£VWUI@aUU@WkI@Ua@JW@k£kaWVUKmnkKbkkVWbVmUUmwU@kk@UakUUa@V@nlx@lUb±lUbnnWLUyk@UamUK@mlk@Wb@VXL@x@xWI@a¯¯V@bVn@LkKmL@`XmKmVU@@bkL@V±bk@UaaLKUVIWXamVVbUK@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ÆbalLVUnx°JnbI@V`lInbl@@V°mn_VJÞUVLXx@nllKVb²kVa@KlknL°@JVLXnmJ@bU@VlnLVKV@nX@lUKVaXal@VKn@¥°L@UnwbnaV@KV@VUX@lVXI@KW@@IXWV@laVLKlaXUVVnkVWV@lwXblIXWVkVmaU£VaUmVIkU@y@WakKUamU@UUK@kmK@w@@mK@LV¯U@WwkmULamVVUU@IbUKUakmm@UakLmxU@UÒWlULţÿmwkIUm@akÈblW@UVUUk@JW@XkWWUkUKUIlw@aUWknWUUmnIWaUwVaÛaVUIwVlUnJ@bÅ@@kVWk@mX@xVVkbma@LUlVVUL@VUbULVxULW`UX@V@lUXWaXlWXX`@bmb@x@LUb@VmXX@@nWKUL@xVlknkL@bWJXbWLKkb@VlL@Vn@VV@bnXmLUK@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@aK@°nJwnVIUaÆJÅ@wwVXW@aV_l@²V°lĊwlaXLwlUkalVVaX@lVXI@aUXJ@U°UU¥VIVKVklanLVa@VÈIVV@nk@aVa@mV_@aK@klKUa@UnKWk@@lU@@UW@@nUWUwmaVIXlV@mLXblJ@kV@kk@KU@WkUWVÅwkLmW@UmL@lULKULak@maUUÝwUJIbKUU@aWK@kUWVkUwVw@mÝ@I@wkW@aww@LU¥kJ@nVJIkVVnkVUkyUIUl@xWUkaW@@°kzWxkLUWmzk@@bVVVb@@XlV@Vl@bVbUn`Wn@WbVVI@`LVbXLV`mnU@@lL@LUak@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`lwkUmUVWX@lk@VanUĠ¼V@@mX@@nVVVXLmJVLnK@bV@@J@VUn@VaVUUUVWVLV@@Kk_@almaVkUU@WVVUVLXmmk@wUaUKUV@°@kmaUaÈmWmUVklaX@lVnxl@@UnaUk@VUVwVKn@VVn@VbVJUknUmmVmk_VwKUUmVak¥@UVKVIkW@UmIVWkIVkmmLkwmVU@LUU@VVXL@JmLUbmK@UUKmkKUUmVUaUnÇlk¯mJUnmLUaUJUaWL@UkJU@aklkU@¯@KWLUmUUWVkbLUKkbU@WX@JX@@LWJkUW@UVU@@LUmbamx@V¯K@¦mULk@WbUbLkVW@kVVxUb@x@LlV@V@b@VU@L@VLnlJVIVK¦aVJ@XU@bLV@LVJnXmbk@@bU`VLUVVb@V@VnL@Vml@@VXnWVXnWlXblK@LnV@VVX@VkV@XWK@bVV@VV"],"encodeOffsets":[[115830,33154]]}},{"type":"Feature","id":"4209","properties":{"name":"孝感市","cp":[113.9502,31.1188],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@VnXK@L@°lVlkb@VlI@VXKVbVIVbnKVmnI°lÈkVmVbnUVVlLnVL@VnLVanK@IWKUUV@V@KVnUlxnKlnUlJUXnJ@VlXUJUL@Vl¦UbnVVLUxl`UnnnmVVlnVKbmVX@a°Ý°LaXJV@VUnKVXVK@LnKlLUbVVX@VwVJVn@@UU¥V@@UUK@maUVUkkJ@L@K@UmVUI@JU@W@U@UV@UIWmXUVmUUÇ@UVmIlmnmakK@akaW@UwVUkKVnUlKVwkVU_WKUkVW@UXaWkUa@w@VU@XaW±@IkbKb¯L@WXkW@UakL@UV@UmVUmL@UXWVL@aUVUUUVU@yUUIUa@wUKWVU@kWk¯UkwVKLUxK@nVxUlUUWVUmw@wUUyXWlX¦WbUV@U@blbUVVbXXl@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":["@@nbnmknJVUÈ@@U¥VknmV@VUlK@IkK@UW@IKV£UWVwU@aVanIly²kVl@@VnIlVnKUnVbblWU@@_VI@mlaUIn@lKVnUlVVXXJ@aVLlanbUnV@@K@mVIUaVK@ww°w@UW@UUUkbU@WWX_WmULaVU@WkbkUV@IWyk¯kly@a@UlLwUK@I@KÅUW@űUm@wl¥ka@@_Vw@ķa@akw@kKW£XVUVwVwUaU@VUUxWKkbĉx¯k±Uk@U`@bWXUx@xÆÅIVbUJmxIm¯@UmxnUVVbnJV@L@@kV@bVn@UVULlx°VXllV@XUVL@xVbJVV@zUVVVUVV@bUKWX@VnKUVVnU@@VlKVb@lXW@X°KaLla@JX²Wb@UV@@xVbXlWb@VUXVlXLV`UlUxkLmVUlLUVVxX@lb@blL"],"encodeOffsets":[[117000,32097]]}},{"type":"Feature","id":"4202","properties":{"name":"黄石市","cp":[115.0159,29.9213],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@VUVV@VbUxaWUblUVmnKlX@bXJVIlVUxVVVIUzlx¯@VbnL@xx@UVaXKb@XkWU_Vm²klWXVKl@nXV@@wmlK²XaÞén@ôÿ@lWn°kUKmmUÑUmm@wkImWU@UakL@bVLUVċ@bUK@alIXKWK@nXnKmkUVw@¯b@LlUL±Wn@KULUaW@kL@lL@bU`@nUb@bmlU@UÇJ@UUbmKkblUULUJV¦¯V@VWIV@bWJkUW@UbkUlbkV"],"encodeOffsets":[[117282,30685]]}},{"type":"Feature","id":"429021","properties":{"name":"神农架林区","cp":[110.4565,31.5802],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@n`lIXll@ll@b°aVklKXaVn@bU`mX@VV@nmJn¼V@bÞ@lL@lJXVlLaVLVnVnalV@VLÈUlblWXIKVU@J_@annaXm@KmI@mkk@KVkWWw¯w¯°@UUU@WaÅWkL@¥@kWWXkWmIUVVbm@@bUbmUUbW@UVk@mVkU@U¯mKVUkaW@aULÆVbb@VÅ@Un@VLWl¯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@kkWWUaVUka@aV@VUXaW¥Xk@WWIklm@ÅxmIVÝUkxka@bWJaUL@W@l¯UULUbkVUa¯bm¤UnÇUkmUUxb@VkXÇal@bVnlJnxŤĀVKXkVÑV@nwlKVbn@nlVbVLaJ@VVUnUbVKlnXxV@°U@KnL"],"encodeOffsets":[[116056,31636]]}},{"type":"Feature","id":"429004","properties":{"name":"仙桃市","cp":[113.3789,30.3003],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@VK°VkX@@VKbXI@alblwÞVUnJÆwn@lkXJ@XWVzV@xnxVXUVVVkUw@mLVwKVU@Um@alU@@@KUmIUaVUmnwmwmb@aW@UkmKkUkVġkUJWbnUõ@UkmUÅKL¯aVkIk`WnkJ@xVLUVVbUbk@WlXbmVxnxUblbUV@@VUV@nVL"],"encodeOffsets":[[115662,31259]]}},{"type":"Feature","id":"429005","properties":{"name":"潜江市","cp":[112.7637,30.3607],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@UbVxbXmJVnXVlmVX@bkxVJVLVlXXWlX@@IVlVUaVwVlnÈVVmn£°aVbUlaVUK@mVU@U@VUkaVamwUwnWaXkl@VaUaVUUK@wWI@aU@@K@_UW@kX@V±VUbkKWaU@mI@¥kKkW@ÅK@b¯@UVmI@lmIkVkUWVnm@@V@n@JUnU@mlXXl@@V"],"encodeOffsets":[[115234,31118]]}},{"type":"Feature","id":"4207","properties":{"name":"鄂州市","cp":[114.7302,30.4102],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@°¥WóXmlw_ŤWkVaX@@K@U@a@WwU@mWk@ULWkX±lUnV`XWl@aWLUb@Vw@wmKUa@°kwyVUJUUVwkUUJWI@akWmLUnkVaXVbUxUVWX¤lL@lx@bb@ĸUx@`@lbk¦@xn²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@aVUnlUXnV@@VnJWUJVnIVV°UbVVVL@²LUVa°V@aV@nmUXblLXWVXVmVLVK@an_`@X@l°VlXXW`nX@Jmn@b@nV@Lm`bUbn@VUVl@nIVbUlV@LkJUnVV@xVblVUbU@zUKU@mx@xUnn@@WV@lbUb@nVWXXV@VIV@VUnJ@VUz@JWbXllI@VXVVL@Vn@Wlb@lXVlLaV@VJ@XX`kVwVl@bkbUlVXIlnLVamVwV@@nV@XaVJVbX@lwV@n@nV@VWnIVVUÆ@Xxa@IUUKmk@mVIXmWUVJnUVU@anaVwkU@UXa@W@m_@a¯@@K@UVbnK@blIlbXa@WW_n@VU@¯bmyUkUJÇÅ@WU@kWKÅwnm°KVkmankVWnXVWV@UwXkV@mUlLnaVaX@VUn@VnVK@xlnXWU@a@@klakVwmUaV@wmIÛ`m@mVUXmlIXVI@K@aU@UaV_UK@wkUmmUKWXmVkUL@mU_nK@aVU@Ukak»@U@ymU¯UUVKkam@nka@mwkLWb¯mka_VaVKUIUw@kKmU@WK@UnmaULkU@wUalWV¹U@@WUI@WU@_@W@U@mU@WbbUK@Um@@UmbUwWWkk@WUa@anUUwlWUwUU@wlJVUnnV@@mnI@mK@U@wa@wUm@_mVUUaVUk_kċUkVWL@mlU@kn¥W@UwUWV@VÝU@lXLWVUbVLXlVIlknmU@VUJk@@@kVmwmVkxU@@XmVUb@xnKVLl@VxUxkIU`@bWVXX@JWL@bkb¤@bmUUU¯Kkmb@VVUVVn@@Vb@`lnxmblUnbk@xUmV@bmWbUV@VJIl@nVUbK@nn@VbnJVIlJVkXJ@X@lmx@bnnWVXJWXU@UlU@mk@@llb°xIUbnJ@VWbXVmI@JVX@bk@bWL@JUXUK@U@U`n@@Xm@XVW@@nX@@`ImxU@@JUI@KLmK@UÅUUV@VW@¯kUU@UamVUUmJ@nxmLKkmJkwkKm_mKXU@aU@b@Wk@ma@zUJVUmbUlU@xnXlWlXXblK¤V@@nUVVLkVl@Xb@VVKnXKVx@znW@X@@lVK@X@JXbWbnn@JUamLVVXIVxnK@aWUX@x@VnI@WlI@anVIVxkl@lbXXxVVVJVInbV@@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":["@@lxUXVlXUVnlVĢJVbUXVJV@XUW¯VIUK@klW@Un@nl@V`XUVL@l@Vx@XXW`UnUbxUlVnUVlb@VnJUVVVInJlUVnwVklKnwLVJVV@nIV@nbVa@KVVVUUaKV_nVVJ@_VWnV@n¥lI@anl¥X_VKlwVlULUVVV@U@VXL@IUmn@VU@wmKXUWU@m²l@VIXWWkWUkWlkIVamUXamUnmWUU@@UnlK@XJl@kVUk@mWKXkl@@aVU@UVWUUVaIn`VUVLnw@U@K@U@w@UVmUU°K@UnV@bV@Xk@KVm@amkaU£VWUUmUUwm`UbULkaKXU@kVmU@aV_UWVIn@yXXK@klmVV_kWVUn@WUU@UmaU@wnwWanUmmXkam@UakLmK@bxUUUU@Km¥Va¯@kUaVUlmUU@mUUÇmUkUybbUaXUWWbÅLmL@VaL@WWXUKmmk@a@UUKXW¥kU@VUkxmVkUWbUJnVJ@nVJXzWxk@lVbUX@VVL@`mbUnUnVV¼k@Ulm@mwLb@lmLUK@UamWkK@£Ua@UkJkUmbVlkX@bWbUVnnUVl@bbVK@VX@lbV@nU¤x²Knblb@xVô@l@b@l@XWxnVl@VV@XLVlLUUXV`bXXmJU@@bm@UUkLW@UlUKWUUbwUmL@nklVVmVXXm@@bUKlÆnXkllVUVVL@nUbV@V@nnV@xUn¯U@JW@UX@xĉ@`m@@LV@b"],"encodeOffsets":[[113671,26989]]}},{"type":"Feature","id":"4305","properties":{"name":"邵阳市","cp":[110.9619,26.8121],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@XIlJIVVK@n@VVVKnLVwVmnLVK@U@wJ@wVIÆ°X@ÜÈUÈxll@kn@VwVaXJWXn@@WVL@UUKVKV_U@@aVKx@UaV@lk@XylbUaV_Vnal@WU@aI@aV@@aVUl@XmUXWaXml@@kk@ma@V_UnUVUUWJUa@kkaWLUmk@@LUVWUkJWkK@¼UnWJIkV@b@JUIm@UlVm@Uw@a@kWXWKUknW@WUU@kmxUkVmIUJUUVmI@UkaUVUmVkwVaVmX_WW@Uw@@kUKWVU_k@mm@@VkX@lVLUJX°WVU@UIVWUaIUġmkVUkWUVWkwWXk`mI@¥kUVUUn±@mXkWknVUVmmU@@XVUk`@Xk@¥¯»mbĉó@mkU@kUKmX@UnmL@lULkKUWUU@bUaUn@Vb@l¦Ub@l@UKmnKUnlUVVbUVn@`Vn@xb@x@VL@nmJ@nU@mmUVkI@xVVVxkXVxmV@bbXVl@XlXVxna@Vn@@VVLaXaV@n@@V@X`V@@XVJ@XV@UºkXVb@xlVVKnbm@VXLV@nlL@VxJVULUb`lb°nXalKnx@lbmn@lbULVV°nV@z@Vl¼lb@VUV@bmLV`@nKlVnUXWVLnnlV@xVLU`VbV@"],"encodeOffsets":[[113535,28322]]}},{"type":"Feature","id":"4310","properties":{"name":"郴州市","cp":[113.2361,25.8673],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@²zVaVlnVl@nVkJl_XJlIVmnL@mV@VXn@lV@XzV@lyV¯²U@UlJ@XVKnVVIXl@UVLV`@n@JI@mlIKVLnUlVUVVLXaKVLl@nb@WXV°KUnVVL@xVJL@b@LUVVVUVXbmbVbn@@lUbm@x@XVVV@@@bkImx@Vm@Xbb@l°XU¤aLmnL@bl@@VUX@VxnVanLnW¥XKVwnUWXmVIUWÆLVxLw@wVmlU@¥XWUkwlÇn_UwWV@VU°wnUy@aVkVlnL@lVnw@VlJ@bXx@bVKnb@U@WVUl@@Vnbl@XLlK@aVLVKnxÞn@aLlmUaVUm@ÅknUmaUKmVk@mkk@UlWUkVm@w@kUU@WU¯¥@wÇ@aVIlUV@kUWU@UUm»@k@mKVkUKUwaUaUa@kkUWJkImaU@UK@maUzk`@zy@XmJkL@UUJmUkV@z@kkVmK@¦UbWL@a@UbmKmwUKXkVUUkmVkw@UUKmL@WUIWaJW_k@@WmI@mk@WkWULUUVKUUVm@Ub@nUÇ@U@wV@Ua@aL@akl@kUJwó@@L@V@`@J@xnnmV@bkJmUó@nJWUUmU@UV@LkWlnnmVXbmxxV@nbVV@XVm@UVlXU`Ukn@lWLWzm@UJVXU`@bVUn@lWVLlbVKVan_VxnVVVUXV¤bnl@bUn@LWlU@@amU@V¯LVVUn@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":["@@lUmkUwUyV@VW@¯VaVmUU@KVUVUVLnaWnkUÓV_@mVU@Ýw@ka@kVmUmK@IkaUamKkXWaUW@WUk@@KVU@aU@L@J@XÇVUKVak_mWkLWakVUbmLUUmlUVKUU@kUWW@UImJ@xkLkKm@@X@óÝ@UUk@UKVULKXkWWbkaIUWU@mUk@WLaUJġ@@XÈÆVIlVnz°aV@Um@X`@XWbkakJ@amLaU@V@L°@@bn`@@XWb@VVlUxmb@bUVmVUIXVWnJU@nnlVLV@JbWzk`m@UVK²VxkLVl@Vn@V°xVKVkVVlUblx@bUÆ@@nVnUllkx@VW@@VkLWxUL@bÝ@kKkVõV@bkXVVUV@VkUkVLkVa@@¯xUxmX@JVb°WXkK@Vm@kVbbn¤xUXkJblxnXÆK²l_@Wnan@UL@bJnIlV@lU@@¯ô@lWȂIVKVmU@aXaV@lwVXn@@K@UVKUUnUbn@lWXlJnULKV@l@²a@UlK@aV@naVXWV_nKlL@KUm@a°U°@VXL@a@wWmXal@k@VLnV@@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":["@@@KL@wnK±nnm@WUkÜÈn@n»@mVamkmUl@VnmmU@wUan¯VKLnVWlInyWUI@WWk@KXUn@mnUmU@WmkV@kXaaVaUmIk@kaX@Um@UKWU@UkJWkXa@IVy@UmIUVU@UJU@WXWmU@VakaU@@Xm@Vm@wnwV@VLyV@VakUUa@wUUVmlI@KUVkUamJk@VU@UmVaan_@KmU@@anm@ImWX_WWUk¯@k@W_m`@bULUKUnUWWXkKWaVmnU@@b¯UUbV±K@UKUUVa¯UUmJUVIXmI@UU@WmVmkUV@b¯w@lmI@W@a@m¯LXbmJVLklWL@V@XXmbVVU@@VU²Ul@VlX@b`XxzUmkUVÒl@bXLWxXVl@VbkLma@nmVmULVbmVUb@lnzmbUÒVl@°nLVlJkn@bmJk_VmmkblxÈx@LUbxVb@Vn@JmLVU@nV@¦VbnJ@lVVbkxbm@UxVLV@n`UnVVVkl°zxVb@VU@@ÆlXnWm¦nbVK@XVVUVVl@XKUV@nVL@WnIWXLVKVLlxUbVKXVWbn@@UnKVLVbJU@aVU°b"],"encodeOffsets":[[112354,30325]]}},{"type":"Feature","id":"4304","properties":{"name":"衡阳市","cp":[112.4121,26.7902],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@lV@XV@mXVlXLWX@l@bVxn@UVkn@VJ@I@alUJXIVm@»LXllIXVVU@Kl@VnXKlb@lVbXIVVUmVVU`@nbl@@lXLVVVKVbnXWJ@VXbWxXbUlVK¦nLVVUVVbbK@ULnK@Un@VxlUV`UnnL@VVL@JV@VUnxnKVbV@@VIVUnJUVUl@nWXllIUaKVbÞLV¼²`V@VIUwlaVmXa@IWanK@U@mkVVUVaX@lnaVLÈ@¥@kkJUWJUaXkaUmwVXJ@_lWUU@¥n_KkamUK@amKnKbV£¯W@kaWan@@UnwlJ@a@@UUU@Wwn@Va@km@UanaWaUVUUVU@K@aKUI@wKUUVm¯LWUX@mak@UKLWbUKVUkUmVUKLkJ@nJ@I@mU_UK@VWkUJmUUL@WkI@V±VU°kzU@Wy@kUm@UWU@@nmKUnkJWIk`IUlmk@mUUkUb±yUX@VUV@bk@WlXL@nVlUlk@WI@kLm@VV@XVmnnVWbnVUblJXkVlXXlWXUJk@±@nXVWVnL@xUVm@Vn@JWK@UV@UUVUVKUkkxULW`k¦m@bkJm¦U@mUX@`UImUU`LVbUVUU@LUbmaU@mJU@UUIKmxkLUl"],"encodeOffsets":[[114222,27484]]}},{"type":"Feature","id":"4306","properties":{"name":"岳阳市","cp":[113.2361,29.1357],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@@wUklmUUmU@@UVm@wUaV_mmUKmwkIkJmUUnm@@UUbUKUmÛamm¯xVLkbÇÆUVUzkVUlUUKWLX¦W@VUUUaKUbmLKm@akU@amVaUUVIVWkk@wk@@xmLlmÅwmbVlXlÝIWVkK@kkVL@VWKU@Ublnam@b@bnW`@XUJk@UUWKk@UKnn@xmLUVm@kbVbVnV@Vb@KnVLWXÆVĢ¦VblnUJWz@ÆVóUVbkVaÅx@¦lVUbVVknWKk@wKVUÅl@zkb@`m_mJ@xXmbVb@llV@n@llbXLUXalUlalVnwnLVKlVbX@@IV@blJ@bVL@VVVUXȤVnkVÑXmlbnVKkÑÅ@UmaVç@±XUlIxlV@VaX¯lUVVUVJnV@°°n°Vxĸł°¦b²¦lJ@U@aUK@kUm@_m±VIXal@Kl@bV@KK@km@UmUUaK@_UJaXU@Xm_VmUk@WUk@kU@a@m@UaUUU@al@nyXXWWwkly@¯n@@bnV@k@mVIVlUUmlUJUwIbXVaUal@Kb@VKVkXVl@VkUU@ylUVVaVL"],"encodeOffsets":[[116888,29526]]}},{"type":"Feature","id":"4309","properties":{"name":"益阳市","cp":[111.731,28.3832],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@ÆxXL@lV@ĢVIbXKl@nVV@XVJlbXalXWLVKUVLl@VV@ôÞ@@Wn@lLlK@wnIVJX@VX@lVVULVnkVVnKValUXblKnXl`UbVLÈU@W@IKV@@bUV@L@lXV@VXXblWnLVblb@JnLVUn@llb@x@ÞUV@nU`VÔmlXmbUKUVUV@LVVUnUb@°UX@UVzVxnlVkVnlVnaW@wnIn`@_la@ykÆVULxl@XLlmUUVakU@¥ÆwblUUaôVU@ÅXyVImkUaġ¥ÅUWXKmU@La@UmUUUalan@VUnK@wmmL@VlXLVVl@VI@WX_m@a¯mKUkwW¥UK@_UWWLUVkUWL@WUIkVU@JwkLUUmJVI@WkXm@VmkKUIU@mmm_@VUV@kJċwUU@KUWkkW@IWW@km@klwkWVkkUV¯m@kWLU`mIkmkXm@@`@L@xUKWkU@VL@JUU@mbUKVa¯WVnL@`lXUVkU@xW@UbUWVU@UJ@lnU@mnÈmVa@bULwUb@@VkxmUUUVK@IUmk@akm@wmIkK@bVWXkm@wULUmm@UVW@UbmbkKVnU@WlxVU@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@JlXXlV@LVVČxlI@VU@Un`nnV@VJlLUnn@lW@XUJnIVVlKx@IVlUVJ@XXKlVVUXKVX@`VLX¦lxVnL°an@bkmVaV@XL@UKlU@llLXUÞJWkUknaÆxnknK@w@l@xllUXUJVVUbn@blV@bnLnKVaLVbVVUX@W¥XKVLVVklUVyUVÈÅlaUK°wnnÜbnVVLaVV@n@VmnVlIlJna@Valkn@na@amwm@UXwK@aUUVUUaVawWK@kU@UaW@kKUU@kW¯XWan@kmmÅ@@I@U@KmLkaVUKkLWVUk@UVmU@am@kkk¥UVUKmaUb@UbI@aKkkWm@W¯K¯b@VmaULVxUXlVk@UxVJVbUb@xUL@ULWWLĕmxVVL@VbKUwaŲWwX@@WUWLU@VbkV@aU@@VUnmJ@VUn@VLUK@UmUIk@UÇmU@@UW@J@LbUmVI@aUmW@@bkXUx@lmLUbm@UbkJ@V@XmlUbkKm@ma@kUaVU@aUK@mImJUIkVUVUakbWwka@UWKkLUamKUXm`Å_UULmaU@@lUV@X"],"encodeOffsets":[[114582,28694]]}},{"type":"Feature","id":"4302","properties":{"name":"株洲市","cp":[113.5327,27.0319],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@XUnwĖKXXVK@VK@wVaUaUIVwl@kUVWUwVKnb@U°a°LX@XnllL@bJVa@VanbVLUV@al@@UV¯ÅÇ@Ummkw@¯yVwnUVVVUkmWVnKVUa@WXkVKn@lUVUVVVXIlV°VnI@VlKnV@mwVm@LXKWkU¥wWw@k@mX@KX¯V@VUVa@VnKWkV@VUkm@aWa@wkUWwkmV£VÿXUVL@mVIXaò@nW@aU@@am@aUUUmXmWUk@nUW@_maVmwUkamaUL@awW@akI@UxUm@kmKUklU@bzVm¯xUVU@XVxm`kÈlxXVW@¦kVUn@xxKUwÅKVXUJWnXmVUxWL¦XmmKbmUUwW@UV@k@VLnlbLm`@¦VVkX@`WIUxVnlbWVbXIVlI@l¦Ç@UKmbkW@UbUVUl@n@VmLXb@JWbUnkbVxUJUxWXXlWL@V@V@XXJWxzUVVVVKnXW`@bkIUlnLVJUbUIWVXlWV@XklVbnn@xl"],"encodeOffsets":[[115774,28587]]}},{"type":"Feature","id":"4308","properties":{"name":"张家界市","cp":[110.5115,29.328],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@@InWVw°w@@blUKlUlVU@VUUUlW@aöUlUlLÞ@@aVKXwlK@UX@@UlwkVkUm@m@ÅV@akwVaUkUUlUL¯w@UUm@UkKlw±UULVn@l_XyWwÅ@VUUmJUXU@@mmU@kxW@UaUIWbU@@mU@UxnUbmKkWJkUVal@aUkUxlW_@WUIU@bkKWUJVnUbbWblU@nl@XnVmV@nmWV@LXl@XJXVmzkJUXmKULm°Vb@xnVmnUk@VnnlUb@nm¼m@ÛÇVl@Xmnm²mL@xK@LUl@nULÆx@V@VXVWbXXl@nLlm@bVKXWL°bnU@VaVU@mVwJnwVK°zn@VVba@Ċ¼"],"encodeOffsets":[[113288,30471]]}},{"type":"Feature","id":"4313","properties":{"name":"娄底市","cp":[111.6431,27.7185],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@lLnJ@xln@bnlV@JLVUVnVlw@U@VaxVK@abnUmÇnV@km@I@VUVVXVaX@@wlVVUkW@_mKXU°UbVLnaV@V@IUKV@XlVL@w@K@_n@lWlnnJV_XK@l°nU@WVU@kV@nbVKVl@nLlLXU@lmkw@nW@UKVa¯IVn@@aVUUKl@nXVKVn²aXblKnLlmVI@KUU@akLUaVaUXm@a@wVUVKnLnWlXln@@U@anUVm@UInm@IUK@UmKVmU_kVUwm@@VmLK@VLaUaVUUUmK¥ULkVWaXwWa@UXImWUaULUUWKk@WnXbWVWnk@UV@bU@@bJ@bV@XkmbUU`VbkaWz@klU@b@VwUL@bV@U`ULVL@VUK@Xm@XWWIUbUxm@@lkkÇwVÛÇW@¯ÅUJ@xIx@@VULmKUnUxmKULUUm@@ULUJkIWJ@b@LJUWkJWnUV@nnÜ_nJxU@VbnUxlkb@l@"],"encodeOffsets":[[113682,28699]]}},{"type":"Feature","id":"4303","properties":{"name":"湘潭市","cp":[112.5439,27.7075],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@Æ`n_VWnLVblKXL@VlbXxlaVbUVlUVJnInJ@VL@bUVVb@lnbn@lLVank@W@UlIVan@VanK@kVwlW@aX@Vn@bUJVna@KIX@@VV@nVÈl@VJn@VVLK@UVm@UnIVm@UV@@blUUaV@XKV@XW@XxƱbVxLUa@UKWk@wmmUalk@WXUWkXUVJVaUImKVklJ@aX_mWULUUVUyXwWI@W@U@UXKWkXWVwU@±_U»ÝKUaLVbkJkWmXk@UVVmIUVJ@UU@UamLmwUVU@mnJ@VUnmV@b@Vm@kkWmXmKULUV@x@bWnVUbVblK@bVV@LUJknmKkLWa±bUmULmWk@VLUV@bm@U°JUbVLX@@mlxkn@WVKkmK@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@lUlVXXJVbnUKmxXV@bm@@XLÞܦXlVnmzVJ@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¦`@XUJU@KmXw¯KXkmy@aUIWJXXmV@K¯UU@@bVL@¤VLXbV@@JVXVK@JVn@bkKmakVVXUVVVlI@`U@nzVVb@¤n@@UlKXLVVI@V@nV@V@ÈUx@óVōkÅWó@mU@bk@Ýwk@WbXxm@@J@zV@kVbVnLWVUXWUXUWLU@Wl°z@VkxU@UVWIxWJkbĬ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°KnVaU°x²mlx@VanU@ak@akmV@@w@Ua@aUwVwUw@w@UK@£kaĉlóIÇVk±@@kUKmVkIkxW@Ua¯UUm@UVI@WVIJV@@Um@UanaU@mI@J@XV@XaVlkXVaUUWLUyVIXmWak@XkJókJUL@KWkk@ULU@WalUIkJmImkVbV@lV°kXUKWKULUmb@VUlVnb@VV@IVKUUmU@ak@@bmV@xklUU@UKmV@nJVbkXKUamLUJ¯UUVmIbVVLl`@LLU`m@kXUVU@VlxUK@xkIWbUKx@VkVVnb¯@@U@xkmbkLÇKb@@XnJ@LmVkl@@XlUVkxakVVb@bVnUbU@@xVUVb@nIĊ`XVVôJ_K@xlU²KlkU@VaVVÈm@kVUVmnamUUaVXIVJ@ç@¥nkVLn@@XVK@VUX@JVUV@UnVJVLUJVLUVlnIbKnU@m°VanI@anVKVLanlKblKÞk@¦@¤@VKnLVKLKVzlWLX@VmV@VbnU°@UalkWXLVUKWkUUW@£Wa"],"encodeOffsets":[[121005,35213]]}},{"type":"Feature","id":"3206","properties":{"name":"南通市","cp":[121.1023,32.1625],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@VJ@bnzWl°LxnW@LVVI@W_V¥@VKVL@LXJI@nbly@aXXla@aVUnllLX@@UVKlb@@mXV`V@bĢlkČÇÆȘ¯wnĕVĉVÿUƒUĠŦğlXÑVǵ@±ōLʵĖ¯lÇbÝÞ¯xk@Çkķén¯@ğġƴǫ@kVVlUbL@xULÇóLUl¤@nkVV°VLkxVb@laUXUKWĖklVX@¤UUkb"],"encodeOffsets":[[123087,33385]]}},{"type":"Feature","id":"3208","properties":{"name":"淮安市","cp":[118.927,33.4039],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@nźUôÒɴèl¦nĖVkbmX@xVlVL@xUb@bUJVnUxlKVLÈxmzXV@lW@XVb@bÈVxnbVIXa°LaÆVVaXUlK@aXIÆVlXKVUlIXalK@alwXLVK@¥Ý¯¯ÿ@mVk@aX@mīlaXIwXJVUV@lw@U¯ybUaUġUÅaUKVknaġm@kUm@wÆIV±nLÆwÇnUUk@ƅÝU¯JÝI¯¦Ul@b@@VVL@l@LLÅmL@b@UaVaUWmLUKV¹KLWKX¥WI@mXk@UmaUVUU@VmL@WbkIUWUmVóIkbmm@UbVLUxmJkU@bkJWbnXU`WzKUÞÈlVbLmx@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@xJ@X@blJXnW@@`XbWkV@UbVxXUxkV@LóxVbUVW²VJĸklUǬ@ĢƳĠ°@mƒī°»ÈÇ¥ULUU±a@bU@¯U@KnImUVWUkmXUVU@lIVaUUVWKUbUkWKU¥n£WakJUkULK¯LKkVIn@VaUVUUUkVk@U@amUkJ@UUlwX¥W@@UkVmk@JUakL@kk¯ÝmJUn@nmVXlmbVVkn@UJ@±WUxV¯a¯KōbżÇxUxUUlWL"],"encodeOffsets":[[122794,31917]]}},{"type":"Feature","id":"3213","properties":{"name":"宿迁市","cp":[118.5535,33.7775],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@XbWnUJVzXKVVUbWklUWbU@@W@IJ@nVmbVbn@@V@UIUJ@XUJ@VVn°VVbX@lwlJnUVL@l²@lÈUôJĊklb@¤VL@@xVxUxVx@bVb@@xU@lnmnXmXLVmV@X@lxVnVJôLLXax@b@@KVL@bn@@m@@alLUUVaU¥nIV±I@mXI@aWWXU@LlUXWW_XWmaUwÇ@aaWUX@@kWUynÇwUKkLVwUmVI@aVa@wUKUk@wWnlaUmĕk¥ɳçóÑŹVmmzkVmm@a@Iók@@LWU@`WbXLWlkImJVn@`nXVbXmL@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`XnlKXXmKnLlab@xmbm@kL@V@Vl@@VUXJXmb@@°Æ@èÈzlW°XĢJlÈ`lInbWV_@m@UUķnôw°ÆmnaVVÛVmĸ»Ģw±Ý@@mUInyUmWkÛ¥ÝK@Wn@@aWUnwVLmUaWIUWVk@kkJUVWLUkÅWJ@bkLWVUbÅUb¯KWbUJWXX`WXkV@KWVXX@bWJ@nJU²mJV¦UbVVkK@b@@nm@@aUK@L@@awWbKóKUIUmkwW@U@UnWKnmWn@bl@bmVUb@kw±n¯wVUb"],"encodeOffsets":[[121253,35264]]}},{"type":"Feature","id":"3210","properties":{"name":"扬州市","cp":[119.4653,32.8162],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@VUXblVVVb@xV@kzV@lwVLUbVV@VU@VbUblb@nkĶ°IÞV@ƆVlmVÈÅxmKU²ÅJ@xVn@lĢnmbUlVLÆbĢVVbVaXk@VXKVVWXVWXUmKUaWaU@¥@£XWUUV@@ynam_VWkUVUna@ÆV@mnkWmXkWUW@k@@akkllWUI@UnKl¥I@VVma@a@I@U@a@anK@UmK@ÅVUnJlkI@aVwka@mVIUW@UWL@WÅbmIULkaUWUxkLUKWlXL@VImÅVUmĉLUó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¯aUakKWU@XULXaV@@mUaVUUl@VmkaUXm@WUUna°IlmVmIUW@Uk@@aV@VVX@VI°»nmU@VKVan@m»UaU@U_@WlIUaaVaUala@¯n@kaUkUUWKU@mwkUUmmL@K@LmUUVKVÅImUJVkVVLèVLVU@WLV@nVÜULVUL@bW@XbWbkJUUVUxVXmVk@WUUkVmIV@nbnVWbJUkUULa@Jma@XkK@VVL@L@JLUVU@V¼nXlbm@kbUKmn@lVb@VXXVUV@b@LVbÆxXbl@@lV@UVV@XVK²VlI`UbVbUlVVn@WXn@@VUV@@KmbVLXÒLkKV@nX@VVUV@bnVllbmnbIWVXU@`lLlknVnmlLlbUmVInK°nUU@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ô@ÆXlŎôU@Vw@ÇUU@@m@UJUUWKkL@Vm@@£aUUmyV@@_kJUUVUUWlUnblL@aUmI@ULUW@IU@WaUK@£UK@aV@°V@LnUWWXIlaVV@£UWlkXĕVLVWb@kUalwUKU¯lU@mk£VôKÈVK@wKVaUkķlUI±ğ¥ÝUŹ¯ôm¦ĸ@XXK@VVXUJ@nlbUx@blJkmIUV@ÆnL@VmL@b@b@V@J@bnbU@UJk¦mL@VVJkXkll@b@@lXXVWlXnml@nÅU@mbUVlVUXn`mb@zU@VVWX@¤¦V@Xb"],"encodeOffsets":[[122592,34015]]}},{"type":"Feature","id":"3202","properties":{"name":"无锡市","cp":[120.3442,31.5527],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@nLÒlxUVkLam@kVWUULUxVVVbUV@bVLUnnźÞVĠ¦XVUUaôw@KlUVwWUwVa@lUXWa@_X@WmkI@a@WI@w@KmKUUk@@aVUVVÅmJ_@W@a@I±wÛ@ƑÇkw±¯£mWĉUóçK¯VkUWK@XkV¯UWabmUaUUblln@b@xbXWX`@VxUblL@bn@Vb@`m@XbWnn@l¤n@xnVlUVLÆWkV@VbÞJ_nl@nKVU@aUU@mVk°WVLUV¯bVXbXlVn@VmL@xV@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":["@@LnxUbVVL@xnnWnn@VVXn@yImx°La¥n@VkKVwW@nXVJ@b@UVn@UnUV@Lb@`VLklVÞnÆ@VaXLlÈJmmVUK@aVUUaUUVwVKXVlUn@blKVUkwÑmKUVUI@±UI@U@WmX@k@aU@wnK@UUmWkaWU°aVUUK¯XUl@nVV@bUVmLk@m`ÝIUaU@lÅXUKkVmU@wmk£m@XmWan@@_Uam@@akKVaUw@W_XWa@w@akmm@mL@UJmnUK@@XnJWLkKUb@VxkWLaWVUImVULUK@L@lkLVVVllbm@@°kbVbUbbVbkJ@XV`V@Vbn¼"],"encodeOffsets":[[122097,32389]]}},{"type":"Feature","id":"3211","properties":{"name":"镇江市","cp":[119.4763,31.9702],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@VĊKnVÆUnJ@UWKXkVLlKVwXVlbVKnJÆaķn¥°óÇIkWKUbÅ@mUÝlkUK@_a@KVUVm@mVU@@aUIW@mXUxLUlm@¦bK¯nwJzm@UW@UmmXmm@wKUUVamwKm@UbUL@Vmn¯¼JUW@UUU@@bl@@VVXJnnUk¯JmbVVXn@VWlbUnk@VVUVb@nU@WbKWV@XVlLVb°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ÈlnKXkVlVL@lJnb¦VKVVnXW@w°@VUmlnUV`UbVUV@xnKVI°KXKVkVL@al@XaLVlULWVVVL@bx@VXVmb@x@VVV@nn¤lb°b°KXXWbX`lbXxz@x`VIVUnKLxWXLVKVbVLVU@wnW°b@nalXmXVJn@U²mKkVlU@@xlnaVmlKn@JVLlnVl@XXÆèVlUX@xVLXVb°W@wnUWmXk@KLVwUmUkUKUw@wVaVK@k@WnkUKWkwlmXL@KVUlLVKXmWUL@aL@malaVk@aaanX@VVUblbJnXaVwn£K@UWmUk@UaWIV@bJW@KmmU@aUUUkmKkVKlUUnKVUlVaV£Å¥WUUK@UkUUw@m@mIkUUWLK¯Uw°¯@wUKUbKm@kkKUL@UUKV¥U@manw@k@U@Wm@@U@WwkmwWaUU@UUmV¯kw@@kmkKkUW@UK@ÅV@XWWkXa@Ul@Va@KVaUUU@aXwla@UkVWaXk@K@lmkUmV@Vmbk@»XI¥VUkVUVU@anKVUKUalU@wX@@a@K@ÝwL@UnÇlUIkJmn@bVVb@VmnkLV¯U@±lIWm@kaUI@aÇU@K@KUIkbWbJUIUyX¯UbU@méUUmUkWKxWIkJm@V¥U_UJUwmVkUU@@knwm@UmkWJkL@n@VW@@U@knm@kUml@xÅx@@XUJlb@VXJVxn@lbV@lULnV@VlnV@bWV@bXL@lVLVbV@blLn@VlK@xln@bX@laLVbnKUVVbKlXVVkxV@nnVUblV@@z°WWkbIkWL@LUJ@bUI@b`@UmI@mkK¯XWmUV¯@UUVUUam@@VULWUJIm`IUJKUkW@UxnWbnnmlXbmIUVmV@Vnb@VLUKWLnÒVVV@VUL@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@nlIn@blVXKnk¼@VUKWL@bL@`UXU`@V¦XLĠ@lJ¦@nV@l°nn@mVXna@nbKn@lIV@VanJ@_lKVVnL@LK@Vn@VbUVanKlLnbnJVbnWVnVVanI@Vb@LbVKVanXVbVJVU@aXLllbôlƼXxVLVK@Xn@xnVVVmb@LnVVKVXV@@mnaVXUVnVK@_UaUmwnKV_anKVL»K@¯ÝU@U@kWlUnlknKVnaUkma@UIUwl»Åw@VwV@nn@ÈXlKVmna@kVw@anm@n_WWk@mUkUK@ImkLUnbkm@wV@klUnLV±m@UInWkWmb@¯amX@xUVUKUaULWKXwKmLUVUJ_@wyWwkaW_XaWW¯L¯akam£@mUU@U@wnaWU@Uw@aUKUXUVKUkKWbk@@bUKUlWL¯LUJmLwU@UVaVU_VkmnUV¯@@xXmWUUUL¥makI@UKUkWlLkmÇ@aUk@UKL@kmÇak@_VlkL@`lbnlLVanLnbmVÆln@kJlbknmKUbÝmmwULUK@bkLWKULUUma@Kk@UV@L@llbVzxUxnl@bVLm@IVJXVlLV`@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":["@@@VI°`nm¤²@bVJUVVXUl@Vmb@xV@XbmVV@lkLmbn`VbnU@VaUnbVllUXVa@w°VW@_VWLnVlbLVbnlKnVK@IUW@_@am@ÑUólK@U@WU@VwU@UI@aUUaX@kwmJV@yX@kan@mkwVmmI@aUU@aUUW@kVkV@@anK»XVWnIVUl`@_W@wlUV@UWKnUbn°InJlUV@VnIbWn@VklL@l@Vn²m@U`kI@bWJnV@°VXnJmXVmx@VVL@bkLmWULUmU@bWXb@llnX@xkxVVnVV@¤nLnVxnJVXX@bn`VIb@blmlLnaV@blWXnlUnbl@KVanUVmm_XK@kWWnaU@UnaWUXaXamUkKmXUWLX¯WakKmnUWwXa@KW_aXWW_@WnIVl@XULnWVknK@ImyUUÆbXKÛ@W@IÆUnVÝlkVK@mUIVwkUVaUm@aVIVyXIaÈwmmk@UnanVUmÅaó»lwW@kkUVmUK@WKLUmWULkamKLk@Wa@wk@UU@U@mbUIWVKUXWmkUmVmU@LkakKw@w@U¯UUn¯l@bmn@xkJWxkL@VkI@mkmJUI@V@b@VVxnbWlkÈkVLbkKmVL@V@²nxWkLUL@xlKVxbXmVnWJ@Þ°@nxUKUw±`UImVmnU@kalm@akwU@UUJmxU@@U@kU@Um@@KnVm@kKmkU@@WUnkLWxkVUwmKmLkUbmKUbV@xUnkJ@n±UxVXUWJ@LUblUnm@W@nknUJUVm@kXllknVbÆKVVb¼V@Ul"],"encodeOffsets":[[119194,29751]]}},{"type":"Feature","id":"3604","properties":{"name":"九江市","cp":[115.4224,29.3774],"childNum":12},"geometry":{"type":"Polygon","coordinates":["@@WUkVUkmaVUb@mVUam_nalK@kUnUWaU@@wna@UVkUWVUUI@a±n£m¯_JU@ĉ¦Ul@UVKmmLlm@ğ¹m`Uk¯@@UVK¯@UUK@amkmKkVVUa@UkUKUaL@VVXUJ@n@WUbnVb¯V@LÅlÝIJÅkÝm@UaWUU@UmUXmmwVUUKWUX±mUam@kWzUaVmÇw@aÅLmKXUWKkL@W¯IwVwlkUJ@Um@ÛÈWKUxWkaUU@KkLVl@UKUX±KUb@nVVUbUVmaUlUL@aUL@@nUlWzX`@V@lx²@Vlb@bVÞ@°nl@UxVL@lUbVV@n²xVUVmnUÞbaJ@IV°xnbl@nbÆ@VwnK@VnXlK°xnUlVXV@Vl@L@lk@W_XK@KkWxUL@JnVx@aX@VVUaIXlmL@bVVX@VbnKa²XVWk°a@UnV¤nbmLmW@XbmJUbVLaÞKL@K@U@aVKlbV@nXlJxV@VnVÈÞKôbźĕČmV@Ċ²xÆIV@Þ¦ĸ¼ÞVlVÞnxln°JkLXWVUVUVwnJVI@yn@lXlaXmWI@w»ma@UmK@akKkXmW@_kaWakKWk@@K@IWkUa"],"encodeOffsets":[[119487,30319]]}},{"type":"Feature","id":"3610","properties":{"name":"抚州市","cp":[116.4441,27.4933],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@°V°UnÜ@n@lnLlV@bV°LlnLllVzVVXlVV@@L@xX@WlXm@UVL@V@n°kVmVUnKlaXxVbnlU@lVVnaVI@aX@VJ@V@bb@Vb@X@lUL@@VlIVm@wUVanLalVnKnLVxlUXwlKVm@k@Una@mWIXKWUÛVk@a@UVWn@@kl@@WXlW@_Um@UVK@aLnalInWV@@xnI@¥Km@kKmnk@mlI¤laXbVblknV@UKXVlUXa@@Unw@±mU@ak_±a@UJUIVKW_Xa@aWUK@mmUVa@IXa@UWmannlmX¯WKXwVUVw@XUlK@klJXa@kkmm@Uww@¯W¯kw@WmbULaUUU@mVUUWmkUbKmkkK@akU¯¥Ulm@akU@m@KVIVV@KUkUVUkaUWbmIkaVaUU@mWbb@bUlkbb@nK@bKXVWnULkKUV@LWKknlxXVLml@X@lULUb@xVxVLVlVnUxK@LWlXnmV@x¯XaWUUK@wVWUkÅçm`@mn@bUx@lmbUnkLÇWm@mU@Ux@Æxk¼VxVJ@nbVlmbUmLklmkVlX@VV@°Þ"],"encodeOffsets":[[118508,28396]]}},{"type":"Feature","id":"3609","properties":{"name":"宜春市","cp":[115.0159,28.3228],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@@VlbnK@b@JLlUnx±ĀXxÆWX@l@V@@blJ@nX@xUbVVUbVV@bVmnmJ@bmbm@klUbLmb@lVb@xUX@bVVVbV¤@LVVbXlVwLXÜÇn@@VIlVkUxx°J@XlKXLVWnLÆK@bÈxUnVbylXn@VbnW²XVLVVUnxWnnV@VVVXVbn@ÞÆlIÞJÆk@K°UUamVa@UUU»@wV@VkkUKUVW£U@UmW@@aXkVUnVlKVVUUkVmU@kWaUanUVVamIX¥W@@aUaUVW@_mW@UnIVVn@VbVm@bVL@anKVUkWKUXVIkx@nabVKb@nVJ_V@VwVUVVXUlUUaV@X@VblabnKlkVaXa¯@m@UKVUn@WXkW@@w@KU@UWkUUUykkmKk¯KU@akUmK@k@mmÛ¯V¯U@L¼UKmLbU`mLxVnVb@`LmUVUUWmb@nU@UWULmU@KnaUUmUwmJ¯IUJWIkVkaWVUIUlWaUIUVkKmbUIÒlVUnn@VlLUJ@bUX¯@aWVUKUXKUbm@UwKWa@a@VkUWn@Uak@mbXWJXbm@mLaWVk@wL@WmanU@knwWmkaWLKWUXaU@¥lUVVVbnw¥nKV»@aUk@a@UJ@kmLma@mbUWnm@ULǺ@LXnmxUm@UbkbW@@akLmWk@UXmJmUkV@VUXVlULmKUxkL@lmXnJ@Xl°Vnb@bU@WbKUX@VmKUX"],"encodeOffsets":[[116652,28666]]}},{"type":"Feature","id":"3601","properties":{"name":"南昌市","cp":[116.0046,28.6633],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@X@m@VIUW@UKVbLlV@VVbUlUnLnl@bVL@V°UL@V°@Vln_Ġºn@knKnLVU@VkĊ¥Vk@U»UaUÅLUalmkklWn@VUVIlm@mXn@VmkVa@KXIVUWVw²@m@U@VK@k@WUa@a@aU@IUW@@bUJmbUU@kkVmUaWwkbmLUVUnlWbUbklmLakbUaW@U@VbkVWVUUUVUx@U`UI@maULamb@lwJWUVXLlUVmL@bUK@aUnUam@UUmJ@VnX@`UXVVb@bX@W¦nJUbUmVVbXb@lVUnVlVUUkLmUUVWl@bX@VnV@X¤VUVLllUU@@x¼VV@V"],"encodeOffsets":[[118249,29700]]}},{"type":"Feature","id":"3602","properties":{"name":"景德镇市","cp":[117.334,29.3225],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@VVX@VbmzxUlU@mbmL@V²xVbUVVblbX@VkVykValKVI@bn@n`lVWnX@lL@WKnVIVa@¯nK@alIXJVIVWUwn@nUnK@alI@a@anKm_aW@UWmIUwmmK@£UUmUUlwwW@km@kWaXaV@VnVKnXlK@aUK@UnwWUnmIUW@¯mUXI@alJV_n@m±@U@kkKUlm@XamJ@UVUkmI¯JmamVXL@VUkV@xX@`k_UVmJUXW¼mL@bU@UllX@VV@bVV@bnJUnlx@nmb@lW@zUnIlx@WbVV@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@UVWLXaV@@ama¯Uk@WmInW@klKVwnLVKUkVW@UlUnVnIVWl@nXlK@bX@laVan@VnwWm@KȹVK¯m@kmU@¥kIğ@WKU¥@V_VW@_K@aXKVL@Ul»mWLkU@amkJm@kmU@@a@UmakwU@Xl@VXk`UIW¼kWWX@@lxV¦XlW@Ubn@mUkL@UmJ¯UkUWVUaUlm@UXWlnUJ@LmLUnXll@bUVUUmVUn@¦xlnn@VÆÈU°kbVVxllnL@VnVVUl@VanL"],"encodeOffsets":[[116652,28666]]}},{"type":"Feature","id":"3606","properties":{"name":"鹰潭市","cp":[117.0813,28.2349],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@@XV@nlL@lUnm@Ln@@VlV@@VV@nwVI@VVlx@bknlbV@nmnUVJ_²VxVLw@m¯@ÝXImnUWaUwkL@wVKlKXmw@±@UKnUlLaKlUlÇXkmaUw@U@a@UUkwUJ@zWJw@WbkVWUL@VmUklUaWakb£kJ@nmlnlL@nL@¦mJ@wU@mXkJmbK@bUL@VVn@`kXW@Xk@@lm@UX@V@blÜ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Å»ókakkWK@bUVUIUamWUbULa@KUa@mJUbmUXUmUamImakKmLUbVUam@@UL@KKmUUkL@`mIUb@U@V@bVl@b¼UmL¦mxUaUUVk@¦VWbXVLXKlbXnmx@lmVnb@XKxl@XUbnKn@WaXIWnal@Vb@XmlV@U@bXbLVxn@VaLVWVLXUb°@VW@aVIkK@UmVmkUÑ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@ó¤VX@@xܼƨ²xWxVV@XVbWXllaÞU°Ċ@ô¼LôÝWanV¥Ñnĉ°¥ÅX¥°¯@w°w@»°k£°mÈŹmÈbÆŎ¦K°z@kxl¦UbU¤klVKŤÞȰ@@bV@nVVUlÞ¦lUllVlU°ÑU¯V°wbXxl@V²@nô¼ó°kmVk²ĕw@wVÞÞ@@Ġö»¯@bnb°mÞ¯°V°ÈJmX¥mamUÅUlaU¯@wKkl±n@@wkÝVUUl±¯I¯bal@kLmakb@ġŹé°Þb°ékLmwXaÅb@bVlbVbÒVbUbUUanwakbVUVak¯ULmxV°UxnôŻX@JXklbkbĉabWU@kWUU¯@@klm@@Å@awWXlKkI@WbUaVIUanU@ĕ¯KmUnWUwm@£ċèkUmbUmm@@nkJUalwk@@nmWUan_óaWmnw±KIwl@UmI@an@@mlUÅmV_KUk@U`@_KUmU@U¯mmb¯@kbImV¯LkbKÛ@ÇnɱJóaÝĢkb@xÒÇll@²VÆUVVUÇ°XóxlV¯lV@bV@nx@¤@șŎnxV¼knJnKX°¦UlnVbUbÆVnÞWVX¦llb@l°VJôÒnLVbbX"],"encodeOffsets":[[131086,44798]]}},{"type":"Feature","id":"2202","properties":{"name":"吉林市","cp":[126.8372,43.6047],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@ôlzaÈV°K@mLWlnVxUVÈ@ÝĬUÈnôLa²VmĀkV@ĠĊnU@bV@b@nl°UVnÞaôJ@bV¦mlkbmVXx¯@VxmnbbÈKV@bÈLwĠyônmnbÜ@nnVx@n²KJ@kal@nxÞULź±Vwkw¯LWWUkŎīVww°yVĕ°wÈVlkÛ»@wW@Uô£@nĶXwWaUamKóÑUI¯@kakkW¥XUmÝÅUVaUamVk¥W¯LmIlmU»mwȚō@£kJUÇk@am¯y¯UVwa@wġx¦K¯X°Ċ¯¦U°ċWULÅa±b¯@UkÅWmVkIUlóċ¹`óIlXWXxmbULÝbƧ@x¯bÈl@x¯zaݤ@nmVWb²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ÛÅÇéĉamKōÇ@IôġVȁÑŹçÝUƧċĉwóóÝ@Ƒ»ğL¯ll²@ƆÅV@¦mÅb@nmlU²VxlUn@VbnWbÇbkÒn@èlnlUÒ°Lx@¼ĉb@ÒUċxÅènLVxÒbÅJ±a@_ÅJÅnVbKlnUÜĊ@UxXVÆnmVJÞ¯VĠwXw°xWLxKV¦ôUwVÝǬóÞÞ¼ÞkVôȘxÞUlVn¦ÞĊa°wb°@bÆwlŤL²`z°@V@@nJVnl@@¥nUmmn@mwnmmUnk@mlwUaLnwn¯°anWakIÇmXwÆamUXUlJXaUUklKUknmÞ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Þ`Wb@n°abKnVw°`_X`W¦ĊIkmVakwKx°UÞbU@ll@°¦VWaÞbxÞI@mVI@VkÅUWK¥nLa@@È@°Æ@nU@KÞalkUwVékUWwkUVkkJk¯@»ókV¯ÆÇI@bĉô¯@ķw¯nmmÅL¯wVUÞy@UówÇLkmm@@UóxkkĉmL¯wVwkWWXmLõm@kűV_ô»ÛƯ@VaVaĠVlmğwķUóÝƽ£ÇJkbǫaƽLW@nxݤkzy¯XɅm@VôÇX¯Ė¯ºÝnUnLVlUÔ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°IllUlVXxlVUêVxkllnÈUVll@Vx²IÞ¤VUlVnIôlÞlwô_bVaĶLXÅÞÇ@K¯@wÛaçn¥¯WXyW¯XwUmmÛ@manómğzxÇK@aUÇLamanUw°@WwnUalnk¥U@aóIÝbUm¯Vmk@@aU@amVğĉ@lUnÿ±UbóKmVÇÞī@ÇVUUwmXkKn@L¯ÇUbyókōè@bn@lÝX@x¯ô@ÆUV_maXm@aóJWxnX@VVnĖVnUJ@nōÆǼV¼kxLklÝw@xx@zV`ÅbmxU±xUnnmknğUbUUb@Å°Üó¼U`Ʋ@lönKnXWlXUx°xnKĊllôw@Vn@lnÈKôx@VÝzV"],"encodeOffsets":[[128262,45940]]}},{"type":"Feature","id":"2206","properties":{"name":"白山市","cp":[127.2217,42.0941],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@Ul¦kÒÆ°IlÒU¤ôz¼lJUnÆXVl°@²aÆbVKČXV¯°¥¯ĉ°WL¥Ģw@xbUx°V°znb@ÈlVlI@w@mU@akU°kUôwWȯVUVUűU@kÈkÑw@laÞġUÞ£@ƅKnÑĢ¯@WaUaVUVkkw@a¯@¯ÝVXnW@@WkXmK@xkKUb@bW@Uw¯mmb@WKUbmUbUaWbJĉIVW@Il±LkmUbUm@nkKWa¯n@`UbmaĉL@bÆ@W`L@n¯Xb@kb@xL@VkL±mlUIU¥mL@lÅx@_la@UaV@kmmK£LmKUnÅKVbmXVlèĉUUbmlĢŤIl¯bǦl@ô¼Ģ@x°l¤nal@xb"],"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ŤJnݤkVÞVVkÈb°y@wkÇ°awƨ@aÞKVnaWwXWkôJ_ČºôVk»óyV£kÑJůlÑk¥Va@wkbmk£¯@wġó»@kÈ¥°akJÆ£ġnkVaĊVkçWUnUaÆLVmnLKU±@m@a¯UbmV¯m@_KUaÅWó¹@UanmWak@@wmI@y@mkJVa@UaIkJ@n@Um±kkxmIkbÇm@°bXnV@°ÈmlÞ¼¯XVº¯LmkWWXLmVVlkn@@lnWÆVxbmnm¯lÝaVÈè@¼VbÆ°ÞUVJkxIxIV¤ÒXxmn"],"encodeOffsets":[[128273,43330]]}},{"type":"Feature","id":"2203","properties":{"name":"四平市","cp":[124.541,43.4894],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@Ɇn°WzlyÞ£mwX@ƾKǬblaÈIƾ¤ôÞĸVĠxnmmV²wVnwÆaU_@yw@wÞxlkKlwU»È»ŎÅ@mVIUmmĕUU@mWXwIô@bWnnbU`V@Å°ó@wÞW@km@aŎç@m°Ñ°Inm±aXaUn@mƑU¦@ǯaU£aUġ¦ÅÒJōUŻókUÇ@¥¯ak¯mUVak@@aċçÅaUm¦Ý`XbÆ@n`IxĊÞōÞml@Ub@Wl_¯JkÇUÝÆÅb@nllUb¯±a@WĉJġĀ¯Unóm¤xôaVnxôI@xV@bmÆ@lnLmÞ¯ÞxVb¯þ"],"encodeOffsets":[[126293,45124]]}},{"type":"Feature","id":"2204","properties":{"name":"辽源市","cp":[125.343,42.7643],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@żôŎVIÆÑĢ¥VbV¤°bÈ@V¥ƒÞ£lÇUUUÝlÞ£mţIlUa@¥nlW¯L¯kÇġ¯ğwWmÅk¯UVUbWlXlmnbUx¯xVVknlUbVÇKUb@VnbmlnzUº±bmJUbWÈ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@awnbl@XLa@Ċ¥@LULnJ@xVnmV@VXXV@VJkn@VÜKXXôJlbxl@IVbnJVLUbnlnVwJVU@XUaUUlwn@°nVKnV°_VJwl@nwlVIXWlIVVnK@IWmkIVaVU@WÈUlmU@UWUalkXġŻ@kI»mmakUmĉUŁV»²ġVĕ@aUU؍IɃ`ȃ@kw@Umwĉ@WķÑIĉÇbÝLkymbIwÇmÛbmbU¯ÜõÈkÆVbŎxnXVÆnǪ¦b¤UxÝnĉÒmĊVȤÈbƼĀÆÆÞźbVVbX°²¤"],"encodeOffsets":[[124786,41102]]}},{"type":"Feature","id":"2113","properties":{"name":"朝阳市","cp":[120.0696,41.4899],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@na@UVI@mÑWkaV¥UI@wl@aÈbm@wVak@@K@k@a@UUmUUalmU@KÇUű¯@±kUKVkUaaU@¥m@@¯k@WLUmkn@mmIkm@amU@wVmkU@Klk@UmaXIWWULaULVbmk@UUmUk±_Uym@mbkImaX¯WWxWKzU@WkJWwkV@Um@UbVVVVXb@VWX@W@Vkb@VnUK±aUUlwXÇWKknU@mmUkLUVVUUVUawbkKmwnIkJ@nmb`kmVkLWwUm@UUUK@UmaUa@UUaWK@mU¯Wkk¯VmUUxVXUVmL¯ymXkWUbmXUKVknWx¯JVnkLl@VVxnxlĀVL²WlXl@bÝVUn@bnlÜaXblIVl@@Ȧ@VmbXV@@xVVnUn@`°@VnXU@K@VV@VmbnVn@ln@bx°Ub@bLV`ÅnW@@lUnnWVU@Vbkl@Xl`XxVUblkX@°¦VUVVbUlkV@UbVbkLUxmJkX@bbxVKÆlXXbnnala@Uk@UVVklKVUXKVU°KVan@VUnLKVLWVaU_@mmUXa@mwXwVkVWXkk@k@klm@wXKl@U@KVUUUVaUV@alLxUx@b°°VnnVxlIXJmxLUVlV@bnX@VbaVx@XJ@bn@VVXÈl@llX@lUVô°°@ÞVbn@Vk@VW"],"encodeOffsets":[[123919,43262]]}},{"type":"Feature","id":"2106","properties":{"name":"丹东市","cp":[124.541,40.4242],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@lzXJU@²x@@V@bUVmKUn°n@lnVKnV@n@VlV°WbXn@VzJ@¦@bkbbUl@bkbJ¯zWULWbklVnb¦VJ@K°Ukl@@WbVn°@Vm²UnX`UÜLXmVXlKVbUVVnUbnX@VUL@lUbWx@²kl`n@Vlb@nUVWVLVU@aV@²bl@ÈmxWXVÈUJVl@laWnXKÈkÈ@Va°bÆm@XV°IVV°UnalVUn@UwVU@@VVJI@bl@XK@wWmXUUVbkJVXnJVI@mknwlKXL@`l@VI@UUaVKÞnaVm@aÇ£XWU@aÇUU@mbkKm£@WWL@@Kk@klUbWKUkUU¯UõÛmUUaVUU@WU_W@kVkJ_WKkV@bUL¯¯±mk¯ġğÑ@UmwKUaka@am¥ÝIUWmk@wmţLKʝbȗKWĢklVbX@VVknÇV@XUVUblJXn@J"],"encodeOffsets":[[126372,40967]]}},{"type":"Feature","id":"2112","properties":{"name":"铁岭市","cp":[124.2773,42.7423],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@XJm@¯mXUlnVbUJU@bV@UJWL@VXLmJVbkXlJXxVL@b@V@n@b@`Vbk@lxknV@VVV@bUL@bV@@bVK@VXLWLXJ@LV@nbWJ@IUVx@LVJUXVxVx@VV@@LXJWL@VU@@L@VnL@bVVmVX@@VVInJmbnLWVnVULVVU@VVmX@@JVzl@nVVKVXÞ@mk_lmUUWV_nJlUÞÑÞVVUVVLUVJ@IVna@@KV@XwWknwnKlalUwaĉÝwJl_@aUaKUUU@WU@WXUÆ@@UVK@n@UnVVblK@bllb@bbW@Xbl@UlnLl°°b¦nKlVnIV@UWU@WXkw@am@nm@aVw@I@KUaVIm±XÑlknJVnVJaX_VaUaVKmwnkmmn@lU@U@mnaXlKUmUIVmklaUK@UlUVUW@UkVma@UUU@JmUU@@bmbKWV¯XUKm@ka@UVKVk@aUKmLkKUUÝUmbXbÇJ@k@WU_@m@klm@UXKVaUI@KWUXaÇWkaWUkWUL±U@lUU@UJI@V¯JmIm@@aU@Uwa@UV@VkIV¯aUkWkb@bVL@@VVVUXW@Ua@@bÝbUVÝ@LmUkVUbVllLUV@LXWbUXm@U`@kxlnnJlbnIllLXlVlUXmVKnV@L"],"encodeOffsets":[[126720,43572]]}},{"type":"Feature","id":"2101","properties":{"name":"沈阳市","cp":[123.1238,42.1216],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@ȚĊÜ°bLlÞxUbUn±@ÈnVÆL@xnLlUVbxkImJkn@V±LUxkV@bbKVKnzVl@L°@VaxÞUlbôxVV@@V±bn@llXLöXĶnal@nkVJVI@aU@@aVK@aUUUU@lmkwl@Ua@_@a@m@U@aUKWwkIlWUanIWK@UXKVIU@@aVVIUamVknW°n@WI@KUmULWnkVkUWKkkmJkamIkmlw@V_n@VWXaW@KVUkKUkValUnVK@ÞVUÞa@a@VbX@VWUU@U@UK@ala@IkKmUUa@U@VkkWVwU_@KÜUXbl@V¥XUVmXakÅlUUkIm`UIUJW@UIKmkm@UUJImmU@VUXU`mIUbUK@LJUUl@X@UbJkU@nm@Uam@@aUmLKwmWXUK@kUaÇa@JUIUa@aKVUUXmUy_@lmbkLUKWLX`n@bVL@JXLWX@Vnb@Vm@UbnVmL@V@x@LUbVV@V@LUVl@mb¯U@xU@UVVV@X@VVblJ@bnVKUnx@llnL±¤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°bUlJ@UVU@bVxV@@bn@nJ°I@UJIVV@V@k²VVKlXXVblÈXWbXV@LVJUbWL@Vkn@l@nV`@X@lÈIWanaÞVVVlLnKVL@bUlUL@Vlbn@VL°WXULna@aV@nV@IVV@VbUnl@VXnKVa@UUnyWkXaaVk@aabnm@_WKXmWanU@alaUl@XJVLVxX@wnKnVlw@V_@a¯¥@UkKWUaUUanK@IaU@WUaVw@klUVyUUVUUÇ@Iôba@mnUma@kXa@UWak@Wal@a@WULmU@U`mIUU`mUk@@UUK±nkJbUam@kwm@@a@UU@Ua@@K@VK@kmKU_UKUUaĉWmkkL@`LnmlkLkbmK@k@Ulmb@b@xUVIUlmVXXxm@JUUk@WUk@akx±@¯x¯UmbKUUVmUU¯UmVVnWkÆlWbUnWVU¦k@WaÛV@LV`UxXllU@@VVbnVlL@J"],"encodeOffsets":[[126754,42992]]}},{"type":"Feature","id":"2114","properties":{"name":"葫芦岛市","cp":[120.1575,40.578],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@ll°XnV@XLVb@VVbnb@VLVV@VVnXxlKnUl_na@mlImJnxlLaxVbUVVUVUKVlnnV@lmXLÈWkxVV²bVLm@Ula@UX@XW@UWaUUUUVan@V@lUXxlIXV@yXLwXXW°nblJnan@Vz`l²nVVVl@nUaVKbVKnXVaUaVUynXK@kVK@X@m@mLXaLWU¯w@a@UVw¥°ó¯¯y¯Uǯ»w¯Im¯ÇUUl¯»ţKċÑţķm¯w@mU_ómk¼VnU`±IkbVlnnU¼±Lk`@XWl¦UbmVUxkXVlkbllUVb@bkVmx@XVV@Jb±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°lVlnXVJLlVnl@zÆxnK@bblKVLn@@VaVLVK@L@Vl@XVVInVVKVwlUXwlKLVVb@aV@XlUXbVW@nlWnXKV@@V@XUVVLUVV@@bVVV@@ln@VbVUXVIxVanJ@UIVWL@UV@@¤V@nInwWklnIVxlnzUVÇJ¦VVÜLĸUnW@aV_WĊXXaKnkl@nmLa@alUVw²K@UlmnIlJwaVUkmK@wÅKmU@DzVmVaÝwkKaÛ¯șĉķ¥ğ¥@kUWkƏīÝ@@akUK@KWIUm¯nU¯JmwUVmIkJÇLm@UImJUU@aW@U@@nUbJabXVWn@UVmX@V@b@l@L@lUb@xnÇabk@@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@@¦VbVbUlVL²l°@ƲÈV@LVknVbVVnnWVU@XmWUabIVa@mV@X@@bVVnIVJ@nÈKlInJVUnx°IV°mVnXJ@LLlV@b@ÞƐĬXllV@Ġ¦ĸ¦naWW@In@manK@UVkXJ@alk@»lU@ÅLUWl_@a²£Kkm@kwVmULm@akIUa@U@WUUVUaÝ@ğwkmĉ£UW@@bÇL@ma@_mKlXUwKLţÓ@UWw@K@UI@mU@UV¥@°UnJ°@@_KUwW@UnaWUmmI@mķwUaÇLóVĵwÝUUW¯¦Ux@Vb@xV°XKWbK@n@nW@UL@lWLmzUVVbUbmWXXWJbn@Vkl@LlVUn@xnV@bln"],"encodeOffsets":[[123694,42391]]}},{"type":"Feature","id":"2103","properties":{"name":"鞍山市","cp":[123.0798,40.6055],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@lxĠÞ@bV@@w°Vna@UkV@K@UUUVa@K@w@UnKmUVan@@Uma@UXWWK@IUK@amW_XKVLlKna@kmKVak@VU@VmU@anIÆan@aUVnb@blLV`ÞLlUbnaKn@naVU@¥°IVK@anUUKVaUVak@mJkXUVwkVUUa°U@W@WlkXWlIXUlJlaxIVVXLll@nLV@lLXlKĊz¥maUlkXaVKX°yIla@aVkala@a@¥IUy@WmXa¯kU@U@mmUULkmm@¯VmnLVU@a@U@±w@VWIkymLUUkJWXJkUmxk@xUI¯`mUULm¯m@kxVVbWV@UVIUx@bkVVVxUbVV@V@zJVXUlnk@@lkLlLUU±Jkm@UIUVLUVU@K@UnnV@l@LlaUJ@zn`@nWlIUVUUUV±Ln@nmL@VUVkLVlUxVLVlÅXma@@akLmWUX@JUnVJVkXJ@X@`WXVUVUIlbW@bVUVL@`Un@¦U`@bUV@z@Jm@@XV`LUL¯J@IVKmKÅI@JnWVnLnVxV¤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@VnlnVVUb@VJ@nnJ@bmXUx@xVbkbkWLUxnl@Ul@xWx@nUV@¼UllknkK@bmbnlLVJX@VIVJn_lJVVXUmnU°VVVUnVVLna°V°w²@lwbl@XVl@VVIn@wWWnUVkJVUw@@anaVk@@lnLlalKnkmK@_lKnlĊXVbVVLV`nL@lUL@@L@VbV@@V@bn@lxn@VbalI²mVL@Vl@nV_VVnJV_@nVKV@X@bkXbl@XblylUUk@Xa@UVIlK@UUWVULlm@UUUnKWU@K@UXmXVa@U°KVUUWUk@aUVKkaWkKUknaWa@U@m@mk@aUJk@@_WKkLmxl@nUJmIUWlIUaVWVXn@xWLk@@aJUI@U@UVVxm@UVkmb¯VUU¯JWU@Ån¯aUbÇ@ÇlLmWXkbk@UIÇVUXWwÇnk@±aU@@bUVUKUXmV@kaUm@k_±l@XwVa@kVK@UWmVaUmVUUakLUWWnÛKVW_m±VnU¯@Uma@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ô@xXbwnKl@nX@VUVKmL@VU@UxÝ@VlbxU@VUb@bk`IUlVUnV@@UV@@JnXlK@b@nbÆWUkUKVwUklKVU@UnK@mm²KVUVVVUJXk@mm_@yVIbk@K@kmUm@VLV@VUKVUVJn@l²IVVKklK@kl@kmVUWI@y@UUUVawUUUl@akmmVaUKmIUaJk@wkaóIWWÛL@UlmUIU@WW@UnUUm@wmIVK@Kĉ¦@bWKk@max@bWXkamK@mVkKmxÛaWX@xUlÝnJ"],"encodeOffsets":[[124786,41102]]}},{"type":"Feature","id":"2110","properties":{"name":"辽阳市","cp":[123.4094,41.1383],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@`VzWnVUVL@bVbVJ@IÈbVb@lVLXWnxLnKVb@n@Vbn@mV@lIVa@@WkVVI@KVLVanJV_VWUV@nnJVIVn@na@alLlmkVk@»VU@mXwwk@@VmkVwXKllaUa@wVwnW@amI@mUI@VaUUkmm@UkaL@UIĉyLWkkKU@mKk@kWKUUJwkbkIWVkJWXkl@X@X¯VVbUVlUxVWlnI@lUbVUbVLmV@bUL¯J@¦UVmbm@LmbakVÝKU_kK@amaVUbm@ÅbmJ@bVUn@UVl@UbnL"],"encodeOffsets":[[125562,42194]]}},{"type":"Feature","id":"2111","properties":{"name":"盘锦市","cp":[121.9482,41.0449],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@Vbĸx@nnJVnXmb@VXVxL@`¯@mI¯V@U¦@VV@nJ@V@LXx@VŤÔKLVxWknL@`b@nÈK@a@VXĊ¤nVK@aVU@UnU@ayU£UwmmKXUm@IÆJnLUL@J°IVKKU_@Wn@@I@yVU@aV_@¥Vm@_UKUV@aXkaVJVUUXW@_@WWIUlUIVm@IVW@IU@@VU@mUVVkJ_l@aVa@UVwka@UÞVwV@@UnKLVU@UmWk@mLxWa@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@Łkklô@£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ÒÈɆôƐŰǀĊ°ÆǬĮƾbyĊ@ĠƒXǀċm»ôw°Ûk¥Çm¯çkkÇǫţǕéX_ĶWǖīŎaÆĵĸĊ@ȚȘĊLĢĉVÆĉʊÇĕóaU¥ĉ°mkÅ°ġUĠřk°mÑČÿÛƒWĸ£ʠÆxÈÞŎÞ»ʈ²ĊÇČalÒ°Ť±ĸzĊKȲm¤Ŏ@Ò°¼nyȂUźīǖƳÈē°@ÝĶ@Èkl¥ÇçkxkJXÇ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£ÇbyVÅČÇV»ÝU¯KĉýǕċţnġ¯»ÇōUm»ğÑwƏbċÇÅċwˋÈÛÿʉÑ°Łkw@óÇ»ĉw¥VÑŹUmW»ğğljVÿŤÅźī@ř¯ğnõƐ@ÞÅnŁVljóJwĊÑkĕÝw¯nk¥ŏaó¦ĉV¦Å`ğÑÑÝ@mwn¯m±@óƒÛKˍƏǓ±UÝa¯lōșkèĬÞn@ŤġŰk°ċx@ĉ`Ƨĕ°@ţÒĉwmĉ@na¥ķ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ôbkV@ôlbnĊyÈzVôab@ĸÞUl°yǬ²Ǭm°k±lbn°@È»JXVŎÑÆJ@kLÆl²Ġ²ʊůĊġřóƛÞÅ@mmLUÿóĉƧ@»L@`ČĸmȗÑţů±ĉğl¯ĀwÇçƧŤÛI@±ÜĉǓçō°UwôǫůķƳűbÅ£ÓÇwnÑó@ȁƽ@ÇƧĢón»ŏĕóĊ¯bÅVȯÅImōKULǓ±Ý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Åķ¥ˋVbUÒġ»ÅxğLƧbWĖÅx¦U°ÝVóŰlô²@¥ÜÞÛôV@²±`¦¯Ý@ÅVÒō¼ô¤V²ŹĬÇĊƑţxç¯Lk»ʟlƽýmłÝÆƏ@mö°Ġ@ŚŹĬţÆUĀĠNJĠX¼nźVUÒ¦Ċxȼ@ôlx¯łʊÒÜĀˌÇČxÆČÈƐaxÒĠn¼ŎVȼĢ°ŤmǖČĊþLV°ÞU¼ċÈUÆzÈa¤ôbknXĀè"],"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ĉzmkaóU@laóķ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ĉVwXĠÝ°Čÿĸ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»ôÇÑ°a@ŹkġKţóbŹ¦ƽȂóW¤¯bĬ̻ŎW°ÅÈl¼ţ¤ĉI°ōÒ@¼±¦Å@Uġ¦ʟƽ¼ÞĢÒm¤êō°¦Èþlk¼ĊŰ°JĢńȁĬ°żnÇbVݼ@¼óĸţ¤@°Ånl"],"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Ý»ÅVlÅôÑġğVmÞnnWçkWÜXƝÆwU»Șĕ£ĉÑğ±±ÅkK@lÅIōÒUWIǼ¯@mka²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īѯmwk¯Ç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@VLaÞbn@@l@bUVlUVzVx¤kÞVèXn@nm°a@UÑ@VXnV@VaUVKUUU@@U@@KVa@U²@wXkWnk±lLnU@UmmVKnIVWnI@UK@UK@@UVKXkmWLWUXmlkVwUyVa@ww@aVIK@aVÈwKlLVV@LnVVVnUܲ°WÈIUÆ@nÞ¼@¦@UÞUVW@UxUxVnbKb¯ÞU`VbǬV@XXÆVVl°InmnUô°¯anam£WVXKXmkôaVU@Vak@@wman@K@UÛUWKXUÇ@UIb@alW@akLUKV@@Ukw±InL@kmwkWmk@JUIůVmnnU@m@UKVKlkUwknVUKmbkI±KkmVkKb@U@aVkUmn`kIlaUK@UUKmbUIÝUa@mUa@am@UUULUK@bmKkbWI@WXwlkXWa@k@kKLVkkK@L@JUVmzUKlwUUnW£XVlKUwVU@aXI@aWaUw@W@_nam@¯UkWVkUWaU@nwmJkUVkWVUmUkJ@ImbUa@@WÅ_mJknmak@@mXaUV@xU@@VUnkV@Vn@`ULUbWLXVW@kbUJ@XW`@nÅĖWJ@m°@xxbnUaw²lÞ°xŤIVVULÛWbbkVVXÆ`UbVL@kx°LlV@VWbJn@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¯UVKk£@amIXa@UkU¯Klw@UKVaÅ_UWlUaXaÜVKUUţJ¯wݱkxVbmaw@wn¯@XIÆĕm@X_@WVIlaX@WUXKVaVK@_Um@lUVm@U@Vw@VUÛwm@@W@ImKUkU@UaaX@wWaUKkw@UVaUamLUnk@»±`¯@kW@UaykbI@VWJkLWUkJwU@n¤mL¯wm@Um²XVWbnV@bmxVkxUblLUV@kVWKU¼kU@mn@JnV@bUnmJUn@k@XlxLVVnKlLVV@@LkKULVbk`WL@lkXW@kV@UÞUlÇXlkaUbmV¯@@L@V@bkb@xlWbbW@±@UJ@IU@mVkVxV@@lIlln@Vm@VUbl@JLmKÛXmVkUKULU`@LĉwKUXlVUl@VbJX¦̼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@UJlazVbX@l°@²_@¼mlVnKVbUb@VlxVLXb@xWbVbV@VlnL@J@Xn@ÜxbW@nl@nblmnIÆ`@X@Vbna@aVUUWVk@kbWakbU@VwW@_l@nmn@@alVlk@UkmVak@@aUXaL@¯@KVa@axWI@KnkVaVJn_lJ@X@m@nVanUVb@mXLlJVWnLlaVVaVX@KXVVkVKlknKVa@aVU@KXb@klJUknUm@K@_UW@alIUamaU¯kJma@IUK@U@@UW@@aXLVVJVaXIKlaUkUV@ambUUJkIWJ@wUIV@JU@UwV@@Um@nU`@UkUmVUxWUUV@aÅb@aWXkKUUUUaWK@wnm@IVU@aXwm@UmVaUalk@anKUwlUwlkK@wmaUkmmIk@VmkUUbW@UVUnW@kV@xkVmbVnU@UbUV@ak@kkW@kLW¤@nV@VU@W_UVUU`VLUV@IUVõVULU@UUUJ@wmkUJ@WI@l@bkKkbVVbVbUL@UUJ@Vm@@L@xbVVVLVlVwX@Vb@bmUkbk@@JWIUVÅw@Km@UkWKXxWLÅ@UVUnWK@xkVW@KULwWVXVWzXVVKVXkVV@VUbV@UVV@@LXxVL@VbLnKVLVxXVmb@l"],["@@@J@aU@LWK¯UUxVVn@ĠLUW@UbUUUa@KUX"]],"encodeOffsets":[[[108023,37052]],[[108541,36299]]]}},{"type":"Feature","id":"6401","properties":{"name":"银川市","cp":[106.3586,38.1775],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@UwVK@UVWÞUbwV@knV@@KU_VK@Kn@W_XWlL@Vn@Ċw@Ula@Wanamī@a»ŋó@aÆÅɲÿUaV_°ÝaLaUmVwVwX@VUVÝ@@¥Ý»@mVÅÇJ¯XÛ±VUmUmU@KUUkKLÇxU@bLUJ@bx@xUbVzUxklWnXVKnXWlUL@V@VL@VL@mJUXmJULnn@VmVkK²mlXWlx±@@VUb@L@@VV@VVULVUbU@WmU@Ò@V¯bmn@V@lVnUnVWXVl@¦VVUn@x@XL@¦lXxVb"],"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@lUxaÝVUX@VULxVkLWV@JnVLXVlUV@zlVL@V@bn@lU²WVLlLVbUVxUx@xǀLxôÒkK²VaU@wXa@WÈĉUa@bÈkm@¯"],"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£°@laXô±źwô@UlżaÜnKw@Uaa²LmÈLÆÈxlaUawÞmÜbÞUnJ°akôÑkwÝVğwÇ@ÝkkV¯¥@ò»nŤ¥XImw@mVwa@ÅwmLkaWw¥l»kçó»@WÑĉğ@ĉŃUwóřVómĵ»Ý@VǕ¯kÝĊÅk°ÓUklkU±IÇÞk±@ƽJ@UġIk@W¦VÑșÓÅnťKULn¯X@¯mUÛ@WÅmóKknōbxÝ@U@kw@ÿÇLţÝUkmwklċVÅU¦LkUWlÅÑ@a@ÅѱUóġŹ¼ÈĉmŻ@@wkwKl¯Uġ@lÇUÓ¯_Waĉ²Åló¼VbknKÇÅ@ƧĢō°Ý@ğWÅxUUm@ÝXÛWULUè¯@mbUaLbUWġxIUJWza¯by@ōÈóLU`ÇXUlUĉV¯nmÛbǕLklUĉVóaġƏbġKţnkbÝmmnÝWȭÈÝXţWókUÇl¯U¯ġUɅĀ@°¯¯VÆnmJ@ĊķnóJUbÝXUlVkL@lVxnnmb@¤Vz`ÞÞŤ@VnÆJV°bUôJkzlkl@²ó@ÆÇ°kĖÇbÛU@lmbXVkzVɅĀXˢlńĬŹ@éÅ@ĉńÆ°ğbUlɜ_°@xŦkbVbƒKĢŤVŎ°@żÈźlĊôKôb@nôxŦÆ@ôŎL@þÆb@nnWˌbÈxInaŎxlU@Ѳ±ğVUĢƨbɲ@Þ¥ôUUķWVô¯ĊWʶnôaŤˁ@£nmnIôǪK°xUXô@Ŧa°mkXÆÞVŎkĊ°ÞLÈôyVaIlwX°UVwĢÑÜKôw@nV@m°nmnÜɞ£VbmXn°ÜÒ@xx@Vb²UlbkxVnJUnVVĊ°KČm°nxÇnn¤±¦@UXVV@lVbmVVÈVxÒ°IbźaČbVw@VLƾÑ@Ŧô¯ĊkôÑ"],["@@@@nòVaw²bVxxÜaČVô_ĊJIVmLa°@Ŏ¥XlK@klKVbUb@nUĢnaÈ@lmǬ»Ġ¯nmnƨVyÑǖĠ»ɲIn@@ÅĢƳ@¯°ôVKÈbVIÇ¥¯@Ýó@ÑnīWKkk@¥¯ÅaX±VÅw@±Ġ¯@»nWmw@@¯VUUWçKĉa±VkkV¯wx@UJx@bknÇbmÅ@Uw±U¯¦UKm¯I¯ť¼ğĊ@ÇŹÈ¯@Ý»ÇnˡJbÛèÇnÅK¯ġĠŹW¼Ålm@¤n²Ýb@b¯l¯@ŤW¼nV@x°@Vx@lbUblbX¼WDzlU@¼V¦@bÇlVxUbVxÞbVbm¦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ĊUVlkǖKÜan°mĊUVVkÈWV_ôKŎÇ@z°abXyVIJĢwVXaKVbna°@VçVKXÜÞWn@VVÆwXĠÞ@Ŏ¯ƨġÆ@ÈLlmUaô»ÆkĊ±Xb°`ÔVkÈĢ@Vk°Llx@xż@ĊnÇź»ôĢ²VÆÒ@@bÆÒXklVKV¥ÆČUklnxlç¥ċç@±m¥wÅJ@VmÈIléÈa°U¥@kÞVK²ÑW°w²ÑK²ñyÆÝVmw»kkWĉJWUVÅwLmÅ@@mwkn¥VÑ»°°@@»¯LlaJônVUůU@W¯Umѯ¯k@WykU@¯wV¥kVwţk»wWÇĉĶçKÞÇaĉbIlU@kwWXU°w±@UKn£WĉKWxkĕVamwXw@Wmnk@aVkbĉLlImmwUÇWxnÝJn@¥ÆkwaXÜĉ¯ÅV¯¤mkx¯kķܲVWôŹVU@V£¥@°wn@m@¯@UbUôķmn@ÆÛ@ÇýVaUÇĊV@Çlğ¯xÝŤlVÈÈVx¤VxkK@@x@kVĖġ¥kIWbXŎx@nxÅUW`_@±UaLUxK¯WbkVlbbmLÛÆWIUwWkwÝV@kIéUbUUkV¯Km¯k@Umݯm¯mLÞĉÛUmġ£UxkKm°Lwk@kVmKVUk@¯a¯ĢmóKUUxImlÅnÇbXèVVU°@@xXnm@¼ğ°@²ÆxU²WÆb°@¦llXLmĬ@ÒÞô°@ȦUJÇaLóU¯@°ġƴ@Æ@mɱJğ¼ǕÒUzƧmnmğ°ǫ¼knÇ@bġmmV@VaUaLkl@kLWō¦¯@bKUnJĉIó`ċUÛbwUw±axbñUm@@babÇÅXmƒÝÅôVbÞblUÞVÞU°VUx@UV@l`¼nL@ĊLW¤kXķWġXUVVVķUbVb@°kVVxÈa@ȦĊbaźJU@ÈVl@XkôaWĢÞ@laĸUÆb²mÞLĠÞÑôbÒĊaJVbm¦"],"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ôLnXÆÜ@nV°@°WmVKŦLÆmȚÔÒUX¥l@ĢJV@ƾI@wW°Ån¥kÅÝVwôÈç@lÑĊĕaJnaÆLVw°kny°UnkÆVČĊll¦Vƾ@@nUźÈÇIn°XwÞKô¦VWV£@£°ókċ±Iam¯Va»ČĉV¥°@mk¥l@Ċm@aUmwX@wÆxmĢ_`VnÆbKVw@@nUVğVmVVöIll@@çÛm£UÇw°@VU¯»m¯JōĖÅLa@»ĉĢ±`U_k`ÇçókXlK@akÝÞ£WċkÝkxJݯÅwxķxmIÅx@k±J@ýŋ¤UkmV°ÅÝxkwmġnÝVU¦ŤlmóXk¤UKç@mVkK@klī£m¯VUbW¯¼ċb¯ĵam¼mVXm@k¤ÇXÇbU¯J¯¯È@bVXVÒ¤V¼kxÝV@lVWxÛ¦W¯mKnlkU@nƑUĉÝ@ǺÛċUĉ¥UÞÅz±òL±Ò¯xX±ÒLÝU@lV¦¯ÇbkêÇJnU@ÆIxn¦@²Čè¦è"],"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°UXbVȂǵé@kWanm°@xzK°¯ĠVVkwLnm°kÞxÆa¥@wnĉÆ@_l_VwmĸèŤÅČU@Wn@ÑmKUnğK@°¯UÿV£nmLlUUÛé±óókkmnakV@Ç°óÝXWəÞťIţxmmVÛUVȂÓnWyȁĉkV°WnkĊa¥_K°ÿWna@mU¯wlÝIU¤UXó¥ÝLx¯WmJÇÈŹmV@ƽ@Uk¥ĉkċÅUml¯Vmz¯lUxÅKmbIbĉĖkÒ@ÇèóUxÆÞlm¦Æ¯X@x@²ÝlÈJV²klVl¯ÔlĉÆÞ°lUǖÞ@Ķ¼nUôôŚ"],"encodeOffsets":[[101712,37632]]}},{"type":"Feature","id":"6322","properties":{"name":"海北藏族自治州","cp":[100.3711,37.9138],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@ōmġxƽUm±LǿþġÔ@kxmWb¯I¯mIUx@bbŹVÇkĵblĉI¯¥Um@ƯÈ@aóUlČ»@w»wXaó°ţçÝkUaV¥ÅbÝw¯lmnKlxUğU¯°Lyw¯@mnXbl@êȁǶUWa¯VÝUğ¤ǫkÅ@mܹXVV@K@ma¯¤ÝnƽĖ¯V@¼ôlèk¼¦xXlbnKÆx@bUx@nnxWJţ¦m¼ñ@°¦lUÞlÈ@ĠxÞUlxÒól¯bmIÝVÛaÝnxVbkbÇwÅÇKn±Kbb@VxLmÛŻbkVó@Źxó²Wkb@¯U¤źĊ@lUX°lÆôUlLXaV°wxUb°xÜôÈKVkÈmlwkÈKwKVUŤĉŎ»»Il¥na°LV»²¯Üy@wĢ°ĸwlwĢw°±_lVk@°bƯz@l_@Ģ±lÅVlUaÞLVnKlnÈ°IllČawÞÑ°xUU@wVkmĠLô»KÞýôaÞ¥ôĀÞmÆmUŎV¥Èl°²°a²¥V@@wamm@Ñ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²ôÜêVVkKmnU¤VĀ¯°@LmĠVnLÈL@alb@al@n°V_XmWUÈamaVIn@naV£óVWU£°axÈ¥@aĊwȹ@óağbm@kw@maÆw@In¯mm@UkkWÑÅ@@kċÅçVkÝJÅkVykŹl¥@¯ĢUÜX¥òýmmXÝÅlmU@£WlyXW»Åbl@aI»k@klm@UxUUV¼¯XlaUnķI@x@¯KĉUU`ólČ¯ô@¤ÞJk°xVn@mbX¯ĀL`¦ĉbml¯XUlȂĊXzmȁÔUÜVUnnŤwŦJɚÝXÞW¯ô@ÈlUbmln"],"encodeOffsets":[[103984,36344]]}},{"type":"Feature","id":"6321","properties":{"name":"海东地区","cp":[102.3706,36.2988],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@@Òb¤ÆI°ôU¼°UnnWx@b¯L@lUUWbXxWlƨnxVUllXVUnL@lȀý²KVnƾĢwV»@mÞ£nÆÞÑmLKUaVżĕWVk²ÆÝ@Xw°@ô@a°wóUUmIkaVmÞwmkny¹VÿƧnÅm£X»naV±Ýw@ab@am¯ĉVó¦kÝWKUU@WanUb@ôǺĉxb@Ǧw¯bV¤UXôU¤bmm@UJnbÇbXVWn`¯Umk@@bka@bÇK"],"encodeOffsets":[[104108,37030]]}},{"type":"Feature","id":"6301","properties":{"name":"西宁市","cp":[101.4038,36.8207],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@@kmKVUWkVkUmwƧXkWwXaVV@k°K@aXwmmV¯V»¯óÅJ£amX@ċVţÆķçnUx`k`@ÅmĊx@¦U¦blVÞŤèô¯Wbx¼@xċ¼kVôbÇ@Å°@nV°¦ĊJkĶalÈźUa@aVwnJ°°JanXlw@ĢÓ"],"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ÕpnñÂ|ěÔe`² nZzZ~V|B^IpUbU{bs\\a\\OvQKªsMň£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@RCPbAvMtBfH@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_IAHKAEXCQUOQCUDEN@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@CFDVPRRVWDFLBBG`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":["@@ŤLLllVń²è°xżĢĠÆlÒŤbV¤ĊXnlĢVĊÒÈ°ĊŰÞèL±@џn»VUźċ²»ÆkôVɆkĊŃ²kŤVVwUUVmUa@KkU@mUmmk@UwUkmW@UVIXa@mw@aKULax@Uk@UbWU@yULmK¯@kXVUwm@@JUUknWKUVLUbU@wWykIa@w@mUI@aUVynIWak@@Wbl@@knmK@wnIl°Kna@V¥ğ@ġUķ»¥@UōJX¯¤k@wmI¯k@mwak@@lX@bUJ@VbknWxkLkxlLVlkLmb@bU@bU@VbU`Vb@nL@mbU@VnUVmnU@mm@kIUWVIUKVkkUJUnmL@VmLUaVWaXamU@U@KUUmVUJUVÇwğnm@mXĉV@l¯xnô"],"encodeOffsets":[[122446,38042]]}},{"type":"Feature","id":"3713","properties":{"name":"临沂市","cp":[118.3118,35.2936],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@bXll@zlV@lXXmkbVVlU@Vn@@Vmb@XKVXWJ@XXl@ÈbVLUl`@XXV@VVUxVbUxVb¦@WnXVJ@bnVUzl@°ÆxUKlU@mUUnUlUVWVUnVV@XX°V@Vll@VkaXVl@Ux@bmbXLlKlb@b@bUJn@@b@n°x°K@an@@UlLVKVbXb@bVVnK°LVa@UVa@XwKVxnLU°@naV@UWUkWULmVwÝKUUla@aó_@mK@aUU@WUkwVm@aVI°W@@IUw@a±¯@¥kUVUm@awkw@K@kVKk@maXalI@alLWXblaVLVUV@LnK@l@waXaLlnUlLmV@n°J@_VmnIVym£UKmI@WnIVm@anUVmÇ_kġIÅWUXÇm@U@ݯÅ@@naWIVW@IkK@klKn@naWImk@abkKkLWnWkLWmk_@UaVUKmLUw@mn£WwUmUaóV@UkUm@UKULUwmJUX@WW@XÒzVblJXWXk@UVWKX¤UL@xU@@VUaU@@XmVkLmWkXUyÝLmKXnV@n@lx@bWLnVVn`knULmxUlWLXVb@VK@z¯x¯¼WxKUn@bk@lVVVz"],"encodeOffsets":[[120241,36119]]}},{"type":"Feature","id":"3707","properties":{"name":"潍坊市","cp":[119.0918,36.524],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@l@@UK@@L@bX@@VlL@JLUVnX@`ÜXn`V²mJ@bU@@nb@l°xnnĸVÆ°@Ċ£Þ@lWnÑnkʶJmó°w@kk»V@»¥k@V@kw@wVmaÅmaô£ŎXI@mlnKla@mV_UK@kUkw@alWIU»m@WUIl±UUÅUbkJ@a@wUKUaVIÆmXIWaka@m@Ul£XKVw@UIJUkmJVkU@aWKImV@UxmL@bX`WXU@U`ÇkUak@@°UblXkmLUKmL@VULóVk@@Vlbn@Ub@ċaUJUbIUlVLUVVbVKXVlVXU@mb¯@VmKUwLWx@Ub@VUb¯KmLUU@aWaUaULkK@Vm@@b¯L¯w@ma@m@UUU@U¦lJUXVmkb@nmXVWkbIVxUV@VUbWLXVLW`Ux@nk@Vn@x@VkJ@V`mXk@VxV@lVI@VULVUIV`°bVXXxV@VWVnL@xVUb"],"encodeOffsets":[[121332,37840]]}},{"type":"Feature","id":"3702","properties":{"name":"青岛市","cp":[120.4651,36.3373],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@@nUJXL@blVUnIVlIVJ@UxWLk¤@V@nlbXbWJÅnUJVbVL@x@blIaÆVVVk²VJ@XnV¼JkX@blxlV@VLU`@nkbLkm@nWJōó¤bnÆbUn@xlxU@l@¦@¼Ul¼ĊUnW@nĠmÈxUVIVnUVV@LV@nVWbXbUVbnK@UnKVmVIllUVLUJVXlJ@nnV@nmVUUm@Vna@K@mUaV_UaV@aV@@aanlKUkKklwlKXwlma@UVI@akW@l@bnxl@°nJxl@°£WŎIUÑn»lamô¹Ŏ¥VaUUkmkġWɱIUUŹ`@kk@ĉƨřV¥_Ç@Ĭ¤ÝL¯m¯£ƽóķwUW±ī¯kōaĉĕkğmó°bW@UKkLUaVmz@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@wnmwmKXaWaXI@UV@Vy²blkVKkamU@kb@Um@VmUkmKmkXKWwkU@Ul@UnK@UVUUmKXwUVLwKU@@Wl@@wUkV¥@@I@W@_V@VWUw@UUa@aaWa@@_mKUwl¯amzmV@WKnU@kWLķaUKbÝVmV@UWÇbÛ@X°UbW@XmVlk²UJUbmLÇxÅWUzl¯Ll@VkKXUbWJ@bU@¯@kbLmKka@l_WXºVbUz@Jn²V@¤lXnV°Ln`WbXLôVlKVUxXnlXLlU@bVV@XJWLUVnVV@@nl°nnVKÈbVXÆJU°VnXVkV@@xVL@Wlb"],"encodeOffsets":[[118654,36726]]}},{"type":"Feature","id":"3708","properties":{"name":"济宁市","cp":[116.8286,35.3375],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@nam_nKlVLXaIl`_@KVVXI@m@w@@k@Knô@n`VbV@@LL@KVVn@VX@VLJl@VUUU@Uam@UkwKWaXamkJmIUVUÈblaUnV@kVKl@@lXL°kVJ@VÈnVJUX@VLXl@xVLnU@VKV@aIUaV@bĊUxKkVJXUlVUVaI@WUI@KlUnwmWk@WXIWUL@Wna@Um@@UVkUUlanWW@kkU@ykWkaWVUlÝbUU@kJUIU@@JmaókLKÇUUkKWLk@WbkUUabmKn¯°¥V@XwV@VanaVaU_@Wlk@WÈ@VUÈVVÛmaklKȯlLVUX@lK@aX@@kV@VmV@VwnJV_UWUwXam@kW@wVUkKVIUUVmU@UV@IVK@aUL@aV@LmUKmx@ômLkUWJ@nXmlUxUL@VknVUU@VL`Ub±LkV@kUKÇbÛ@UWó_mJ@Wk@@X@VLxUKVWxLVnUV@VmL@Vk@VlVXxWLnlLnVlUnn@@VlaV@nlbULkl±aUzU@@VWJXbWbnLnxm@xUmJUUU@@VmLUl@VUÞVLUV@bllUn@VUXm@@VkV@VݼÇnUVJ@¦nnlnVlL@Þb°KVV"],"encodeOffsets":[[118834,36844]]}},{"type":"Feature","id":"3714","properties":{"name":"德州市","cp":[116.6858,37.2107],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@¤@VmbVXnVVbVJX@ll@zlVInl@@bVxUbĠl@ÈblaIxXVWb@L@nULWVXXWWLnL@`@LUVVL@lVnJU@UUkanVôôb°¼VÞXIÜbČabôWXÞWÈzÆmnLVJ°ÈnlV²lbnW@@UUVmnwmkkKWkla@mVIUKUaaUwmnJU@@amIk@@bVlkX@mmUklUUa@_UaUUV@wwWkXmW@I@WUaÝU@UXaWUU@UUVW@UUUWUn¥nUVa@m@k@alU@wkLWa@UUm@@wnmUwla@anKn_@alK@Ý_@@WUUUmlkaIyU@UwU_Wa¯yU_mWUwkImm@InWWUk@@UVWVkW¯U@VL@b¯b@l±¦@VV@lUbV@kxVnUl¼XV@b@lV@nIWxnb@UULxÅxm¯aUwU@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@`bVkVlnV@nlWUk@al@nJ@bV@InmVxbVbVLUJ@nkblXlLnlmxnUV@V@mXnlbĸ@nnVxb@lnXV@UJ@nVxxnxVbÆVn¯ƒĕ@@wÈçUÇlķVIb@Çmk@¥k@UkUK@aWakUóJW_UW@wkkWK@U@K@XUUkmUUalKXala@U@kkWlkÈl@kVmVIVmU_awnwVW@wwU@wU£wkJWIyUI±bkVUJ@nmVUklXmx@lnbWkVUkLWxkKUUmUkbJ±LÇxUKmkUmkkWamUaVkJÆ_²KĠ@UW@wU¥nUWwK@aÝUkÅVaVK@akLW¯I@bnbVx¯JWñWbUL@nV@VmbkUUV@IÇak@@bWak@WJUJWL@bXV@@VJlb@zUlUUImnbVmz@°UV@VbV@@V@L@xLmKUnmJVXJ@VkLW@UVUL@b"],"encodeOffsets":[[120083,38442]]}},{"type":"Feature","id":"3715","properties":{"name":"聊城市","cp":[115.9167,36.4032],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@ô@VWnLan@VKÞLÆUnVV@xVbn°ÆwwKVV@maXwmJU@@k@aWUk»VUmlw@UVa@kUU@²¥@k°a@aK@UU@mmm@ówѱ¥¯@@wKmwI¥kU¯UmakJmIUaVkKUkm@VUUaU@UaKUK¯@wUVUIUKVwk¥wbV@xn@lWnXxlL@`XlJX¦l°XxW¦@¦Uln@@@Um@@VXVmx@¯bllUnUJ@VULVn@bxVVL@bVlnVVblVÈnVlIVJLôlJ@xl²"],"encodeOffsets":[[118542,37801]]}},{"type":"Feature","id":"3705","properties":{"name":"东营市","cp":[118.7073,37.5513],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@ͬUǪlô@°Uw°ōĠ¯»Ģç»XÇ@wwƑaÇkwVƑ¯@ÅķUmm¯w@ka@mV@@anIU±m_ÛW@_mWVUK@IkK@UW@@a@K@L@Vk@±U@UV@lm@mUU@kLmxV¤@xVx@xUXmxxbV`UnUJnU@lÇkkllX@l@VkbWbkLVbnVVlWV@@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°VlXUUX@Vl@XVmX@JnnlJVxnXV`°zXbV`VxV@zJlbkVnVV@X@`@ÞkL@bm`mL@bkbxnVm@xn@VV@XbKl@xkV@b@l@nUbmVm¦XVVV@VUXVVV@XVWb@VÞVVb@X@JnXlWXx@xUVV@aVKVUX@lK@UIUWnIVmnLK@w@K@UU@a@UVU@¯nyUmanVJVVk@ykaIU@@WU@aXKIVXIl@Xb@al@Èb@JVUlVna@UmU@VKXaòX°IUwma@aU@UU@wVW@Ñw@aI±`kbUkwUmJ@UkmÇUUkmKknUV@mJUkaWka@KmKkULmyXa¯_@WmImmbLmUkVUbUVJbUkkWJkUlIUmkLlK@knaVmkI@mWaLUKUU@@VmLUVLWK@UUUWUkkVmx@Vl¦"],"encodeOffsets":[[119014,37041]]}},{"type":"Feature","id":"3709","properties":{"name":"泰安市","cp":[117.0264,36.0516],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@n¼WnxL@x°@¥Uk@nwlUVlXVV@VXLKVUnK@UV@VVLKXb@nlJUnmb@lkLKlVnJklVXIllVaIVUValUnVKannnJ@X°`WbnzKlVnL@LbXlbVlnI@VUU@UmV@U@U¥@VmV@@_Ua@m°@@kmUUm@UVmn@nX@@aanJVUVLmlIVJn@nkVLVa@KVmVLXVVL@@U°bn@VaV@@K@aVkbWaXUVymU@aUImWX@¥UaVwUaVwUUU@WW@k_VUKÇa@nmxkV@LVJ@XJUbVkUWVUIlLwĉVaU@VbJ@bUUL@mVUK@wWkK@UVWUIÇm@UUI¯lWK@kk@UL@lmUVkbÇaUVVnJlInWbXbLxVln@VbV@VUV@kIUK@UWm@UU@LK@KU@Uam_ó@m@L@l@@x@nWJUU@L`k_JWbUKkmLn`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ł̥Uwm¥kÝmkkKóbÝ@U¦@mb¯LkmJ@xLmn@lk@a@X@lXbmJUzV@bVJ@n@xblJXzxV@VaKVUXLlmVV@In@VxUlW°@nLVK@zXVVal@@VwbVKL@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":["@@UaVUUKVkJVaVIČb@Vam@ka@Ul@UôVK@UnKVLnKlkWVa@¯l@VbÈlV_V@XWW_@anKVwUmVw@@UnyUVblKVLX@aô¯ó¥mÛĊÿÈ¥Þ¹lUī¯Kĉ¼ʟbÇVUUXmakJUnmV@bUnmJ@XnJVLn¤UzmJUn@`¯ImU@nKVkkmKWbb@xk@mL@KUUVUKkbWaXkK@bkJWbnbl@UL@lL@lxx@bnUVlV@¦²°@bVx@J@¯XUJ@bUnlxVX@VV@bL@nô`@bkbVVÞLxnU"],"encodeOffsets":[[121883,36895]]}},{"type":"Feature","id":"3703","properties":{"name":"淄博市","cp":[118.0371,36.6064],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@nlKV@nVn@@kVU@²VVaU@wmKXU@UUWwUW¯aU_JUVVK@UJU@kUw@UlnWU_@lI@U@wUml@@mVwX_KWUXKVa@UVUUwJlaXWUn@mlanUVWkIV¥V@VVVI@a@akakLWKna@aVwk@WUbUlk@k@U¯UWWU@mUUVUXkVmVVV@nkVLVÅw¯k@WVXbaUl@bV@@b@xkVVXVxkJ@nk@@VLUlVbVXUVVUzVLVbUbVVWVkLmkJ@n±@UxUVVkV@bx@ÒUX@xVVV@°JXlK@bULUblÆÞV@bLXxmV¦V@xXVğ@±LÅ`IUlVbnbXllVnnlVLÈwK²IlanVVVlLwXlKVlUXma@knwWlkVnU@mVIUl²aVJzXJlI"],"encodeOffsets":[[121129,37891]]}},{"type":"Feature","id":"3704","properties":{"name":"枣庄市","cp":[117.323,34.8926],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@yUUUkl@@aVmLXw°»°w@yL@UUaWXKVknwVKlm_UmmUXK@aw@k@mUWmUL@@@£@KbÝV@akwaULmbUKLUU@lm@°mL@nUJVxVXU`mIUxU@UnU@@lW@@bkLW@UVkKÇ°kLlbnUÜÇUUVÇ@@Xkl@XV`UbmbUbU@WxU@¯¦m°nLaVblVXal@XKlLVVÈLKôlnbI@V@VJI@lVVÞaVkXU"],"encodeOffsets":[[120241,36119]]}},{"type":"Feature","id":"3712","properties":{"name":"莱芜市","cp":[117.6526,36.2714],"childNum":1},"geometry":{"type":"Polygon","coordinates":["@@lmnLVlÈVln@VnIVlxVla²_JlUUUVVw²@@mlInlKXUUUVaUaKUVyUUWVUUaVkUK@l@@mlIUwUWlU@w@aU@@LU@Ubm@¯a@V@UKWUUKUn@LUbUKmlm@UIkJnUKUVmIb@b@mWm@Un@VVnnVl@¯@@nVb@`U@Un@¦@V@VUVnV@"],"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":["@@ýVnIW»W@»kUÇLÝU¯¥ÇIUWWÑUWwX¯m@»n@ÜÈķô@a±kȱwÑmwçċmU»ÆkkVyImĉÿ@ݹWnwÇVÅazmmĉ¦ókVmxxU¼VkVm_UlVlk°IVkmJa¦kLmmV@XmKnlUôVXbb@UaÇLğÜÅw£mKnmċwÅ@UkbmaVn@m¯aUJm_k@kWXyl@@kÅamwLUÞmWÅzUKUk±@b@nnKbX¤mzVVxÇn¯@ÒknWVUbkķÈÑWkk@VaU@mUkbÝÅ@Ý¥ÇbkĬXV`kLÇVmalUUanV±nwmkJ@In°KVw¯UnÅ@¥U±bUU±mWbÛKWnUm`UƒVK@bmnmÈż@VL@xxmŤ°n@VmK²VllKkô@êÜV@VXLlm¦UV°Ș¯²ÿ@¥@ÆĊ²ImĶnnb°bKVĸLlÞ@UȮÜ°IVÞÝÞlx@ķĀWUxèÆ@°XnlĊĖ°mnV²V°ÒƦaÞ@zll@bÞĀl¼nKĊ¼óÈb²±IǪÒ¯ĖV@lxnVlkJlaXwŌĉ@VnlÆĕUÆLèŌŤôxÈlU@xlaUċĕXmIWmnkVVVW_@aÈWUUmk@¯çVm»±W¯n¥VmkXw±ÇVw"],"encodeOffsets":[[113592,39645]]}},{"type":"Feature","id":"6106","properties":{"name":"延安市","cp":[109.1052,36.4252],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@@kkÇmImUwVkUU²WmVkm@m`mIĢĕUVa@mXÿVVkyUýĕ@l_UmnWKVkţ¥awğ@@aôWakUma¯¯a±£kxmmxUwÝ@xmUb¯KwóÝ@kmm¹Ub@lklVbmnnVUV@xUknƧJUX@LÇWkwLķƧÅwWJkLkþĉxWzJUnÇk@Ɛk¼ÜÔÈKè@°lÈÆk¦ln@l¼@l¯L°UUVÇ°¹`m¼mXkbUaV@U¯x@¦ÇUUmlmUVmnnmlkw@@¦ÅÇLmx¯Ikl@¦mÆ°VUx¯Lm@JInlmxU²mVbkVbUnÈlKU_WlīÈaÞ¦Æ@ÞlanV@VUbl@XlÇÒĸlVaUXlm@Ñ°ÈmUwUnyW£amL@ma²@lVVLÆynXÝVKnxÆb@lk@WzX@lln`IV°b@nmUnbaVlÆ@ČxmnnL¤ÆxĠÛÈKVb@aWaUókVmnL@WUnnKl¥bnIlU¯JlUkVkn`lUUV»wnwlUôĊ¥nnyÆb"],"encodeOffsets":[[113074,37862]]}},{"type":"Feature","id":"6107","properties":{"name":"汉中市","cp":[106.886,33.0139],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@lKnb@nlWb°bkxĸwVb@łnlĊ¥L@XlÈVblÈKbakVwôml²`n@nVKlk²xŎ°¦VUJĊw@çnWçÞVkUóÛ@¥kwUmX¯WÑk@UymIUwlUn¥mUk²a°¯V»@ÝVÈÝċÅÅVl»@l@a°±@_kammÅba@m@żKknõĠ@m¯LÅwLVxmb@¼kV@mw¯wVakKW»X±¼¯Vkxb¼W@nx@x±bóakb@ÝmU@ķÓÛLkVUmk¯¤ÝLUlÝ@Ýzx@x°bmX¯aUJW¯k@bÇWwÛwWx@XWlb@VÈUlwLnl°VlUô¦U°¤VUxVXUxlbkVVlI°ÅVlU°m@kÇU¯xUlLUlVL@b°ĠInĠ°ÈnK@xÞa²naUyXUKVkWô¼Èaz°JXUVÇV_JVz@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°aXVÞVUÞ@aXm¥kImx¯¯V@anU@UÇéğL@¯¥V£m@ÝÈbKX°wČÿb@xÈblxȯĊmÆUVnÈ@ƨÜLĢ¥Źn°VnnKaô_ÈwUaXmnW¯klLXÇō¦ÝaÅVmbğUn¥±wÅéVan¥U»°am¥£Ý@wVw¥nUÑUmmVwmķIÅaóVWxkblb@ból@ğÒĉ¤ċX¯XxkÇ@óÆÅx@xķ_kmÝÇ£kblb@`¯²@bk@k¼ÆUČÆÞÇÞU@U¼¯°±bVlnm¦kVVxnJVz@lÒXW°nVlx@¦ôÜVUlÝ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`°wXôw°VĊ°@ÅÞÆVzÞK@x@aLÅ@b@nLl@lnmnLVwabVVnbU¼V°blbÈ@ĶŦb@nÇ@amIyUI@ĠVmôUVwkwlanJ¯lwó¥@an°J_@nóƒó@£l¥UwmaÑ@Um±V_J£JUW¥¯@_k¯¼mUVUè¯b@wmL»ğVmağI¯¤ċIUWXKĵ¦ķaJUbIlUóVmk@WÅÅÇ@mUÅVnĉÇ°kwÇa@waċĀ¯xWLÇa@ÞnU¤°¦@ĠKÈê@VmV@bU°°nwlJn¦WbÝ@V"],"encodeOffsets":[[111454,34628]]}},{"type":"Feature","id":"6103","properties":{"name":"宝鸡市","cp":[107.1826,34.3433],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@@£@°Ib@¯°ynŹaUlU£Umĵĉ@@ylUÞ@@£kWU¯WaU£¯ÇV¥@kb¯wn¥ÇkUÇnU@¯±kULm@m±_kónUxlbaÇLkUaÇkW@Kĉ¦km@ŁUaķxlw¯aXak@mmakL@mÛ@¼m@lXV`nKU°°@²¤UÈ@VxmôxKlVV²aVwXlaVlx@UVnÇnk°VVLlkIJÇk¯V@knÆn@lznmlVkzVVVx@Uxz@x±¼VxxUlkb@¼ČkVXlĠkôV²wLUKlwJ@aIV¥Þn¯Ün@nkl²kÆ@°aVbnI@Ťn"],"encodeOffsets":[[110408,35815]]}},{"type":"Feature","id":"6105","properties":{"name":"渭南市","cp":[109.7864,35.0299],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@@ÈôLxU°Þ@mÈnl¤nUôLwX`@ÞÝLUmLôôbVbnºlnÞ@ôx°LanVwÞ@Vxnwnlw²¤b°°bVnlXbó@bĠ@xb¦ŤVXġ£W¥ƽɽó@ýóƝÝ»£XmƅĊkU@ókťaĵÇ@aka¯UV»maUUabUxmKnkm@kmK@xó@¯n¯KǦ@ôÅèlxkx°nƾ¯KU¯WķL@VÝIUbyWbX¼Ç°"],"encodeOffsets":[[111589,35657]]}},{"type":"Feature","id":"6104","properties":{"name":"咸阳市","cp":[108.4131,34.8706],"childNum":14},"geometry":{"type":"Polygon","coordinates":["@@IXyĊwlýKlXIVaķ»a£¯aVU@awÈōaL²»VUln°WȯW»XazVaÞJ@U»@¯Ýbğwly@£kÑţ±WÑ@kaIUn@¯ómţUbU¯lÇIÝb@¤Ý@kV@zĊ@ĶnVV¤kVbmź¯z@°a¯J@¤@bUxb@`xUÔ±ºVXWUnUJLĢ¯ÈKlblmÈXŎ°U°LlkÞ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°kVaŤVôn°@mVJlb@XÒŤ²lÒ@¤kzĠxÞa@°¼ĸK°XV°Lƽ¯mlwkwÆç@óÈ¥°L°mô@w@aÆK@b@wÝLyÅUÝÆ@ĉ¯¯UóxW¯x_ÝJmLUx¯bóak±mÝUUW¯ba»óóxƧçĉbaĉxIUV¯¥ō±wl"],"encodeOffsets":[[110206,34532]]}},{"type":"Feature","id":"6102","properties":{"name":"铜川市","cp":[109.0393,35.1947],"childNum":2},"geometry":{"type":"Polygon","coordinates":["@@ÆxĸƨKlxÈXK@VWƨIlmV@wVUmUnmUalk@kVaUaóaónKVÞK@ÝW_xóKmVk£ÇmnÝ@¯VwóK@ǯXkmVU±¼KbÇŎ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¦WlnnUm°²VVVVVnUnºlz@l@J@kXWVXl@La@KULlbnKlLnKLnKÆXn°bVV@bUVl°Un@LnaVJUbW@UX²l@ČwlVVIWnkÆa°anVKn°UW¯@aVUVk@Un@aV@ValwUanmWUk@WVUUanaVwnLVl°@nk@mVU@UVK@wLVKVU@K@UUKVUV@@bnLaVaôlIXmlKX_°KVV@bVV@zV`kblIVUlL@bnV@VĊllVlIXW@kaU²blKVnIlJalbXXlWVn°JnnL@l@XlJlaX@XW²@l_VmnKUblU@mnkVK¯@U@ma@kX¥VmakkLa@a@WIUUVXWWnk@a°a@kkm@kUUmJm@WUUUIk`m@VkaWWkXKmXk¯@WKLkak@±bw@aa@aka@ma¯@LKÇÅkKWbkmġ±ÅULUKVVkm¯LUVVbUwUW¯bmULxWJ@klmkUm@@KnwVkVK@akw@@a¯bKknVUIb¯mmbk@UbmKUL@xUU@klmLUlVXIVVVUVUU`mLXVWbXnW`Ų°xmxU@mĉwU@mbU@UmbkVW¦kJ@X@`¯Im@UlUVVnb@bWJXnmbJUUUUa@UamIkax@@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@VbVVVInaWmXI@aaUmVUVkn@°J@_W@lIX¥lUnaVV@naV@xĊnV@wn¯wƱX_WmXaWUnKV_VVUUUUWJkUVnKlk¯@@kmKUaűKkU@WmI@WUIlUUmVwXw@UlUVwV@LnbW@anU@UaVkô@l»n@naJnUÈLVaÆUUVmVKV²L@mU_lK@UVWkUa@a@U¯aUaÑóÑUbKk@@ak¯mVaUwVÑkWUmK@UUKmXUWÝwUaLUU@aWJUUU@UaÝU@WL@VKVaVI@WnU@alIVK@kImIkJ@m@@@_K@x@kaW@U@Vmn@UK@mIJUXV¤XXWlkKkkK@XmJVakImJU@ó¯LWKUV@nUVLkxmKkLma@kXKmmLabLmK@V@mXVÆUxX@`nLaV@@VmLUVnLlLb@°²nx@bVUxlb@V¯bUV@zVXVĊXVx@lVn@VnnmU@LlJXVz¯VWVXbV@bmnVUVkÇþÅ@XVxmbUlVUlnW@Xl@VLXÒ@bÞJ°¦Lò@nUb@°X@XbmVUVnb@xx"],"encodeOffsets":[[113614,39657]]}},{"type":"Feature","id":"1410","properties":{"name":"临汾市","cp":[111.4783,36.1615],"childNum":17},"geometry":{"type":"Polygon","coordinates":["@@nW@@UnLKabKnnWL@lnblKnLlwKVU@mVUXL°KôV@nIlJUbnI@WlLllLXkWWU£VWInJ@VL@nm@UVX@lb@@wL@`@n@V@lw@nVmVXWmwnUla@_lKwVlUn°xVKVXXWlUVVI@K@Kn°KwlVlU@kna@V_WnmUVm@kXml_@mLlKXw°m@_ôJVUV@Xl@UaV@Va°Ilk»VwUkVmwUmmVn@V¯@KUwmK@U¯wUVÝ@mJUnWK@@UnKVa_lykUmKÛnm@x@UUlwVkXW@a@U@@K@kIVnammVakUl@wX@@k¯@VVbml@°UbULmlVbnbÅK±VKVXUJWa@ULWaUU@@U@aWK@UkxUKLUUUJ±UkL@V±kk@kam@UV@l@LWl@n@VVUxLlUUx@VUVU@aIUlL@°mLUbkUUaWUUaUU@aWKLWJ@bUL@VUVVbU@m@a@kmKmnĉlUKXWUblbxmIkU@xWb@lkVxLXmzVV@bklVVUzm@bk@Vx@xlU@lUbVnl@Wxnl@n@UbVmLmb@`X@lUX@@xlnkLWaUJnnWVVn@l@bULVV@lV@XnJVX"],"encodeOffsets":[[113063,37784]]}},{"type":"Feature","id":"1407","properties":{"name":"晋中市","cp":[112.7747,37.37],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@@lInJlJ@ULkJ@bmV@XUJUbL@UXKV@ÞVbV@VVXI@bVVKVbÞxVXnWVL@VnLVlXÒUVxUb°nl@bl@LVaôÒÒVb°b@VnLnnV@lmn@lbUV@JUVVXkl@lUzmJ@xXklbUnJVUbnUlbV@nlLX@lakV`Ub°@XVJnUL²KlxnI@KV@lbUbVVKnVl@zlm@U@nI@WUaVl@@mVU@XkW@nkVKV_Vwy@knwVa@XalU@Vnml@X@VLKVaÞbnnlJImVKnVVVInVlU@m@mXK@UmyUI@mWUUakamw@wUwmLkakwVmKw@wUam£y@am_W@UU@knmmamU@WUa@knw@UUUUV@nJm@mVUkKVUUUkKmwKULKUImV@lUnnm@mbUK@°bUnmbUmkkWUb@am@UXkK@a±@V@ĉÅVUXVxUVkLWl¯@@bULUlm@@nm`XlWakIkmVUbUL@Vm@kI@@Km@VaXI@W@aU@kUVU_KbJkkÇb@nkKmLwÅW@kVUUVU@WUIJmIXmma@_kyVaUUlkUm@kUx¯Lm@L@LUJUkVWXUWUL¯wVmUkxkL@`bkmVnxXUWUnm@kxU@"],"encodeOffsets":[[114087,37682]]}},{"type":"Feature","id":"1408","properties":{"name":"运城市","cp":[111.1487,35.2002],"childNum":13},"geometry":{"type":"Polygon","coordinates":["@@VlnJwkaVaXWVLĊknmnLl@@bnV@UaVU@UVK@aXIKXL@bVVVbXVVblVaVnK@¯KVkJ@bVVU@UVwkVKVwUUm@@Xk@K@kVUn@lbl@²l@UlK²VVIVVKVLlw@VXL@b@VV@VXbVK@XbVIUWLU²ÆLmaUankVKVa¯@nkUaU°@n@@kWaUVaXUW@IXKVw@UWU@W@@UUU@mn@`m@UUULkUmJIU@@UK@U@anak_@wmKUwmakVkmKVk¯bw`kwUIÇx¯»ÇaÅmn@@mmUkV@wkKW@kxmLUkĉLÝkxÝw¯lóVUmV@ĀVVX¦W¤kz@`Vx°²ĸ@Ul@xêĸNJ°¤VVlXLWnXxmV@nUl@"],"encodeOffsets":[[113232,36597]]}},{"type":"Feature","id":"1402","properties":{"name":"大同市","cp":[113.7854,39.8035],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@²£yl@ČĖ@bĸĢbĸXaKŤnn@ŎôllÈxnVnÞÇV@bnXllL°KbVb@J@b@UxlKXLlKlXk@UlkJlkUVKXUÇVIVm@_nÇLalwVnU@UUwma@aaÝaLmUk@@W@U@@XwVWÝUUUk@@VmLKV»nwUwaUL@`mzJUIVUaUwKUaVIlJôanÑlLVUn@a@VV@@UUwVK°Vn_lJÆLéW@UUUÅ@»lm@aÞIVwXWUUkkm@U@aU@mwU£VWU_kWmXwW_°yUkkK@UÇK@kkUVymóKU@KWIbUak@mJ@bkbmLkUmkVUW¦@lnb@@V°ULml@nkVaVmLUnk`±@XWW@kbǦX¯WxI@xmbmxXlWV@bÅUz@Jb@bÞbU@Wbk@xk@WX¯VÛWÝbÝUkVUU@alI@a@akLWam@U¯UUmÇL@K@aU@¯VUkKmX@`@kJ@nVUb@lbVÆXVWULU`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":["@@UkLky@IJVa@mÞaWy@_W@_WXVlUVw@nw°K@mUVamVkU@mmmnLVUmKXaU@IlKVUnK@UmWkX@WV_V@akU@aKWIXyIUVmUnUa@WaXUVKVmkUWVkULU@@VbKbIUm@mbVLxWUUkn±V¯wbÅJUbmLkbmKÅKbVnUbVKUbKUbmLKmbaKkUm@UnnVnxUVlUxl¼k¯JUbU@Vbk@WU@UVóI@`¯nWxkLK@nk`Wn@lUnVnmXU`@mb@lkV@VnklVVUblz@`nbWnnJIVJ@XUVVUV@lÆXxnKlL@maÈllIaLV`UlVV@@b@XJWUb@n@L@lJn@@UVKVaUlnlJXbkWn_@mn@VkVK@a°@XklKVUUwVWUĊÆ@U²@@blLVWn@@bVaXllVnnaVma@¯VLnan@mVm@knUVJ"],"encodeOffsets":[[116269,37637]]}},{"type":"Feature","id":"1406","properties":{"name":"朔州市","cp":[113.0713,39.6991],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@XXWVXVWnnlnn@èƼ@xlVnblVÈUVl@blnLÜĊmUkU@Ua@WI@aXk@WVUlKUaV_VKXWUUÅka@VaU@mlI@@_nWLVl°UV@@b@LÈKVn°V@VnXblK@b@bkJ@bVVlUÞVÞaXÜ°UXWl@wl@XaV@Ýa@aa@IVyÆ@aXUWknwna@wJXw°WÈ¥kI@W@kmKm¯IUmkXWWkabkImJUkL±aVb@lWXkJUkĉk@UmU@aKkVUkJlaU_y@UU@aUU¯LW`kLWnkJóbUbmK@aU@UVVL@VL@UVULK@xUL@VUV@nml¯@UkmKUxmbVbUV@XlXVmnVbkxUbU@bm@@VUlUVb°@VX¯m"],"encodeOffsets":[[114615,40562]]}},{"type":"Feature","id":"1405","properties":{"name":"晋城市","cp":[112.7856,35.6342],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@lVLbanLnKVaLVaLUVaUmaÆLnLlanKVaÆIa°x²UlmVVXwUKna@VnJaLa@UV@@alUkKVKnkmmVwUkw@@kxWUXW@@mk@aUa@a¯aLkKmwkUm@kL@K@aWIXmVXWkUVakL@UVKw@aUK@UUKmLU@¯nKUwVUIWJUWmka@UXJk@UkmW@kLWKVx@bmI@VUaVU@a¯@UUmVKmX@±`kÝKVxUL±akL@VbLkKmV@XWVUbVXb@lm@@lW@@xklVUbnnmbUlJ@@L@@Vb@WXUlkxVV@wn@ÜmnLlVkz`UbmL@V@XLmVnIÞ@VU°x@VnLxV@LU°"],"encodeOffsets":[[115223,36895]]}},{"type":"Feature","id":"1401","properties":{"name":"太原市","cp":[112.3352,37.9413],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@@VV@wVKnLVal@na°naVJUlmL°a@b@lx@bULUlmx@Ln@lVknl@XIwKVn°aVXVxUaVU°KnUlUVLKÆV²ĢlnXalLÈÆLKUaVkUanmWUa@WwkUWU¯y¯Ñ@anIl@@aVUmIymULUUVakaU@@LmJkw±LKmVUI@W¯VaU_lkbW@kK@mUkaVmVaUIVmalkW@wnIVy@klkWUUVI@UVkam@knU@mmmK@bblVUX@VkLV`@n±KUULUnVVÅUbÇKmVImbm@k¼ó@Ulb@VmV@bXmaK@UUxkVV@xWUxVnkVVJ@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@bbb@x²al@lbKXU@mkUWkkmUUVwV@XUW@naVklKXblKnLnLVanImaXKlLaV@U@KUKWalXK@£WKXUV@VUUUVW_V@W@@K@UIWmXUmULnJkImmÝaUbLK@UWk@mnU@kVWb@Ubmx@lzUx`UULml@XWl@UV@nk@UVb@XJm@@Vknyk@zJnUV@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²KU@UU¥a@£ÞôxKnkmX¥IUÝUwlk°V@ÈKUwlkUyV¹mx²XllÑW»lw°UŎnJl¯°V@wôIVÇnnUllLVÇLô¼XW£@±@¥k_ÇJkUékwXa@Llw²Vxbm¼ÈxlLÈVWÞn¯mÇÑUÝlÛkwlĉmULmwUJç@wkm@ÑlUXÑôġVaUѯ@wķÓkbVmnU@@y¯IķKV@¹aé@kmÞU°¥@a¯@anKlblU¥@óğç@Çw@wklaçݱk¯±@ğÝUÛmݯw@kb±¯akXWÜkXUÆÇU¤X_ƐwV@¤XUbUIUlÇUkġ@aXČmlUlèUV@mVk¦Vx@¦±¯¯¯anlW¯nÅw@w°KVak£m@klKknÇU»óKīlaUaV£@¯@ÆUVÛÝÇXÇlÓlŹ»WUğJ¯£mxLĵôºXVlUll²bllxónn°ÝU¼mJU¯nV@êĉ°Uĸw@m@¯kmXamѯaUwÝKU¥mÅn¥Wmn¹n±ƑƆÇôXê±NJnUôlĖkȂVÒ¯¼VnȮ¯ĀnƆĢ@k°V°¯ĢVlkVxm¼X²Ŏ@VxknWÜ°U¯nÆÝ@`ôݲÒÇznmX@xè°K°ÅUČĬóĖÝó¼ÅêÒbmk@V@Òl@nĉÜêx@ĖmlÅJ¯¦óxȭ°Ým¯LĵèĀ@Æl°żX@xmkV@z@°blnÞ°J@bn@ƼUVUóóL°X°ÝLxUn°Ĭn@lnL@Æ@nKÆxnUnVInĬmÆnxŎ¼ĊIĢóÞ@ĊƨbUmV¥lkwnLmÅÆ¥XwU@wwUÞ@alUUÅUVkkm°aU°Ó°w°Ub°a²K¯ĕ@ÈbÞĊa»XVm°InĬk¼VbaJô£VĊanků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@lVL°wnJ°UĸŎèIlwV°¤nĮ¤ÝlèL@@xlè²ôĊ_ĊġVÈôJżīlbXÆÈVkxÇVn°¦Üb@è@nn@@°UÈ¥WÇ_Uala¯¯UÇk»mVwk»k²°VxlL@¤_@x`ÈĖöb@l²alXa@bnK°¦VK@nnWmx@nUnl@@llĉk°l°UXkmW@Un`kÇLWÛÈVxVVlVk@lIXb@ylXÈWĮWŤzy@mI²J@n°@VJ°aÅ@ŎkVÇkaUwKVwV@nkm@±ôkôĊJ¼InÑm±nIÞXÈĊxĊUÈbÜyÈ£Vkw@kVUVm@a»ÜbÈmUXwÝxUn¥@°ġÅaJVkaW¯Û@W¥UŏĶ@¯kUŃ@aI@mmanwÞW@mw°»Uřk¹±WxVx¯¦U°zţWw@°ÇVÑk¯@y°a£@mnl¼aÝÝakwU±aĉImlĵn@m@kkV¯Ñmĸ°xl@XVÞmlÛÝĉUÅ¥mwÅ¥VaUwXġċaVůÛŹlwU¯Uó±xÛV±¯¯n¯mċLmnĊm@_kJWaXmwUĉK»@mwXÝUÇkKÇw»naUw±kxK@WbxlVêlÈIl`@¦@²X¤Wó»KUÈKkkmVmUÈóJ@x¯Uk°Imō¯VxkX¼Òkk±WwnUºVzklVxLÇ@¯UklVxÞVJW¦nmlLówÝ@¤b¦V@VV±LUxVbU@Vx¯x@²n°xnWbb"],"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ÞÈÜUVÅ°@@U¤VbkbĬôL¼ÈVlmLlkn@l¤Ub¯L@xÆx°mXmk°b°°²@¥Uwl¥nU@VUkçVnkWċbĢ@lÈVVkJVaVW@£UƏxW`£ÈVVÅlWXÛlW°b²la@°xnÞVÜĠÞ²@l°Þ²èkbl@xÈx@Ġènal£nUDz@ÞKnn¤@¼°U¼nVXUbnĠUVbUlV°LX@lVèÜUnK@_yXVyUwmIU»VkÇ¥ÿkkV¯m±n@n¯ÜanVVÆz@bwÜbm@wa@kmk»@a@VUUów@nb°mXmnVbÞVôanwJak£lwLÅnÝ@wl¥IÇÓ@UL¼kVÇÅó¯kVmmw@n_Vn»°LÅ»@éÇçŹīVÇÝ@ÝğUaVݯķlŭġl@óÞÛċ@¯nkUÓm±IVġUwóKUn±¯Kw»KÝVnl@óxUwţ£ĉUmÅÇÝKÝUlmK£UV@ÞÈW¦Ò@Ĭnny@nÒmV¼@°Vbl@VlnUUwl°a@@llnk°lbnKWĀnUVxU²Åm¦ÛÇÅaUVb@¦m`móXUmmxÅ@±Þnè²U¯»mVm@wU@wÝÝmLa@VÇUkl°¯VlkV¦UmxaULUèVx@kIUxmWV¼¯VmȯUnlÈ@m»ÅVWxÅbÅğW@km@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ĊÑJw@È»m»£°Kk@ÇnÑÆ@w°JUwnw@wbVb@VlźLUwa»aUklyUUVakwWXwWUxkLmn¥mwkUXlJw@aIk°X¥W²l¥aUIlmkklÈL@m°nlWUaW@V@UaV¥@ak@Çk¹K@aK@kKkÇX@VU@kx±VèkIWwUVUkkKÇ@a@wkml¯@kUWn£WaaVwnaVÝw¯@UaWxnJÅUxUma@L@mbUU±VVnkxUÆVm@kkKW°X@¤ÇUkÆÇnU¦¯kmLVwÅK@UóbÇÆV¦L@±êX¦mVÞkÜÝnWU@k¯wķn°ÒUlln@@ĶmnkĊJ²bVlxÞbÞbk»mn@¤¯bz@l°UÒ¯È@xŤXyV¯°¥Uww²XlºVŚ¯¼nx@XÝmxnb@nJ@b"],"encodeOffsets":[[106448,33694]]}},{"type":"Feature","id":"5117","properties":{"name":"达州市","cp":[107.6111,31.333],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@Uxn°bnlUnÒÆnn@n¤LnxlUV@Ælx°XXxl`XVWLè±nÈb°b@²x°Kܼ°ĉV¦lJnU@¦ÞJÞğmLÞ»xUlbVÆannalVÆX@lnŎVmUmaÅXa@aWm@£@wĉJVkkkkmnk@mna@alKJ@ÞwmÅÅ@ambkU@KUġKU@mak¯±a@aĉÑÅaVwXlw±V¥l@@ak@@£mĉÝónWV@nÝÇÇxUmbaVkkk@m@m°ÝýXmakÅī@@mb@@xmnb@mxkWL@¯b@WUXmWWKkbm@kxXmm@LUlxlêóKnUallLlLó°m¯JVUK@xK²Āô¦l°"],"encodeOffsets":[[109519,31917]]}},{"type":"Feature","id":"5108","properties":{"name":"广元市","cp":[105.6885,32.2284],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@ÆLĊx°»Ŧ¦WLÈ@xÞKÜ°ÞnVxÅĀlÒnJ°a@wV¯l@XWknKnwVÈ°XXalX°VI°bWna¥@w°n@yÆ@nkÞ@°¯lJn°IÈlUlXÅ@ķlUV¥VUUÝÞUU@UwJUkĉm@ýlkWUwVwWJk@VUKlUkaVUmLkm@@UIk`@UmlUkV¯ÇXKÝ_mm¯@U`kwml¼±KV¯¯Vk±Vk±kzmaKUnDZbk¦±X¦¯WlJ@bxkIWVlxnm¦nlKVwXWxXlxUbVVkzVlb¼bVxŹKUk@Uaa@xmxVx¯Ix@Å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ĊklxkÜVÞÒnÈm°nx@¼ĊLVnxWXblI`@nmĉnKČôÅlUÑmUK²¹@ÇÅVÓůVýÞWUVmXÆbnwKUÿ@UmmIUb¯¥Uw¯ÇmçmanUm»UUlk¤a¯bVU_WĕmÇűĢUlUlÛVçkU@W¯KUVkUağVmaVWUmV»¯@»m£mÝL±@ÈmVk¤mb@ô¦kVkamL@b°@b¯¦ÝVn@lêb@ºUĸL°J@zV@nmUlaĸÔ@x°VÒUbóĢÒWkV@Ò"],"encodeOffsets":[[104727,30797]]}},{"type":"Feature","id":"5115","properties":{"name":"宜宾市","cp":[104.6558,28.548],"childNum":10},"geometry":{"type":"Polygon","coordinates":["@@VlÈnlXnWLX`m²nV@b°xĢçlnVmnn@@°UzlV°nÞÒkxlw`UnVbmL@albÞKÈÛmܼ°@XÇ@wmW@ÅKĊLlVLVŎçÞL²±ğkw@Uy@¹lKXlKVa@wČ@w@aÇU¯n@@wġakaōK@Å»VakUWmķwkbğ¥mLak@ġÞ°¯xVVÞ@VxVVWxXlxU@k²WVÅULmèULVĊklĠVJVx±nů¦mwğ@mlğkkl±@kUk@¯±ÇKkxl¤bImx"],"encodeOffsets":[[106099,29279]]}},{"type":"Feature","id":"5111","properties":{"name":"乐山市","cp":[103.5791,29.1742],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@kVkÆkV²UlºÈIlxLXèÜlUXUmkbVèx°@@¼°Knnn@mÆIUbnJ@bVI°b°±@nK@mVakkKl¯nbmĸèl@VnÈlUUwwmwnm°¥LlLnU@VaImbkmKnk@mbLVJVUUVnkVmb@a¯JUaÆkk¥IW¥KlwÑmÝU¯kVy¯@@mmnUkmġè¯w@aU±mnW_XKWmkÇmUkóbUÝUanmW¯nma@xVôUV@b@l¼n@lb@xnÛaxa@yUÅmUÛbm°@mn²U°llĀȦlUV¼nJVxUzWz@`mL"],"encodeOffsets":[[105480,29993]]}},{"type":"Feature","id":"5113","properties":{"name":"南充市","cp":[106.2048,31.1517],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@ȲVmLnblyl²²UUl°U°²L»knlx_V°@nnÞ`WL°ÈUVlnkV@l_JV@n@lnKV£ÇUV¯m@laXUUbVx@VkôJU°Jn@wUk°wnUV_nJmknmm¯Vwk¯ó¥±ÿL@wLVUkUbX¯mykI@a±Kk¦ULmaXVm¯Kz±klUIVbÇJkL¯lUÿUlUkJUmUUkVVklKk@@aU@J²x¦kĬ@¼±ºXnWbxU@xx@lL@bLlº@Èl@bU¦Vb@U@XbVkX¯m@nÇKkllknJV"],"encodeOffsets":[[107989,32282]]}},{"type":"Feature","id":"5119","properties":{"name":"巴中市","cp":[107.0618,31.9977],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@VUlbkVVLUl@XIUxVxXkl@þĊnVlIVx@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çKXUWk_Ww¯WwÅk@UkVmwK£@mmmÅmÑkVmamnnlmIU`Vm¯xVlx@m¯IVóIUl@UwVaVWkb@nU°VÈU¤"],"encodeOffsets":[[108957,32569]]}},{"type":"Feature","id":"5105","properties":{"name":"泸州市","cp":[105.4578,28.493],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@VVXwVKnwnVnl@b¯xmKUbVn°°X°@blLènV@Vnl@ULnmmUnaVV_ĶV@wnJl@@kkKVólaUwnJmwUlm@aUaôKVnJWbÞ@VwVLX¥VV_Þ`wWÞŹmmnIn¥W@kWV¯@°kILk¼Ç@k¤±XknmݯUlÅÛKWV¯klUwkLÓ@U@w@ġXVWX@UbVbV_kÇVlU°lnwŎ¦ÞaƯnmm¯Um¥nkVmkl_ó¥¯UÇl¯@Lk`¯ķLUy¯@mw¼ķ°ġ_ÅU°mlnÇVUÞ@_JUnVUXblĢb@x@mV°Èb@xċ@@xUbkLWkL@ºzV@lxĠ±²"],"encodeOffsets":[[107674,29639]]}},{"type":"Feature","id":"5101","properties":{"name":"成都市","cp":[103.9526,30.7617],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@°n°m²°ÜUw²ôV°VkxÜźUŰČbĢlaÈL»@kwVÇ@nÛÆ»ÈUÝ°Kl_V°U`Vbn@VbÈLaVU@ƨ»VnIlUUa±lIk±@VnKmÅ@WaK¦lVōkKÝ@maXÇmw¯IU@kVwUmVIçÿU±Å@¯È@xK@wLUbÇKÅ@mÝ£@yóUóóUxkI@WlIUabaVĀLmxÅaWUnVÝXUþÆ°UÔÈÆ@±ºLnVVÒkóÆ"],"encodeOffsets":[[105492,31534]]}},{"type":"Feature","id":"5120","properties":{"name":"资阳市","cp":[104.9744,30.1575],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@èUJVnxU@lV°JnxWÈnbÞ@lLŎUk¥LXbÆ@nmLU@zlbXmlnVynLçJVbUnómUnamUan¥lKV_²aValWôn@nbVK°¯VblW@kklUnlV£°W@wUXk°KVwmVkwVyVI@wkmVÅ_Umm@Uÿmbk£xUaVw±V¼V¤kLWxU@UkbyXóm°V@@zÝÒkKn±U@@_VVkÇaVwnLWalm@@kkVVl¦kIV`±n@wKk²aVUUV¤nkxmUkVWVnLUbVb`kUUmLUmX@`ÅbÇXbWLXn"],"encodeOffsets":[[106695,31062]]}},{"type":"Feature","id":"5104","properties":{"name":"攀枝花市","cp":[101.6895,26.7133],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@bKÞnÞ@xV@xnUn°¼V±mç²ÝÆ@wnnVWnôn_@¥UaVbÆÈÜn¥Æ±VUwVmXÿmLkal¯km@k@¯bkVxmVUkk@Ua@¯»UnmÑ@mzm@īÑX¥Ç@ÝxU¦ÅÇUkx@lbUWVXmV@xĵĖ±@@¯xUÆLnÆmx@nXL±lUUVwKWak@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@baVbkJ@XlJVwôôôV@zÞ¤@nÆÈLVaK@xL@w°ÇÆ@²VĀmWXKWaÈÆa@_nWVnKVlV_UaVamKXUWwnmmwÑm£@ynUkWĉUkWVkkV±çkJmkKK¯¦mnnxxVxVÇkUmk@çķnmak°LllUb@nmL@¯²¯aUJ@amIVaÅJnm@mm¯L@»¯@wUçanlVWVÛkWçKkwÇJk¹±VUÅlġV²ÈÆnXĖV`U°ab£lkVVn¼mVnbèÈn°"],"encodeOffsets":[[105683,30685]]}},{"type":"Feature","id":"5116","properties":{"name":"广安市","cp":[106.6333,30.4376],"childNum":5},"geometry":{"type":"Polygon","coordinates":["@@VlIVkVĀVk°lKÈIUaVJlk²yLn°UWnbVKl¥²L@blJnzW°alV°Inô¯KkKkkbVmôLkéwVk@KnnWlwn@laXLnXVW@X°a@XKlnw@man@w@na@@wĕġġwUkUWb@mk@¦¥mUÛb±yÅn@bml@kV@lknVbmVnlmbÇk¯bWyk@V_UamJ@I@WaVXamIVWkUkbVaUUx@VnkVU¼bkKUxmK@WxnV@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¯lLln@UVÅlwUm²UVVna@@KnbVVwÆImXwWkIVwÝĕVUaIèmKUzkmWnka@y@l²kJ²VbVkmJUƧ¼@UVbÇKUam@Ua_¯VUk`¯LVÞÇżmÜ@UÈx@l¼ÇKkbWVxUbƦnxƦĊV"],"encodeOffsets":[[106594,32457]]}},{"type":"Feature","id":"5110","properties":{"name":"内江市","cp":[104.8535,29.6136],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@²èlUUllXĊVXlmV@zn¤ÒnxmnXxlUnVlwmU£VVUbl±L@x²mU_lJ¥UklU@ln@kXbmKUxÈblUU@`V@²mlLÞÑ@yU@¯ônWzaVlV@XwlKU£»aVaUwm@mwUVUwklVDzLlKVm_@ykUm@mUçkKmxkIUÝ@LUJ@n±kºLXb¼@mmIXa@mamnkWKUx_U`UklwUwmUbV²akbmkn@`UmÒVxUbI`UaÝÈ"],"encodeOffsets":[[106774,30342]]}},{"type":"Feature","id":"5109","properties":{"name":"遂宁市","cp":[105.5347,30.6683],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@ÞĖUxlJXVb°@xUÞmbUxbXbm¤VX@lk°ln@xbÈ@lLVlVUXxlJç²UlwV@@UÈWlLw@wVwXaWm²¹@»lī¥w±I@V@bl@kLUllUVVn@mmUwXċbVb@VUkbmamW@ka@k@laUa@¯b@mmwó@@lkXUa¯°LUamm@ó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ÞÇbV_JVaUwnÑV@_lmnlab±UVanVxkxVlV_`wVLlXnmnb@WbnJ@n»WaKl¹²@mVI@KÞVlJnw@aW¯¯¯UmVanL°w@akmmUxmULWxUUÝKōèUKUkĉKL@ÆnX@xWȯ@Û»nÇÜÝLka@bKnUaVm_xkLX¦Jl¦ÅlVb°I@bnaUmlUVUVIUKa@nmlnLlnaJUbV@"],"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}aekgKSuSsMß`¡CqZ·be@Q^o@gieMp]}}Ľc_Kk
{ùA¡r[uom@ÑĥJiq©mʼnq¯Bq]ÙYgSåk_gwUisTE
ĕiqiUEkue_OSsZaWKo¡qycY£w}ĩĕS§Z©SN¥SyLÑ¡±Ks^IYPdY[UoFp}´\\¬\\j]eÜò¤¡ā a\\bnU㺹Ìs¼j®[cíȈEĝĆ`ļf¶®K|VØDdKGpVnUFjpHF`B[pMºxÖjbpÎxp¬|ΟÜÒC²®ÜApZG~dÞàV¨|¸`|²tx~\\~|dFf^zGĄŚhdL\\hĸ¼OªP®lV`p\\]Xpllæ¤CpQ|oF}fMRiNSon_²qämMNM\\"],"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@[LaCIICBWKCEEG@WBQHCDFD@HSLEJI@IHWECFGAAEKCGDBFCBSBIDCKKHEADMJMFABKOKEQAA@IEEG@GIQAEK@OZEESMOLlu@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@DUÂ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@BIOEKJEBICFKaKPFAFSE@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[wepc¢·²^QEKIEKIgiQDkehY£uSDBMkUDOJDHC@GF@CAFBFEN@CQ@BeP@@G@HD@@MHQKi@[IGCOCESE@GMA_OcCGDu`a@VZzKDkJBLNXGDqKEWE@cFEFA@ISIi@@KMABJGBcMuFEzGVH\\ATSEUBeALCEMG@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@ETEBObLELJDFALIPFAJL@@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@IXIFEoGE[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~yFVNRrdJGzDPVFBCTNND\\UR@E`F@@Ip@IWGUoawOEE@ÏDgK{İEEMFëCb
@KwOCDHHKBDJCDEEEAGHOABFABMCgDLSQ@CFEBMgYIDQINE@AUSwSAdYEHQMEyK[KI@GRMLE@@OqOoBOnpJ@BmEAFHL^FDB[C@BBDVFAHFJENB@sNEjQAMYsUgCSBGDJH@\\LjGR@NC@@G@HO@AfR@DM@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@ITURBRZNHNWRQoOj½fcqAqeiDÿÍyÓįFL|Ch@ÐFFxPpbHVJXo@@JCTR^BPABQA]^MB@bE@@FQBFVJRH@FXtPNZSBAja@@NDTLJrQTHFXZFB`"],"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±¡¸odfx\\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^FJFFJIbSCAFTJTIpKDGLBEKLBjHTVNBZWbE\\SBQGE@ATCRHDGEEKECBECxOhOfAZGA_YEEWSGqRKISC@Mb@BiTAMYsOEWG@IQEURA@EF@@acUOXQRYCUDCHDTEF[SUEgAYDcVGJM`iAWDWLQRMHUHgDsDBLHJFCFDFGHBFFVEAGHCJN@RJFPIhBD\\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ēAM¡Wa[MeqpQRMXMGQYQASV@J@NNXDPmBAtJXlveRLFGACFGAYf@^X@BPV@|HNPFA\\FNEEYBCnQGMDCDE\\IHFpEFWJ@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@[VMCSMADUECOHycIqMQEU}zkawENRDENB@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[EACJgOIE@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":["@@DT@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":["@@ƀǨə͌ƣǛɁ҄˽ʁˋΦɫϘƏḷ}Ӣ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":["@@ỉŶÆگʉѬµє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ନύʐ֛ƛ˧ɚٙىʱٹ̕ϡΥŽˏ¥čȹAMϛƷࢵĿßˍ͝ޗ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ŭޥVAAӁϛ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ߊɌࣴĴʼиÆ̚ƶӎKaEAࡑ@ѫ"],"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ˎ͞ŀàࢶϜƸ౦NBĎȺː¦Φž̖Ϣʲٺٚي˨ə֜Ɯώʏ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@DZJX´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ȣˌōlUȯŎKÆƅ°XÑܱnŗġV¯óaUƧUōŁÑ±çɲ¥lĉkğ°k¥nğţL¯ÝÝUƽĬlķ°@ōXÿݯV»ŹLʉÞɱŤĉó°ÝJ¦ÝKÝ£ţÜÈĉ@xǩUċƑ@ky͓¹`U²ĉVġ»ğa¯¥ť@ĉó@ŻÛÛJw¯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ŎçÅ°ȯȰÝ°óƒÆͿĉ»̽çnmɱĵƧºóUƽ@±wóL¯°̻L±Æ¯Vƴķb¯VÇ¥ğ²Ǖbk¥ÇKlÅɱġ@ÑóK@ÇaÝXğţxĉČǫķê¯K@ÑaŹƑK¼¯VóaónġwóÞéUġbóĉğÇl¹aUóğKWVůnÇŋƑķnʇ»óxĉwçÇ°Åw°ċXób±kÈÇJm²ţx@ÒÝŦǺnó¼n°ÇbUÒ±¼XĸĠłƽXmwĉºzÈÜmnxmx²Ė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°°ĸJkʠ¼Æw°¤ÈlxɆzČºĶI²ÆǔU°ô@Þ¦UnUĠ¼ŎÓĢ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@ĊXmmÑÆ»ȰÑ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¹ƨémanѱĕnwmwnÇÛyĉ¹ŹlŏkĵèķmōÞġKñÔċKÅèĉzômxȗÿƿI@þÅČÝKÝ°@¼ÈVº@ÅĢÆUċłnÝÆǕČĵJm£ÝJ¦@ĊxV°ƏLċ¼ǩ@m@ÅĢómÇÆğ¹ÇÆĖÞKxwô¦ÆÑÆL²ÆƾU±ŚÅŻĖ@ĬŤÈñ@ǔÇxÈǃ","@@VÇţ°ğUĠ¯mk¯ó¥ķIġÿƏbĉa±ÒĸĀlKU_m»nwm@ÈŤ¦ĉ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ğnaċƨbVğ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ôÝĢLxÆLɲm²VlwÈ@Uƒ°¯ǖxĊmUÑƨa°Å°WV¹aÇɃÈm¥°¯ŹóĸķǫUm»Å¼ÇVɱlÝŋnķÇÝX¯ͩÇɳaÝ`±_U±ĵnWa@ĸóķ¯ǓV±ÅĵJċ¹Ʌykwǯ£Åxʟ»lķI¯X¯ķêǕȭnķ»Ź`±kÞ@Ýô@Þ°xŤŎIƨÆUxō¯²ǔĬǬlUŚ"],["@@ÞĀlź¦¯ĸŤKÞċƨbVğ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ȁĊÝabŻ£¯°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ğnaÝţ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»nwm@ÈŤ¦ĉ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Ŏ¼źÇĢĠĕˎŁ°óƨ¼Èam@¥°wǔǖ°ƨÇŤġƨŎŃôbÈÛŎĊ°@Ġw²ÑÞJÆÆb²°êĊUÞlȲVÈKĊÒĸĉ»ÅôťUÅÇk¯@ÇÑklÇÅlĢVÑó@°@ÛĸV¯ÇĊn¯Uĕƽ¯m¯bÈ@Ò°Ĭbĵ¼kxķýÇJk£ÝaUÑÅóĶǟkÓʉnĉݼƑó»Þmn£mČ¯@ȮÿV¯ĸk@Ýów»ğġ±ǓLōV¼Əèķĉè±b@ÒţUÑóakl£Ó@¯L@ÇlUóȁ¯aġÈÅĕÝLķ¯Ė¯@WĬxÒÈnW°ţôU²ǓÓġ²V°¯ôǔÝLċk»Ý»Ý¯ÞVwÛÝÇōͩÈĉċ»ĉm¯£W¥ţKkóġƏW@¯±kōÈb@ÒÇaƯakóÛǦÝa¯Ýĉ@Ç»ÛmǓxķƛ¯lVĀÅÞġbÇJUÅVĖƑWzō»ōWn@è¯ÞóVkwƩnkźÇÞÒÞ¯ýğÇUxÆÈnè±bĉÝ»ÈŃwwÞ@m»ÈV@ýÇ°ķxaݯXċ¥ÈóW@ôkxlnxVÈóĊ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ÇýVUó£ğÇÑŹ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¦lKnĬȀƾÛ¦WÆÅmNJĉ°ōUţ¤UŎ°ŎKÞłÆǓ¦Þř¯bmUÝl¯Umğl¯£șwÅǫaÝnĉĶk@¯Kō»ĉnaÞ»ť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ĠÞĕklýƾťô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Ŏ±²¦ƐUlj°aÈÑŎbĢŎbÆ¥ÞIȘlôVÈUbkɲĶnmnXb̼òƾĖŎ@ĢȂÑôÓĠĖʊĊÔ"],"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Æķ¦klnŦmݼbĊmŎ¼L@°lĊĵÞmǬbÆȚx°¤Ġkn°VÞkVn°aŚÝǔ¥ÅÝŁōL¯ōVŤ£ŎVĊ¯nljÆXÅÜ¥ǿƽmīLkl¥ÿn¯ĊL°ķÈw°ĉ@ƑĸaV£ʈȣÞlôwÈ@ҼưºŐnmÆĸ¦UńÆVóĶLèôkÅ°lĬ¦ŹôôaÆôÇĢnèŎÈƨaĉ²VLĢ»lţôĉUÇwkmlw@óôXÇȦ°WÞbwĸȯ@þÇUn¼Ý@xxÇńÞ¼Ċ²amçÅÇVwĠÈþ°ÝÑÈÝlŹƪmlxôU°Ý@çmXŎŎ¼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Òó¯±Żĉ£ķÆÅLLjĉýţÛ¯VnV¤ÝÈ@°ÅÞݤŰğŁm¦ÝxóK¥ɱÈUĠôêVôÛ¼ÇWÝçĵaō¦óĖƧlÇĢƑnŎÇV¼¼ºÛ@m¦ƽĉmm¯ÝKÛç¯bŏłĬb¼ÅLmxť°Å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ķÑÜ@ÒóŚÝ¯°ĉówDZ¦ÅJUÒĉĀķw¯°mĖ¯±akxÝÅn»lÑK@¯lU¯UVѯóĊ¯mōğVǓƅÞWÝÈÛ@ƿô¯ÜġzÅþ¯ólmôʇġĊÅUͿřŏȁˋŁóÇˡōƧÇbw°Ķôk¦ÒnUþġÒÔkǔķèó@²@ŘōńĵyzġaݤÅI¤Ƀť¦ğѯ¤ķbó¯ó±U²°¤ČÜVnÈÆŚŎ°ôĢþÆzèVĀÇĀÇXŹÑ¯¤ówċķk¦łUÒġzÇ@ÆÝx@²Þ@ƤUô¦U°xU"],"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ÿwwÝw@¯mÞŗ°wĠĸkÞğlĔ²¦°@ĕĸwVóal@nĢÇĊn°@¦źUXçǔůĸVÆKÈÝĠ²ÅĔô@lÈ_mzǖlaU¼ôwV°¯¦ĬÈal@ČǼnIxô»ɜ@ƨ¥ɆŁŃǪȁ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ÒɳÒÅ»¯xVmbb¯Ý°UWéÛaxʉÛm¯ÝIUÇKk°VƧīķU°ȭĀ@ċ°nm¤Ý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Þ£ĢbyĶ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Č¼ÇĊŎͪÞÈÜxU°ÝÞÞ¼¼lČÞKǓ°óU¯Ģ±ǔÔV±ŤóX¯ÇmÑwXī°@°ĕĸÞKÆĖĢÇ°bȂÇŁUV¯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¤kVxl@°Ś²@y@ô¦¯@xxVxUVbVÜm¼ŎĢmºXXWÆ@ĀmmXU°ÅÒm¼Þx°w@°XêĠ°»nV°Ul@k@V±ôī@£ČŃÆ£KÞý@¥k@ya@nWVUVwm£Jknm@wmknXX¥mUUlUnb¯°nkVInlIUw°nmk@@mlanXlanmk@wVWUw_@éĠanmUaÜ£mX¥¯@@óUmݯ¯ÞÝlKnxô£»»ĠJ°aVUÝÿV¥ÛbI@wmón¯yÛL@WkÅmÈ`IWa¯K@¯mUnmaXmbmak¯ĢÒÝm¯mV¯KÇb¯KÛWWX@aVknċLUWVkXóW@ka@ób¯Uwmb¥UUlaU¥U£maķKXkmÝ@kwmѯk±ċbUUVakaġ¦kL@`a¯xmÅLUW@ċnÅUV°LkL@b°°@¤²nôôkl°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@°@¦WnÛ¤Vbmnğb@ê`VxUX@xÆÞUnnWÞĸĢÈ@Çè@zÛÜWÅêl²KnV¯ĖĊx@bk@@°JÆ£Èblnnm°nlUkVUUwVmKnnVÞxVLX¥laX@@xl@VzÈVmk@b°ÈĸmV¦`WXbUbbX¼°x@aVVkn@lþnXUlVxŤÅyIUkaIŎĊ@lXx@bz@ô¥_V@ln@ôy@al_l`nmÈ»@kmXwWKU¯»aÅ@wmUÝKUaUUwW@w²»@kÆV£mm£VKkÑV@@»nw¥@kÆnllIVlnLVakalknJWmnaUaVÑVVÞn¥m@¯Uÿl@VçaXaV¯UyVLVk@nJlXLlkxlbla²Òl@nVJVkxKlkUaVķÝÑU@Åm¯@±Uó°ğńķĠmUÑ@ǯ¯Å¼@nml@°¯¯`@w£@¯Çk@»nmċ¯U»I¯LÇĶÛn@bó°Uwm¯UmǯaI@ykIVU¯bIğ¼¼ó¤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@XbÞInlVUVwJVaUK°¥xmÞXnlKlnna°@ĊČÆwUmnkl@°£nyn@VV@Vak@@kÞÝbmx°Vnw°klÞInĖÞVlKl@Xa°KlVU@JnxU@ÈĢbUKlm@ak_wanWUk°l»k@Wk@lwU_@UalóU¥ÇnkJW@mVXx±bK@nV±a@Åa£ÝK²WknamKknÇk¯aVV¯ĀUÒ¥I@mm¯¯xÅW@@`k@ó»UU¯lm£ÅWlĵw@mmwÅmWU@y±UxmwU¯U¥Ý¥¯£m@kÇVUV°VbklLwUlUImk@±ÑkbkalwkWKkmI@UlUKVzU°WbbUè@kVĀ°@nm¦ÝUUUÒVbmbXnmIkllbUbmKUkkJmkÅ@l¦mx@¼U@lÒULn¤nU¤Å@l±¼@xXxVVVbÞLVn@xÆb°¼V"],"encodeOffsets":[[106504,25037]]}},{"type":"Feature","id":"5303","properties":{"name":"曲靖市","cp":[103.9417,25.7025],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@ȦlKÞĕUV¯Um¯ÇVUnVVUĉnĊÇƾLn°°ÈJÆw@lbÞa¦VXJ°¯W¯aÞJVkUa@lKnÅmWUk¯a¯»@m±@ÑkkbWWX_WÓU»_lkÑm@U»m@l@IWċn¯l@VanVUVUVwVxKÈVmUē@n@VÝÆLwVVwnVlmkUVÑÇ°ka@kÿÝaÞUl£ċĕX±±ĉa@UnVnalónk@wlUVmkÝJaW@ÅwóVVnnb±°@óxXLWxn@lǼnmk_k`@bózm@kU@`¦ó@nW@ÜÅXWw@yb¦@ÒlnUb@xlÜk@²Ç@U¯bmy@kV@bb¦U`lLVx@bLl¼Þ¤@°VVÞU@WÞUbJ@nn@lnnmxUUUbK@ÇwklkUVWakn@lbU@@ULVxkKUn°¯Ò@¼km¦m@klȰ@lUl¦@Vl°wnnþĊUÆbUxbVĖU°annaVal@@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°knmKUxxVôUx°¼ôÒÈ°JlnÞKĠW°¦Vx²JVw_°¥@UV@@wnymknK¯I@²b°£V¥wUV¤nLkÆJÈwôô°l»Č¯ġVUU@@°ÝXl@U»°Å@U¯@w±¯VmUUlm@mÑnIVyUwmak£Vwm±@Çw@n@UxkwlÇnLmkÅ@±kka@kóJV¯Ç»U£lw¯Xalbl¥¯UX@aUaÈL@ÇVIVkaU¯mmakLWkUJ¯Umxn@kUx¯xmWÅīÝkkbŤbkxWmXwWk¯wKkLŤċń@¤óĬU²@@lk¯VmU¯¼@xV@k°l°kbU°nmVnU@°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":["@@lbKVIUa@²m@bxôÒÜxXLmbnl@K°¼kUôxôlV¦nJUÆnm@xÆwbXÆôôLUVwôK@wlmaVw@WknmIUmlnJla@_@kÝmKUaÑm¯Xw°aUaVl»²JVbÆJkôĶĀ²VVkmbVwUówVwnLlmk¯maVw²¥Wk@XmV_WnÑUk@kó»UV¥ÝmVÑÅaÝUçV@¯VUmn¯mVlak¯l¯U@@wğWé¯@¯xÝw¯¯Jċa¯U¥mLU¤bÞȤbÇLWUwmIUVW¼kb`UVb¯L±ĊÛkÿÝKkwKţêUĉþÈV¯ÞVbU°KVk²ÝmImV@kmUkVxm¯KXÈķJU¦V°ULWxL@môb@bkx±LnVUVLnkÜWnwlLŃmW@kkJU_VWĊÞ"],"encodeOffsets":[[101408,26770]]}},{"type":"Feature","id":"5309","properties":{"name":"临沧市","cp":[99.613,24.0546],"childNum":8},"geometry":{"type":"Polygon","coordinates":["@@xĢl`²X°Vx@x°Þ°KXağUÑWbnIl`X²°bxl°V@xVxk¦mbl@xXVÆzX¤Æk°kx@lźêlaX»VUnJVxXÈKaÝȣaV£nKV¦°Čb°I°n»ÆÑV¯nWn@ÿXÅWWn¹ġōn»ÛUaUVUww@w°ó¥@z±@ř¯@kUwlk£±aĵ¯Uĵ¦±±@bó±VÝ@ó¤w¯I@mÅóm±X¯IólK@°UllbzkKlln@@ÔºUmVk²ôÒxŎUVóLbmÈnmbnlax@z@Ʀk"],"encodeOffsets":[[101251,24734]]}},{"type":"Feature","id":"5334","properties":{"name":"迪庆藏族自治州","cp":[99.4592,27.9327],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@WXw@akk@yk°īX¥Uóķ¯w@n»UaVaUÛ¯mV¼kÞċô@n¯xÛÒmV¯Ô@x@kwmÅa@UaݯVÅyVa@ÿn»ÝVmankmmÞÅô@n£±ğzÇmU¦VmnÜmbn@°nV@xmzÅ@mºV¦k°ln¤¼õôn@xkÆIUxU@Ť¦VmVkmkXW¤XzVx@Æx¼Þ¯b@lVĸÞVm¼Xm¦VÞ@ƹVón¥ÆKnKX¯x@èĊȱłXaÆxnlV@UÛlȻkğV¥m²ljmÅÞĕƒƛm°ÆmX¤mznÆV¦ÞVVb°bnÞWbn°l@VÈ@VĵĊ±@óInxÆw¥@£ÞW¯ĸ£UUKk±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":["@@mnK@wmUÅ¥móXǓŏmX@VmL@xţnk@mlUŻÒğŋ@L@mmLkm@bXÅW¼ka¯lÇŹ¯aÇ»ÝÝ_@m@@a@UklwUm@ak@bUmbmbV¯ĕUaVwÅaĉVmým¯xUk@k¥VUX¤VÈm`@ńÇÜ@ĀknĔkƞÆĠÞUVôƆÞI@UxƦnl@ĊĊnxUÒ°¦Vb¯WUnWIml@xnUbô¤¼ÈxlI»KV@ÈÔJkUĖ±ÆVb@nVÜVUVLwĠlknĠ@nx°¥Æ²mUw@mmÅUl¯UÑÑUmLllIl±@VkwW@w°@U»kUóI°»ĢÑL`nUĠ²lmbôV@nJUxƦX¦l@ŎUV@lVKVÅV£UaÞUnW@¯VU@ó"],"encodeOffsets":[[107787,28244]]}},{"type":"Feature","id":"5301","properties":{"name":"昆明市","cp":[102.9199,25.4663],"childNum":11},"geometry":{"type":"Polygon","coordinates":["@@n@VkVUn²°@x°V@¯ÆV¼k@WÞ¯@@VVUĢċ°k¼VĊx¤Ōx°mVkÑÈL°x°X°VmĊLVxUĖ°bX¦VW@kȯlkn@¥ln@»°Ñ¯VmlLUwVK@V@ka@lmXbUlVlkÈx@LVaVVwnmm@km@mIVaÝ@XVUݯU@Ý£k»K@aUwkKV_¥a@alU@nz°aVÈ@@±lÛk@wVakm@Ñ¥az@XxÆW@ÛX@m@y@aWw@kōĉJlbVJzţÆUwVkmWkým@UlU@b¯wVºUVUêĠXUaUbVĊUWXUmkKWnUUUVVVÝ@kk±¯Lk±WkXlVkl@wXbmLVUIVmk@Ubma@kkaVKUkmlXLWnJ¯ÒĊ°@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°ÓUnÜÑ°w@mČóÝlU»n°VÜUbVbm¼@°xôĸVW¦¯Ĭl@zll@bWxXaX@ÆĠÆaXwl@XaƦn¼Jn@mnKW¯È»V¯°akVanXVwl@VyUĕVUbÈīlaUk°k¯l²VUkƛô@I@mVwĊaVakaÆbUVLaXIWKUwaWÑÅKUaVk°@Uw¯¥XğÝLkm¯IÇóѯ»anUl±UĵÿlóÅIaU±Ik¼UVb¯bWxn°ÒVbnLlÞ@@`kbmIkVnJmnXl@Uxbkn@xóLUxVKóóÅWaÅxw@nÅmVôXLlVU¤b¦m¼@ĀbUzUÆ°ÞVb@Æbnx"],"encodeOffsets":[[101937,28227]]}},{"type":"Feature","id":"5328","properties":{"name":"西双版纳傣族自治州","cp":[100.8984,21.8628],"childNum":3},"geometry":{"type":"Polygon","coordinates":["@@l²°nÒlxÞ@nWlLĸnbV¤V¦kbVV¦nax°Vôa@b@lôXlWUVXČKlmU@bWXXÜ°LÈa°LnU°ÞnÑġ°lnba¯¯KWó@kmK@UĉV@k°VV¹a@y_ċl_nÓlL@anI@óWl£VUlkĕlKVwU@kVam¯ÅL@bÝk@VnUbÇbÝwÅ@ċ¥¯lk¼ÅÒ°b@¦nlUn@ÇVmÆbWôU@ÝÅōm¯aUmkWWw@±n¯UèaL¯mLkwl@°mnÈÒ¯ów@VxĀ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ޣȺlkUUw¯UĕVwĊ@n¦mlnVĸIWÇ°LnUwlVn@lnUnJÞl±U¯LVUa°ÝUÇĊýVŤéLlxÞLĀÜl²ĉ°KUaV_Źé@klw¯lÅW£ÅyUW@wknal¥Uw@wUk¯w¯aW±k_mJaXVÒĠWb¯L¯Ý@wwU¯±Wk_ġwwōKmb@¤bk°lĖôUJVnÅlťU¯°VbnbWxXmÞWUĀLyWzÛKmbUxVKknÝkVĀċ¤Ux@¯m@¦"],"encodeOffsets":[[100440,25943]]}},{"type":"Feature","id":"5304","properties":{"name":"玉溪市","cp":[101.9312,23.8898],"childNum":9},"geometry":{"type":"Polygon","coordinates":["@@lL°xXlWxXnlwaţlaÞlÆĬnX°wVwl@mnw°VVIXllKbnnV°lbUUJ@ÈÇKVb@bW°Vk¦kaWb°kxV¤È¼U°ôI@llbl²@@ó@mm@VţkKl¹@yĉ¯°ÑIXmWKnklVULlb@lnbVal@UnVJUnKWax@lkkUlW²XlK°l²@lÞUUUVVVXmlLVnXWVUĉVaVbWğVéUVU¹W»aVaaWX_U¥nÇķ¯@alUnÇUyk@@wW@kbW¦UKÝwUmmLUnVxUVVlk¯mmnmkÇaŤ¯I@l@@aĉw°ĕmUL±kÆéXÜÛ@yÈç@ÇġÝķXmmÝVÅlmnkbmWkb@nl@nm¯VxkJmUJml¯°makVVnV¦WWmnl@xmnlI¤nxUVUmX@b@zl@¦Ýþ"],"encodeOffsets":[[103703,24874]]}},{"type":"Feature","id":"5333","properties":{"name":"怒江傈僳族自治州","cp":[99.1516,26.5594],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@WyX£lWlnnUU¥@ţVVwJlÅ@wmöó»£kml¯U¥n¹Æ@ny@wmU@¯mnamÛnUV¥ÈnĠy²m¤@ÆónÝnmlnbÞU¥aV£kUKWómIU¥ókwVól»¯Lk@mnaWKÛwóÑw@a±n@VbUJLkaÝXĉUV`lI@lnXÆƑkKmxÛXmlUKVmU²Klw@aaó@nKXwVKU¯V¥mUnkm¥ĉ@UxVĖ°VxVklmÞkKWĀkVWnl°Lnm@°UxlV@nk¦JVÈ°VÒ@nX°@ÆlUômlnô²nxmłnVV¯x@Èm°XblVUl°@xkXU¤WXXWXÆmkÅJmÞw±bxUīkKmÅVUĖÝèVkx@lXlnk¤LkĖk¦xUL°¯Ė@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Č£ÿUlÞlmULVwnaÜLXyzKVÿXÝnWXwmaUa°¯VŦÆkUmVIókĕl¯a@£nama@¯m¯ó@óyţbġkÅm±ÛammVkLwU`Wk@VkUmÅlUUKmbkkUVUw¦ó°¼bn°ô¦lºz@x¯@U°nU¤ţU°VƆ@ÈmlnzÞl°¦ÆaxUxLkxWƒ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":["@@@VbVl@XnUXKV@¦nxlUXVnKVmnLUV@bn¤lLXK²`nnlJXIVJIVnn°KnnVll@VLXWV@UkVaVKzV@VVaUK@U»VUl@@WnUU@wVLn@Vwl@XW°LVbn@VU@Xl`@XnKVbkl@XVJlUnlVxlL@lnXl@VUnV°°@aUVLXblWVXn@VVUV@L¤VLVUVbnalLUUVX_laVaWVzXKV@@a@KUmImmXama@kU@yVIUKaVa@kXK@aWU@VIUmW@kkVmU@VwUa@K@k@U`@kUKVk@UV@VaUm²Vy@klUUWUkVmUa@_KVaXaXmU@mUlWkaUX@mmkL@wJnVVÅbWKXa@@I@aJUUÇ@VULW@akLmb@K@aXXw@mVmUVkUy@£@aU@@VkUWm@kUKXUWU_mW@wkkmJUUkLWWUXW@IkJ@k@mW_kÓ_UlLm@I@aUa¯m@ka¯LUJ@mVVxUba@LUKkXbm@Uak@@a@Um`IUbUJ@nUVW@@LnVV@lUbVlUX@`@blXklWUmXlm¦U@@V¯bml@@nUb@llnn@VbX@lV@UVULmU@JVnbVbkbVWxU@@nUVk@"],"encodeOffsets":[[121546,28992]]}},{"type":"Feature","id":"3301","properties":{"name":"杭州市","cp":[119.5313,29.8773],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@X@l°KXXlWb@²`bIX`l@@bWl@n@VnLUV@V@°¦@l@XVlU@@xVbUb@Vkb@@XVJVzJ@LÞ@VmLUxUJ@LUVxbxXUl@VaÈwbaÞa@Vl@XUVx@V@VLlbnVal@lbVnnLnKnL@VlbVJXalIb@KUU@mVInJUVl@xUVLnU@UÞaV@lkV@UanKL@UlKVUnbÆmn@@nUlVnVJl@@UXUL@WVIVJVxVLXV@IÜKnbn@V¥V@@I@y°b@UUwnk°ÆƨVlUçXm£aÇIkV@WV@@aWIUWUIkb@WW@UnK@UU@kaWVkVIVVnU@UWVUV@VmVkKkWIkVWaULU`UImJUImmU@wmwUVIUWVkUamaU@mVkb@KVU@aVU@anKULVJU@kÛUJUVkkVakU@aVwkW@UWkXmWaULUaUK@XJUUmVU@UVUkJ@ImwmKU@k@lUW@@akKmkamIkWl_UwVm@UkaVUUa@UamakbWlkL@aUalU@mkL@U@UlmK@XkKm@Ýakb@xnXb`nUUU@U@wU@@mKkkV¯U@lULUbVbUb@Va@LºÝb@bLmKx@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`VXWVL@lXnlV@UV@@b@¤VzUlnVU@nWxW@b@LnalK@bXVKUÈ@VVI@b@J@WbXLÆaUUmI@xlKnn@VWlbkXV@nVWnWbUbL@`VbUnVlVXkV@lUz±VnUbU@@VUlVL@l_@V@l@LVbV@XLV`VÈlxn@lU@aaVVk@XJ@nl@@LU`°LVbL°a@aUVy@anI@aanV@²wÜJX@VVV°kna@WVkaWwU@m@kaUĕÝÝŤnÈaaóI»@±XWkUķ@kV±kwUkWwUÝ»ÛkɳlImaUaWóXÿǬkUnWVmmkKţnŏÞğlUlUx@XWbV@JkX°mb@VULVxUVk@@LWWk@WIkUkJmUkVmI@y@UakLmU@mUUUkaVk@mK@UlUU@UmKmbUUUJ@n@KVLUL@VkJWXX`mnULWlkL@JVLVb@°kxkU@LVV@VLV`UL@VUX"],"encodeOffsets":[[122502,28334]]}},{"type":"Feature","id":"3302","properties":{"name":"宁波市","cp":[121.5967,29.6466],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@Ċ¦ĸĀ°nXÞVKkƨƑźÿ°»n@wô¥ÜbU°ÆXÞWóçĉݱIUÈ¥@U°wÆ»²mm_@aXVKÞVlk@akk̅@£X»VwÆXWa¯aȗbKƽŰĊxLók@@¯nKUL@xkLÑkWULUUmJUXVU@mUX¯@V`mbXbV@@nn¤WXx@kJ@nVVUVl²UbÝVUVk@Wx@V@VXzmlaL@VlLU`XUVVVUnl@VbnJlnUVVnlUKkbmnnVxlJnxmbU@UL@KUVX@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ÑÆwlƏÈóVĭVǓ@ĉwɛkmK@ĉXīWaĉUĵÝm¯ĉwĉ±±nż¯x@VǦV²JĊÞôèÝXÅW¯VÛaó¦@xm¯¼ŹĀ"],"encodeOffsets":[[124437,30983]]}},{"type":"Feature","id":"3310","properties":{"name":"台州市","cp":[121.1353,28.6688],"childNum":7},"geometry":{"type":"Polygon","coordinates":["@@lVIVWVz@bXJl@Xal@°nLll@nVxnVK@UJVb¦°k`UIWJXnÆ@bUJXl@lbWn@UzVV@bVVmVnnJVXnabKUKnUVVUnVLlKVLXaJm£@mU@WanaU_°@VWnV@UVWnIVVVKlXÒlK@wVKL°m@l@ôKwĉƾůUl£@»UVkm@ƅUaÛIŏmUk@mw@a£Wk@ţIm±@ankôUlaUUw¯ōabÇbţmÞÞVĖbl@@nVXxbUl@Xmb¯lUUUW@ÛI±xU@mb@bmJ@bUzV@b¯bKUa¯KV_@Kk@@mWI@lUUb@bkVm@kwUÇU_WKU@Ux@VUnllX@VnJ@UXV@bWL@lUbbVLUJ@zV@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`lXnJlbnlL@bX@V@klV@nLnx@JlIVU@VUVnVVI@WVLVbVKXbWnXl@VlXUxb@lVUbllVUIÜVnalKX@@bV@@aUUlUwUw@naWWUVaUUaVbLlxXJVk°UlkU¥@ka@LVlXLVlVWznVn@lxJl_@WX_@mVaa@alU@kVVnaKVLlKb@UUaVabnUWmXU@k@yVI@aÅWmXIVJl_¯¥UaVI@LmUUw@mkkmK¯k@Wbk@WI@aUyUXJkU@bU@WLUyXUbkbW`UVVkKmbUaVUUK£@KVUUUm@UWkXWaUKV@b¯¯mUV@UkmW@kkKwUmkkVUI@WlkUamL@Wk_W@UVm@Ua¯KWXk@Uxm@UK@xVmV@Xk@UVV¼@VLUbUU@yULUbVlU@@XlVUVVbU@lXXVW@XUVl@@VUVÈn@VVU@lVa@UmL@`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@UwnLK@aÞa¹@Kb@UVaUaVaVK@k°VUllnL@V@xV@V@VVm_Wam@wlaÞbn@lL@WnLk@V@VlK@nkVVb@blKXklakw@wVK@kVW@UXK@_W@_nKV@Ub@kVUUm@ÇVU@Uk@VU@WUXWW@kVUaVUkU@WWXUKk@Ukmm¯LmmUJUIWJkImm_±WLkKm£@aVUmKUnLmWUkVmw@¥ULVWm@WUka@UmmLmm@@bUX@@WUIm@UVUK@UVUUUVVJmb@bXnmV¼nnn¦mJUVLV@VW@UzUlVnUbl`UnVl@XU@kl@bmÈUxVk@@J@¼W@ÅaVVnzmV@WJk@kWJ@lXbWbXxmVnlLXb@°lKVXnWbWVXmbV@XlbI@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_VKXblUXJllLUUnU@UVVX@mVUUUJlXUlbV@@VLVmX@@XlaVJVXXJ@b@XU@lUJÈb¤ŌJçVUUnml@@kna@wWVU@LVKV@namwkIUwmnmlaVLkUmVUkmmIUak@VmUUVUWV_kK@UKbnkWyU@@UXwl@VUÞUVak±VUUU@mlI@wXWIWbUKkLUKVmUUmVVLLambUWmIUmnUU@aUUVym@Xkak@W@z@lWVXnmVaUbVb@VakLUKLmbUU@lkV@bbUb@nW`@Xk`Ikwm@mUXyUUkWKUk@Kb@lV¦klV¯UlWIkwKUabVVUbVXXmb@VxxkVVV@bU@@aW@kLmb@lVUIVKmL@bUV@bUV@LalnUV@nbVbUlVXJVUnx"],"encodeOffsets":[[122997,30561]]}},{"type":"Feature","id":"3304","properties":{"name":"嘉兴市","cp":[120.9155,30.6354],"childNum":6},"geometry":{"type":"Polygon","coordinates":["@@@blIX@@VÜVUnn@lklKnI°Þl`²LVKVbnbVaVLUVn@W¦@VkVVb@VI`@blLnLaX@VVb@U@XlVa@@kVaUKV»U_lWXU@albk@VllnLVKn@@UVIUw@y°IVVXU@VV@lwm@wVkƾaJLkΡƧƒlLÝUmW¯ķÿĉ¥IŋWnèkVƧU¯ÅmlVx@V¯az@@JU@U¦m@@nVmn@VLV"],"encodeOffsets":[[123233,31382]]}},{"type":"Feature","id":"3305","properties":{"name":"湖州市","cp":[119.8608,30.7782],"childNum":4},"geometry":{"type":"Polygon","coordinates":["@@kLlkm@VmÛU@UW@kJ@aUK@UnmmU@maÛL@JWUUKUwUIUJ@XKWV@Vk@UIUmVk@mm@ÅnmaUVkL@VKmLVbU@klU@ÝbV@mVUKV@wUkVmIUJ@nVV@LakJWbUIka@UmKmLKmmUUVk@@nmLX`WXUV@@nUlkmlU@UbxVVIlVnn@@nUÒ@°n@@xmb@VbnV@@b@`@L@L@x@blVklVbnnV@aXb°VlU@Wb°ULXWVUVVwÈwÜ»ĸaĠnUVw²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] || [];
|
| xMarkMap[seriesIndex] = xMarkMap[seriesIndex]
|
| || {
|
| min : Number.POSITIVE_INFINITY,
|
| max : Number.NEGATIVE_INFINITY,
|
| sum : 0,
|
| counter : 0,
|
| average : 0
|
| };
|
| 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]
|
| );
|
|
|
| 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];
|
| if (xMarkMap[seriesIndex].counter > 0) {
|
| 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] || [];
|
| xMarkMap[seriesIndex] = xMarkMap[seriesIndex]
|
| || {
|
| min : Number.POSITIVE_INFINITY,
|
| max : Number.NEGATIVE_INFINITY,
|
| sum : 0,
|
| counter : 0,
|
| average : 0
|
| };
|
| 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]
|
| );
|
|
|
| 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];
|
| if (xMarkMap[seriesIndex].counter > 0) {
|
| xMarkMap[seriesIndex].average =
|
| (xMarkMap[seriesIndex].sum / xMarkMap[seriesIndex].counter).toFixed(2)
|
| - 0;
|
| }
|
|
|
| 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)
|
| : '-';
|
| xMarkMap[seriesIndex] = xMarkMap[seriesIndex]
|
| || {
|
| min : Number.POSITIVE_INFINITY,
|
| max : Number.NEGATIVE_INFINITY,
|
| sum : 0,
|
| counter : 0,
|
| average : 0
|
| };
|
| 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][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];
|
| if (xMarkMap[seriesIndex].counter > 0) {
|
| 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)
|
| : '-';
|
| xMarkMap[seriesIndex] = xMarkMap[seriesIndex]
|
| || {
|
| min : Number.POSITIVE_INFINITY,
|
| max : Number.NEGATIVE_INFINITY,
|
| sum : 0,
|
| counter : 0,
|
| average : 0
|
| };
|
| 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][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];
|
| if (xMarkMap[seriesIndex].counter > 0) {
|
| xMarkMap[seriesIndex].average =
|
| (xMarkMap[seriesIndex].sum / xMarkMap[seriesIndex].counter).toFixed(2)
|
| - 0;
|
| }
|
|
|
| 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"); |
| }); |