百度Echarts 全国省市地图 动态数据图形报表


最近有个挺好玩的需求:需要将分布在全国各地的系统用户数量统计出来,以地图的形式展示出每个地域的用户数量。

此前我一直用的是highcharts,怎奈highcharts不支持地图报表,于是转而使用百度的Echarts,Echarts本身的功能没的说,很赞,API也很详细,但是网上貌似玩的人不多,于是自己动手参照官方demo耍耍。

先展示下最终实现效果,如果诸位看官感觉效果还不错,欢迎继续向下看,如果感觉效果很逊,pls close ~   O(∩_∩)O~



简单的描述下:上述地图中,左侧是展示全国地图(默认选择的是江苏 ps:因为在下目前在江苏 O(∩_∩)O~),右侧是展示的江苏各地市的用户数量,点击左侧的不同省份,右侧地图会随之变化,从而显示不同省市的用户数量。


下面说下具体的实现:

Echarts 官网:http://echarts.baidu.com/

先说下思路:Echarts的样式是很容易在前台jsp定制的,最重要的数据源(如图中的各区域的用户数量)是需要在后台拼装,然后传到前台解析显示的。Echarts页面上获得选择的省名称(如江苏),ajax传入后台,我在数据库中存入的有最新的全国行政区域代码(国家统计局http://www.stats.gov.cn/zjtj/tjbz/xzqhdm/获得),在后台会先通过省名称获得对应的省编码,然后获得其下各市的用户总数量,将这个数量数据拼装然后返回前台解析显示。

代码如下,echarts.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
        <script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/jquery-1.8.3.min.js"></script>
    	<script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/echarts/esl.js"></script>
</head>
  
<body>    
    <div>
		<div id="main" style="float:left;height:500px;width:620px;padding:0px;"></div>
		<div id="pc" style="float:right;height:500px;width:600px;padding:20px;"></div>
	</div>
		<%--注意 此段js只能置于此位置  否则echarts无法正常生成 --%>
		
		<script type="text/javascript">
		var curIndx = 0;
		var mapType = [ // 23个省
		               '江苏', '青海', '四川', '海南', '陕西', 
		               '甘肃', '云南', '湖南', '湖北', '黑龙江',
		               '贵州', '山东', '江西', '河南', '河北',
		               '山西', '安徽', '福建', '浙江', '广东', 
		               '吉林', '辽宁', '台湾',
		               // 5个自治区
		               '新疆', '广西', '宁夏', '内蒙古', '西藏', 
		               // 4个直辖市
		               '北京', '天津', '上海', '重庆',
		               // 2个特别行政区
		               '香港', '澳门'
		             ];
	    var fileLocation = '${pageContext.request.contextPath}/file/scripts/echarts/echarts-map';
	    
	    require.config({
	        paths:{ 
	            'echarts': fileLocation,           
	            'echarts/chart/map': fileLocation,
	        }
	    });
	    var pcChart;
	    var myChart;
	    var colorList;
	    require(
	        [
				'echarts',
				'echarts/chart/map'
	        ],
	        function(ec) {
	            colorList = require('zrender/tool/color').getGradientColors(
	                ['red','yellow','lightskyblue'], 10
	            );
	            myChart = ec.init(document.getElementById('main'));
	            pcChart = ec.init(document.getElementById('pc'));
	            myChart.setOption(getChinaMapChartOption());
	            window.onresize = myChart.resize;
	            var ecConfig = require('echarts/config');
	            myChart.on(ecConfig.EVENT.MAP_SELECTED, mapSelected);  
	            
	            mapSelected(true);  //初始加载江苏各地市   
	        }
	    );
	   
		function getChinaMapChartOption()
		{
			var  chinaMapChartOption = {
			title: {
	        	text : '全国34个省级行政区',
	    	},
		    tooltip : {
		        trigger: 'item'
		    },
		    series : [
		        {
		            tooltip: {
		                trigger: 'item',
		                formatter: '{b}'
		            },
		            name: '中国',
		            type: 'map',
		            mapType: 'china',
		            mapLocation: {
		                x: 'left',
		                width: 600
		            },
		            selectedMode : 'single',
		            itemStyle:{
		                normal:{label:{show:true}},
		                emphasis:{label:{show:true}}
		            },
		            data:[
		                  {name: '江苏', selected:true}
		              ]
		        }
		    	],
		      animation: false
		  };
		  return chinaMapChartOption;
	  	}
	  
	    function mapSelected(param){
	        var len = mapType.length;		   
			var mt = mapType[curIndx % len];
			var selected = param.selected;
			for (var i in selected) {
			       if (selected[i]) {
			              mt = i;
			              while (len--) {
			                 if (mapType[len] == mt) {
			                      curIndx = len;
			                 }
			              }
			             break;
			       }
			}
			$.post('${pageContext.request.contextPath}/usermanager!ajaxUserAreaJson.action',{'provinceName':mt},
	           function(data){
				    datas = eval('(' + data + ')');
					var option = {
		    		    title: {
		    		        text : '江苏',       
		    		    },
		    		    tooltip : {
		    		        trigger: 'item',
		    		        //formatter: '{b}'
		    		    },
		    		    legend: {
		    		        orient: 'vertical',
		    		        x:'right',
		    		        data:['系统用户数量']
		    		    },
		    		    dataRange: {    	 
		    		        min: 0,
		    		        max: 100,   //此处由于echarts的bug 默认的max最小值为100且为100的整数倍       
		    		        color:['orange','yellow'],
		    		        text:['高','低'], // 文本,默认为数值文本
		    		        calculable : true
		    		    },
		    		    toolbox: {
		    		        show : false,
		    		        orient : 'vertical',
		    		        x: 'right',
		    		        y: 'center',
		    		        feature : {
		    		            mark : true,
		    		            dataView : {readOnly: true},
		    		            restore : true,
		    		            saveAsImage : true
		    		        }
		    		    },
		    		    series : [
		    		        {
		    		            name: '系统用户数量',
		    		            type: 'map',
		    		            mapType: 'china',
		    		            selectedMode : 'single',
		    		            itemStyle:{
		    		                normal:{label:{show:true}},
		    		                emphasis:{label:{show:true}}
		    		            },
		    		            data:datas
		    		        }
		    		    ]
		    		};
					option.tooltip.formatter = '{b}:{c}';
					option.series[0].mapType = mt;
					option.title.text = mt + "-系统用户分布";
					pcChart.setOption(option, true);
			});	
	    }
	    </script>
    
</body>
</html>
注意:jsp中的post方法,是动态获得数据的关键,以及获得的data数据eval下,在series中的data中设置数据源即可。其他的东东请参考官网。


后台拼装数据:

实际上后台只要获得如

[{name:'南京市',value:13},{name:'无锡市',value:4},{name:'徐州市',value:4},{name:'连云港市',value:1}]
的字符串即可,或者你也可以叫它json,但是要注意name和value是没有引号的,具体拼装代码就不展示了,你可以用各种姿势获得其。O(∩_∩)O~


这里提下,dataRange中的max属性的获取思路,首先将每个区域下用户总数获取到,进行sort排序取最大值,最大值然后传入如下方法处理,获得返回值同dataJson一起返回页面解析显示即可(上述的例子只是简单的写死max=100,具体如何动态化这个max,请自行思考,其实so easy……):

  /**
	 * 获得echarts的dataRange的max值 max必须为100的整数倍 
	 * 返回值示例:94则返回100 125则返回200 1240则需要返回1300
	 * 
	 * @param ranMax
	 * @return
	 * @see
	 */
    private static int rangeMax(Integer ranMax)
    {
        int max = 100;

        // 小于100 则直接返回100
        if (ranMax <= 100)
        {
            return 100;
        }
        else
        {
            // 能被100整除 直接返回
            if (ranMax % 100 == 0)
            {
                return ranMax;
            }
            // 返回比当前值多100的值
            else
            {
                int m = ranMax / 100;
                max = (m + 1) * 100;
            }
        }
        return max;
    }


综上:最主要的就是jsp的写法,和字符串的拼装。如有不明白之处可以给我留言~


PS:附上echarts作者的地址 http://my.oschina.net/kener   kener@osc


评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值