Echarts堆叠条形图——各班在各个月份男生、女生迟到次数统计

提前准备好echarts.js官网下载地址:http://echarts.baidu.com/download.html

先定义一个data,用来存需要统计的数据(可以看做是请求返回的JSON数据):

var data =  {
"month_start":"2017-11" ,
"month_end":"2018-04",
"resultlist":[{"time":"2017-11","sex_no":"-1","class_no":"1","times_sum":"3"},
            {"time":"2017-11","sex_no":"0","class_no":"1","times_sum":"9"},
            {"time":"2017-11","sex_no":"1","class_no":"1","times_sum":"7"},
            {"time":"2017-11","sex_no":"-1","class_no":"2","times_sum":"5"},
            {"time":"2017-11","sex_no":"2","class_no":"2","times_sum":"5"},
            {"time":"2017-11","sex_no":"3","class_no":"2","times_sum":"2"},
            {"time":"2017-11","sex_no":"4","class_no":"3","times_sum":"4"},
            {"time":"2017-11","sex_no":"-1","class_no":"4","times_sum":"4"},
            {"time":"2017-11","sex_no":"6","class_no":"4","times_sum":"4"},
            {"time":"2017-11","sex_no":"7","class_no":"4","times_sum":"7"},
            {"time":"2017-12","sex_no":"-1","class_no":"1","times_sum":"2"},
            {"time":"2017-12","sex_no":"0","class_no":"1","times_sum":"24"},
            {"time":"2017-12","sex_no":"1","class_no":"1","times_sum":"24"},
            {"time":"2017-12","sex_no":"-1","class_no":"2","times_sum":"6"},
            {"time":"2017-12","sex_no":"2","class_no":"2","times_sum":"5"},
            {"time":"2017-12","sex_no":"3","class_no":"2","times_sum":"8"},
            {"time":"2017-12","sex_no":"-1","class_no":"3","times_sum":"6"},
            {"time":"2017-12","sex_no":"4","class_no":"3","times_sum":"5"},
            {"time":"2017-12","sex_no":"5","class_no":"3","times_sum":"10"},
            {"time":"2017-12","sex_no":"-1","class_no":"4","times_sum":"1"},
            {"time":"2017-12","sex_no":"6","class_no":"4","times_sum":"7"},
            {"time":"2017-12","sex_no":"7","class_no":"4","times_sum":"10"},
            {"time":"2018-01","sex_no":"0","class_no":"1","times_sum":"25"},
            {"time":"2018-01","sex_no":"1","class_no":"1","times_sum":"34"},
            {"time":"2018-01","sex_no":"-1","class_no":"2","times_sum":"4"},
            {"time":"2018-01","sex_no":"2","class_no":"2","times_sum":"12"},
            {"time":"2018-01","sex_no":"3","class_no":"2","times_sum":"15"},
            {"time":"2018-01","sex_no":"-1","class_no":"3","times_sum":"3"},
            {"time":"2018-01","sex_no":"4","class_no":"3","times_sum":"4"},
            {"time":"2018-01","sex_no":"5","class_no":"3","times_sum":"15"},
            {"time":"2018-01","sex_no":"-1","class_no":"4","times_sum":"3"},
            {"time":"2018-01","sex_no":"6","class_no":"4","times_sum":"20"},
            {"time":"2018-01","sex_no":"7","class_no":"4","times_sum":"14"},
            {"time":"2018-02","sex_no":"0","class_no":"1","times_sum":"8"},
            {"time":"2018-02","sex_no":"1","class_no":"1","times_sum":"12"},
            {"time":"2018-02","sex_no":"-1","class_no":"2","times_sum":"1"},
            {"time":"2018-02","sex_no":"2","class_no":"2","times_sum":"2"},
            {"time":"2018-02","sex_no":"3","class_no":"2","times_sum":"9"},
            {"time":"2018-02","sex_no":"-1","class_no":"4","times_sum":"2"},
            {"time":"2018-02","sex_no":"6","class_no":"4","times_sum":"12"},
            {"time":"2018-02","sex_no":"7","class_no":"4","times_sum":"10"},
            {"time":"2018-03","sex_no":"-1","class_no":"1","times_sum":"1"},
            {"time":"2018-03","sex_no":"0","class_no":"1","times_sum":"2"},
            {"time":"2018-03","sex_no":"1","class_no":"1","times_sum":"2"},
            {"time":"2018-03","sex_no":"-1","class_no":"2","times_sum":"1"},
            {"time":"2018-04","sex_no":"-1","class_no":"2","times_sum":"1"},
            {"time":"2018-04","sex_no":"2","class_no":"3","times_sum":"20"},
            {"time":"2018-04","sex_no":"1","class_no":"4","times_sum":"5"},
            {"time":"2018-04","sex_no":"5","class_no":"1","times_sum":"7"}]
};

其中,time是月份,class_no是班级编号,times_sum是迟到次数,sex_no等于-1是冗余数据,其余的0、1代表一班男生、女生,2、3代表二班男生、女生,4、5代表三班男生、女生,6、7代表四班男生、女生(为什么要这样呢?后面会慢慢讲到)

最终实现效果:

Echarts堆叠条形图——各班在各个月份男生、女生迟到次数统计_第1张图片

Echarts堆叠条形图——各班在各个月份男生、女生迟到次数统计_第2张图片

先定义一个方法,根据传入开始月份和结束月份,返回一个月份数组(月份格式为:yyyy-mm):

/*根据始末月份获取该范围内所有月份*/
function getAllMonth(time_s,time_e) {
	var startTime = new Date(time_s).getTime();//  转换为时间戳
	var endTime = new Date(time_e).getTime();// 转换为时间戳
	var arr = [];// 存放结果
	var format  = function(time) {// 最后的格式转换
	    var date = new Date(time);
	    return (date.getMonth() < 9)?(date.getFullYear() + '-0' + (date.getMonth() + 1)):(date.getFullYear() + '-' + (date.getMonth() + 1));//1-9?£???油0
	};
	var isLeapYear = function(year) { 
		return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);// 判断是否为闰年
	};
	// 月份映射 假设不为闰年
	var MONTH = {
	    '1': 31,
	    '2': 28,
	    '3': 31,
	    '4': 30,
	    '5': 31,
	    '6': 30,
	    '7': 31,
	    '8': 31,
	    '9': 30,
	    '10': 31,
	    '11': 30,
	    '12': 31
	};
	arr.push(time_s);
	if(time_s!=time_e){
		while (startTime < endTime) {
		    var start = new Date(startTime);// 转换时间格式
		    if (isLeapYear(start.getFullYear()) && (start.getMonth() + 1 === 2)) {// 判断是否为闰年的2月份
		        startTime = startTime + 29 * 24 * 60 * 60 * 1000;
		    } else {
		        startTime = startTime + MONTH[start.getMonth() + 1] * 24 * 60 * 60 * 1000;
		    }
		    arr.push(format(startTime));
		}
	}
	return arr;
}

获取月份范围数组,定义纵坐标:

var timeArr = getAllMonth(month_s,month_e);// 获取月份范围数组
var classNOArr = ['一班男生迟到次数','一班女生迟到次数','二班男生迟到次数','二班女生迟到次数',
    '三班男生迟到次数','三班女生迟到次数','四班男生迟到次数','四班女生迟到次数'];//纵坐标

需要将data数据不同月份、不同班级存到一个二维数组中(目前的例子有6个月,4个班级(男、女又各一组)),结构如下图:

Echarts堆叠条形图——各班在各个月份男生、女生迟到次数统计_第3张图片

因此,上面提到的sex_no:0、1代表一班男生、女生,2、3代表二班男生、女生,4、5代表三班男生、女生,6、7代表四班男生、女生,正好对应二维数组的各行。所以,初始化为8X6的二维数组,初始元素全部为0。

//二维数组定义与初始化
var dataArr = new Array();
for(var i = 0; i < classNOArr.length; i++){
	dataArr[i] = new Array();
      for(var j = 0; j < timeArr.length; j++){
      	dataArr[i][j] = 0;
      }
}

将sex_no作为二维数组的行下标,将原始的data数据分别存放的对应二维数组的位置,作为最终的绘图数据。

var list = (data.resultlist || []).sort(function(v1,v2){
	return v1["time"] < v2["time"]?-1:1;//字符串比较,排序时间
});
//数据放入二维数组
for (var i = 0; i < list.length; i++) {
	if(list[i]["sex_no"] != -1){
		dataArr[list[i]["sex_no"]][timeArr.indexOf(list[i]["time"])] = list[i]["times_sum"];
	}
}

定义series数据系列:

var seriesData = new Array();//series数据系列
for(var i = 0; i < timeArr.length;i++){
	seriesData[i] = new Array();
}

将二维数组数据塞入series数据系列,并定义数据视图的表头、表格主体:

typeArr = classNOArr;
var length1 = 0;//循环遍历参数
var length2 = dataArr.length;//循环遍历参数
initData(length1,length2);
	
function initData(length1,length2){
 	for(var i = length1; i < length2;i++){
 		for(var j = 0; j < seriesData.length;j++){
 			seriesData[j].push(dataArr[i][j]); 
 		}
 }
   table_header = ' ';
   for(var i = length1; i < length2; i++){
	   table_header += ''+classNOArr[i]+'';
 }
 for(var i = 0; i < timeArr.length; i++){
   table_body += ''
 				   + '' 
 				   + '' //数据视图彩色图例
 					+ timeArr[i]+'';
   for(var j = length1; j < length2; j++){
	   table_body +=''+dataArr[j][i]+'';
   }
 	table_body += '';
 }
}

开始画图:

//series数据统一处理
function seriesArr(){
	var serie = [];
	for(var i = 0; i < timeArr.length; i++){
	var item = {
	           name:timeArr[i],
	           type:'bar',
	           barMaxWidth : 50,
	           stack: '各班迟到次数统计',
	           data : seriesData[i],
	           itemStyle: {
	        	   normal:{
	        		   color:colorArr[i]
	        	   }
	           }
	         };
	serie.push(item);
	}
	return serie;
}

var myChart = echarts.init(DOM.get('#main'));
option = {
	    tooltip : { //tooltip:气泡提示框,常用于展现更详细的数据
	        trigger: 'item',    //或'axis'
	        axisPointer : {            // 坐标轴指示器,坐标轴触发有效
	            type : 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
	        }
	    },
	    legend : {//legend:图例,表述数据和图形的关联
	    	data:timeArr
	    },
	    toolbox : {
			right : "10%",
			show : true,
			feature : {
				mark : {
					show : true
				},
				dataView : {
					show : true,
					readOnly : true,
					optionToContent: function(opt) {
					    var series = opt.series;
					    var table = '
' +'' + table_header + '' + table_body + '
'; return table; } }, restore : { show : false }, saveAsImage : { show : true }, } }, grid : { //grid:直角坐标系中除坐标轴外的绘图网格,用于定义直角系整体布局 left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis : [//xAxis: 直角坐标系中的横轴,通常并默认为类目型 { type : 'value', ////坐标轴类型,横轴默认为类目型'category',纵轴默认为数值型'value' } ], yAxis : [ //yAxis 直角坐标系中的纵轴,通常并默认为数值型 { type : 'category', //坐标轴类型,横轴默认为类目型'category',纵轴默认为数值型'value' data : typeArr, name : '班级' } ], series : seriesArr() //数据系列 }; myChart.setOption(option); //图例点击事件,全部取消选中时纵坐标显示为空。 myChart.on('legendselectchanged', function(obj) { // console.log(option.yAxis[0].data); var selected = obj.selected; var option = myChart.getOption(); // myChart.clear(); for(var i = 0,j = 0;i < timeArr.length;i++){ if(selected[timeArr[i]] == false) j += 1; } if(j == timeArr.length){ for(var i = 0;i < timeArr.length;i++){ selected[timeArr[i]] = true; } } myChart.setOption(option,true); }); }

完整代码:




    
    echarts应用
    
    



    

代码还存在一些问题,后续添加一些简单功能并逐渐完善,比如说实现可选定只查某一个班级的数据等等。

希望我的分享能让学习相关知识的同学有所收获,欢迎大家批评指正,有什么好的方法和建议欢迎大家指教,万分感谢!

你可能感兴趣的:(前端学习笔记)