首先给大家推荐echarts官网:里面什么柱状图,折线图,饼状图都有。
https://echarts.apache.org/examples/zh/index.html 可以去下载对应的echarts样式。

1.效果图如下:

MPAndroidChart显示饼状图能显示占比_html

我这边是根据开始时间,结束时间,用户选择三个下拉来查询饼状图的数据的。2.引入前端样式:(前端主要是bootstrap的样式。可以去官网下载哈)

MPAndroidChart显示饼状图能显示占比_html_02

3.前端代码:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Dashboard</title>
<link rel="stylesheet" href="../static/assets/css/bootstrap.min.css">
<script src="../static/jquery/jquery-3.2.1.min.js"></script>
<script src="../static/bootstrap/js/bootstrap.js"></script>
<script src="../static/js/echarts.min.js"></script>
</head>

<body>
	
	 <div style="margin-left:10px;">
			<div class="form-group" style="width:280px;margin-top:40px;  position:absolute; ">
			    <label  class="control-label mb-1">开始时间</label>
			    <input id="startDateTime" name="startDateTime" type="date" class="form-control" value="" onchange="checkDate(this)">
			</div>
			
			<div class="form-group" style="width:280px;margin-top:40px;margin-left:350px; position:absolute;">
				<label class="control-label mb-1">结束时间</label>
			    <input id="endDateTime" name="endDateTime" type="date" class="form-control" value="" onchange="checkDate(this)">
			</div>
			
			
			<div class="form-group" style="width:280px;margin-top:40px;margin-left:700px; position:absolute;">
				<label class="control-label mb-1">用户选择</label>
				<select id="userNameId" name="type"  class="form-control"></select>
			</div>
			
			 <div class="form-group" style="width:280px;margin-top:63px; margin-left:1050px;position:absolute;">
				<button type="submit" class="btn btn-primary" onclick="refresh()" style="width:80px;">查询</button>
			</div>
	  </div>

      <div id="main_pie"  style="height:600px; width: 850px;margin-top:250px;margin-left:200px;position:absolute;"></div>
				
<script>
	
	
	$(function() {
	    //一进入页面就加载用户选择的下拉框的数据
		onUserNameList();
	});
	
	
	//用来检验开始时间不能大于结束时间
	function checkDate(date){
	    var startDate = $("#startDateTime").val();
	    var endDate = $("#endDateTime").val();
	    if(startDate.length>0 && endDate.length>0){
		    var startDateTemp = startDate.split("-");
		    var endDateTemp = endDate.split("-");
		    var allStartDate = new Date(startDateTemp[0], startDateTemp[1], startDateTemp[2]);
		    var allEndDate = new Date(endDateTemp[0], endDateTemp[1], endDateTemp[2]);
		    if(allStartDate.getTime()>allEndDate.getTime()){
			    alert("开始时间不能大于结束时间,请重新选择");
			    date.value='';
			    return false;
		    }else {
		    	return true;
		    }
	    }
	}
	
	
	//获取下拉框得数据 
	function onUserNameList(){
		$.ajax({
			url : "/dashboard/getUserList",		
			dataType : 'json',
			type : 'GET',
			success : function(dataInfo) {
				 var dataOptions = '<option value="">请选择或搜索查询</option>';
				 $('#userNameId').html(dataOptions);
				 if(dataInfo.length>0){
					 for(var i = 0; i < dataInfo.length; i++){
						 dataOptions +="<option value='"+dataInfo[i].id+"'>"+dataInfo[i].userName+ "</option>";
						 //用户id:dataInfo[i].id
						 //用户名称:dataInfo[i].userName
						 //id和userName必须要和后台接口传过来的名称保持一致。否则前端打印就是undefined的
						 $('#userNameId').html(dataOptions);//拼接到JSP页面
					 }
				 }else{
					 alert("数据为空");
				 }
				 
		    }
	    });
	}
	
	
	 //查询按钮事件
	 function refresh(){
	     //获取下拉框选中的用户id
		 var userId = $('#userNameId').children('option:selected').val();
	     var jsonData = {};
	     jsonData.startTime = $("#startDateTime").val();
	     jsonData.endTime = $("#endDateTime").val();
	     jsonData.userId = userId;
	     //调用展示饼状图的方法
	     echartsPieFuncOne(jsonData);
	 }

 
	    
		
	  var echartsPieFuncOne = function(jsonData){
    	  $.ajax({
    			url : "/dashboard/getBar",
    			dataType : 'json',
    			type : 'GET',
    			//async : false,
    			data: jsonData,//代表传给后端的三个值。startTime,endTime,userId
    			success : function(data) {
    				var json = data;
    				var jsonPieNameX = json.jsonPieRuleNameX;
    				var jsonPieY = json.jsonPieCountY;
    				var pieAllCount = json.pieAllCount;
   					//饼状图的图例名称:jsonPieRuleNameX
   					//饼状图的data数据:jsonPieCountY
   					//饼状图错误的总和:pieAllCount
   					//jsonPieRuleNameX,jsonPieCountY,pieAllCount必须要和后端传过来的map的key是一样。否则前端出现undefined
    				echartsCommonPie(jsonPieNameX, jsonPieY, pieAllCount);
    			}
      	  });
	  }
	      
		
		
	 //饼状图
     function echartsCommonPie(jsonPieNameX, jsonPieY,pieAllCount){
		  var jsonPieX = jsonPieNameX;
		  var jsonPieY = jsonPieY;
		  var pieAllCount = pieAllCount;
		  var myChart = echarts.init(document.getElementById('main_pie'));
		  //myChart.clear();//清空画布,可以加,也可以不加。
		  
	      var option = {
	           title : {
	        	  //subtext: '错误总个数:'+pieAllCount,
	              text: '错误分布数量图(错误总个数:'+pieAllCount+')',
	              x:'center',
	              y:'bottom',
	          },  
	          tooltip : {
	              trigger: 'item',
	              formatter: "{a} <br/>{b} : {c} ({d}%)"
	          },
	          legend: {
	              orient: 'vertical',
	              x:'right',
	              y:'top',
	              itemWidth: 23,   // 设置图例图形的宽
	              itemHeight: 10,  // 设置图例图形的高
	          	  data:jsonPieX
	          },
	          toolbox: {
	              show : true,
	              feature : {
	                  magicType : {
	                      type: ['pie', 'funnel'],
	                      option: {
	                          funnel: {
	                              x: '25%',
	                              width: '50%',
	                              funnelAlign: 'left',
	                              max: 1548
	                          }
	                      }
	                  },
	              }
	          }, 
	          calculable : true,
	          series: [
	              {
	                  name: '错误分布数量',
	                  type: 'pie',
	                  radius: '55%',
	                  //radius: ["40%", "60%"],
	                  center: ['25%', '60%'],
	                  data:jsonPieY,
	                  emphasis: {
	                      itemStyle: {
	                          shadowBlur: 10,
	                          shadowOffsetX: 0,
	                          shadowColor: 'rgba(0, 0, 0, 0.5)'
	                      }
	                  },  
	                  
	                 label: { //去掉指示线
	                  	normal: {
	                  	show: false,
	                  	position: 'inside',
	                  	formatter:"{b}:{d}%"
	                  	}
	                  }, 
	                  
	              }
	          ],
	      };
	      // 为echarts对象加载数据
	      myChart.setOption(option);
	}
	   
	    
	</script>
</body>
</html>

4.后端代码:

A.controller层代码

  
    @RequestMapping(value = "/getUserList")
    @ResponseBody
    public List<UserVo> getUserList() {
    	return dashBoardService.getUserList();
    }

	 @RequestMapping(value = "/getBar")
	 @ResponseBody
	 public  Map<String, Object> getBar(@RequestParam(value = "userId", required = false) int userId,
	    		@RequestParam(value = "startTime", required = false) String startTime,
	    		@RequestParam(value = "endTime", required = false) String endTime) {
    	 Map<String, Object> jsonMap = new HashMap<>();
    	 if(startTime!=null && startTime!="") {
    		 startTime = startTime.replaceAll("-", "/");
    	 }
    	 if(endTime!=null && endTime!="") {
    		 endTime = endTime.replaceAll("-", "/");
    	 }
    	 //根据userId查询所有的用户
    	 UserVo vo = userService.getUserInfoById(userId);
    	 //饼状图
         List<String> listPieRuleNameX = new ArrayList<>();
   	     List<Map<String, Object>> listPieCountY = new ArrayList<>();
   	     Map<String, Integer> mapPieName = dashBoardService.getEchartsPieCount(vo.getUserName(), startTime, endTime);
   	     int pieAllCount = 0;
   	     for (String pieName : mapPieName.keySet()) {
 	    	 Map<String, Object> mps=new HashMap<String, Object>();
        	 mps.put("value", mapPieName.get(pieName));
        	 mps.put("name", pieName);
        	 listPieRuleNameX.add(pieName);
	         listPieCountY.add(mps);
	         //错误总个数
	         int temp = mapPieName.get(pieName);
	         pieAllCount+=temp;
   	     }
   	     jsonMap.put("jsonPieRuleNameX", listPieRuleNameX);
	  	 jsonMap.put("jsonPieCountY", listPieCountY);
	  	 jsonMap.put("pieAllCount", pieAllCount);
	     return jsonMap;
	 }


B.service层代码

	public List<UserVo> getUserList() {
			 return userDao.getUserList();
	}
	
	 public Map<String, Integer> getEchartsPieCount(String userName, String startTime, String endTime){
	    	Map<String, Integer> allPCBNameMap = getAllPCBNameMap();
	    	List<String> dashBoardList = dashBoardDao.getEachCountByTime(userName, startTime, endTime);
	    	for (String d : dashBoardList) {
				//String arrCount = d.getErrorEachCount();
				String[] arr = d.split(";");
			    Map<String, Integer> newMap = new HashMap<>();
			    for (int i = 0; i < arr.length; i++) {
		            String[] ruleArr = arr[i].split(":");
		            newMap.put(ruleArr[0], Integer.parseInt(ruleArr[1]));
		        }
		        newMap.forEach((key,value) -> allPCBNameMap.merge(key,value,Integer::sum));//合并两个map,key相同value相加
	    	}
			return allPCBNameMap;
	}


C.dao层代码


    //代表表名
	private String projectsTable = "projects";
	
	private String userTable = "sys_user";
	
	
    //得到所有用户信息
    public List<UserVo> getUserList() {
        ArrayList<UserVo> list = new ArrayList<>();
        StringBuffer sf = new StringBuffer();
        sf.append("SELECT id,user_name FROM " + userTable );
        SqlRowSet rs = jt.queryForRowSet(sf.toString(), new Object[] {  }, new int[] { });
        while (rs.next()){
            UserVo userVo = new UserVo();
           userVo.setId(rs.getInt("id"));
           userVo.setUserName(rs.getString("user_name"));
           list.add(userVo);
        }
        return list;
    }
    
	
	public List<String> getEachCountByTime(String userName, String startTime, String endTime) {
				List<String> voList = new ArrayList<>();
			    StringBuffer sf = new StringBuffer();
			    sf.append("SELECT error_each_count FROM " + projectsTable);
			    sf.append(" WHERE 1 = 1 ");
			    sf.append(" AND user_name = ?");
			    sf.append(" AND date_time >= '"+startTime+"'");
			    sf.append(" AND date_time <= '"+endTime+"'");
			    SqlRowSet rs = jt.queryForRowSet(sf.toString(),  new Object[] { userName }, new int[] { Types.VARCHAR } );
			    while (rs.next()){
			        String errorEachCount = rs.getString("error_each_count");
			        voList.add(errorEachCount);
			    }
			    return voList;
	}



注意:后端接口 /dashboard/getBar 返回的数据格式:

1. jsonMap的数据格式才是传值到前端,展示饼状图的数据.

2. 代表饼状图的图例名称:jsonPieRuleNameX,也就是jsonMap的key

3. 代表饼状图的data数据:jsonPieCountY,也就是jsonMap的key

jsonPieRuleNameX和jsonPieCountY传过去的格式必须要统一否则饼状图数据加载不出来。

因为我用的框架是springboot,可以根据自己的框架自己更改后端的方法。

MPAndroidChart显示饼状图能显示占比_饼状图_03


5.数据库表结构:

MPAndroidChart显示饼状图能显示占比_饼状图_04


总结:以上就是我的思路。纯属个人见解,记录一下以防万一。如果您有更好的解决方式,欢迎留言指教。