Echarts图表开发之饼图

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/samile6899/article/details/78589373

     在相关的后台系统开发中,有一个必不可少的模块就是图表主题分析。通过图表分析,可以更加直观的展示业务的发展状态及各个业务占比情况,更加有利于公司领导做出相应的决策。在开发的最近一个项目中,有用到了Java 的 Echarts 开发其相应的后台图表主题分析模块功能。既然用到了,就概要的说下,希望以后在需要使用或者有其他人需要使用的话,只需要看下教程就可以立即上手操作使用,而不需要重新去看文档花掉很多时间。

     序: 在刚开始使用这个图表插件的时候,我一般是首先新建一个页面,然后的话把相应的官网Demo例子全文复制到该新建的页面中,然后运行该页面,观察其是否能够正常运行。如果不能运行的话,找出其相应的原因,总之最后把这个Demo例子先成功运行起来是开始学习的首要且重要的一件事。当你把下载下来的例子成功在你新建的页面中运行起来的时候,然后开始动态赋值,从后台动态加载数据,开始轻微的修改代码,与后台进行交互。做到这一点之后,前后台的数据填充和交互差不多就OK了,然后的话图表主题分析肯定是要有其相应的搜索条件,根据选择的搜索条件去动态的加载图表并重绘。这样的话一步步就差不太多了。(注:因为在项目中,我的饼图和折线图是在一个JSP页面中绘制的,所以的话下面的讲解都是基于一个JSP两个图表的分析)

     ***********************************************************************************

      饼图和折线图:

         1,引入JQuery minui 和 Echarts 相关的 js 文件 并绘制相应的JSP图表界面;( JQuery mini 项目中有用到,没有用到可以不用引入 )

<head>
    <title></title>
    <script src="resource/js/boot.js" type="text/javascript"></script>
  </head>
<fieldset id="query_fieldset" style="">
	   <legend>查询结果</legend>
	   
	  <div style="width:99%;">
        <div class="ct" id="chart1" style="height:100%;width:96%;margin:0 auto;">></div>      
      </div> 
      <div style="width:99%;">
      <div id="chartContainer" style="height:100%;width:96%;">></div>
      </div>
       <script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/echarts-all-3.js"></script>
       <script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts-stat/ecStat.min.js"></script>
       <script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/extension/dataTool.min.js"></script>
       <script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/map/js/china.js"></script>
       <script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/map/js/world.js"></script>
       <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=ZUONbpqGBsYGXNIYHicvbAbM"></script>
       <script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/extension/bmap.min.js"></script>
	</fieldset>

        2,引入 Echarts 饼图和折线图的 Options 参数并初始化图表;

  <script type="text/javascript">
    mini.parse();
    var chartPie = echarts.init(document.getElementById('chart1'));
    var chartCross = echarts.init(document.getElementById('chartContainer'));
	var form = new mini.Form("#queryForm");

	//=======初始加载 "饼图" 和 "折线图"数据=======
	var data = search();
	//====================================
	
    var option = {
    	title: {
            text: '业务饼图分析',
            subtext: '各类业务申请次数(人次)',
            textStyle: {
        		fontSize: '24',    
        		fontWeight: '900'
	        },
            x: 'center'
        },
        tooltip: {
            trigger: 'item',
            formatter: "{a} <br/>{b} : {c} ({d}%)"
        },
        legend: {
            orient: 'vertical',
            left: 'left',
            textStyle: {
        		fontSize: '14',    
        		fontWeight: '900'
	        },
            data: data.legendData           
        },
        series: [
            {              
                type: 'pie',
                radius: '55%',
                center: ['50%', '60%'],
                data: data.seriesData, 
                normal: {			      
    					label:{  
                				show:true,  
                				formatter:'{b} : {c}人次 ({d}%)',
                				textStyle: {
                					color: '#000000',
                					fontSize: '14',    
		                          	fontWeight: '900'  
		                      	}	
        					   }									        
   					 },              
                itemStyle: {
                    normal: {			      
    					label:{  
                				show:true,  
                				formatter:'{b} : {c}人次 ({d}%)',
                				textStyle: {
                					color: '#000000',
                					fontSize: '14',    
		                          	fontWeight: '900'  
		                      	}	
        					   }									        
   					 },
                    emphasis: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                }
            }
        ]
    };
    
    var options = { 
    	title: {  
    	    text: '',
            subtext: '',       
            textStyle: {
        		fontSize: '24',    
        		fontWeight: '900'
	        },
            x: 'left'
        },   
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'cross',
                label: {
                    backgroundColor: '#6a7985'
                }
            }
        },
        legend: {
            data: data.crossLegend, 
            textStyle: {
        		fontSize: '14',    
        		fontWeight: '900'
	        },         
        },       
        grid: {         
            left: '5%',
            right: '4%',
            bottom: '2%',
            containLabel: true
        },
        xAxis: [
            {
                type: 'category',
                boundaryGap: false,
                data: data.crossType
            }
        ],
        yAxis: [
            {
                type: 'value'
            }
        ],
        series: data.crossSeries
    };	

    function buildChart() {
    	$('#chart1').removeAttr('_echarts_instance_');
    	$('#chartContainer').removeAttr('_echarts_instance_');

        chartPie.setOption(option,true);
        chartCross.setOption(options,true);
    }
    //buildChart();
    
    //重置
	function resetForm() {
       form.reset();
    }	
    
    //查询
	function check(){
	    form.validate();
        if (form.isValid() == false) return;
	    var streetId = mini.get("street").getValue();
		//发放日期
		var beginDate = mini.get("beginDate").getFormValue();
		var endDate = mini.get("endDate").getFormValue();
		if(beginDate>endDate){
			mini.alert('开始日期不得小于结束日期,请重新选择查询日期!');
		}else{
		    data=search();
		    
		    chartPie.setOption(option,true);
            chartCross.setOption(options,true);
		    
		    //饼图重新赋值	
		    option = chartPie.getOption();
		    option.series[0].data=data.seriesData;
		    
		    //折线图重新赋值
		    options = chartCross.getOption();
		    options.xAxis[0].data=data.crossType;
		    options.series=data.crossSeries;
		    
		    buildChart();		
		}        		
	}
	
	function search(){
		var legendData = [];
   		var seriesData = [];
   		var crossLegend = [];
   		var crossSeries = [];
   		var crossType   = [];
   		
	    var data=form.getData(true);
	    var json=mini.encode(data);
		$.ajax({
		    url: "theme.queryBusAnalysisData.action",
		    type: "post",
		    data: { submitData: json },
		    async: false,
		    success: function (text) {
		        var pieData = text.pieData;			       				
	    		for(var i=0;i<pieData.degreeInfo.length;i++){
	    		    legendData.push(pieData.legendInfo[i]);
	    		    seriesData.push({
	    		    	name:pieData.degreeInfo[i].NAME,
	    		    	value:pieData.degreeInfo[i].VALUE
	    		    });		    			
	    		}	
	    		var crossData = text.crossData;
	    		for(var i=0;i<crossData.legendInfo.length;i++){
	    		    crossLegend.push(crossData.legendInfo[i]);    		    
	    		    crossSeries.push({
	    		    	areaStyle:crossData.seriesInfo[i].areaStyle,
	    		    	data:crossData.seriesInfo[i].data,
	    		    	name:crossData.seriesInfo[i].name,
	    		    	stack:crossData.seriesInfo[i].stack,
	    		    	type:crossData.seriesInfo[i].type
	    		    });		    			
	    		}
	    		for(var j=0;j<crossData.typeInfo.length;j++){
	    			crossType.push(crossData.typeInfo[j]);
	    		}							       
		    }
		});	
		return {
			legendData: legendData,
            seriesData: seriesData,
            crossLegend: crossLegend, 
   		    crossSeries: crossSeries, 
   		    crossType: crossType   
		};
	}
  </script>
         注: 与后台交互通过JSON的形式,所以需要把相应的数据结构给定义好,这是我的后台实体及JSON格式;
public String queryBusAnalysisData() {
		List<String> strList = new ArrayList<String>();
		String pieJson = "";
		String crossJson = "";
		DegreeOptionInfo degreeOptionInfo = new DegreeOptionInfo();
		String json = getServletRequest().getParameter("submitData");
		if (!StringUtil.safeToString(json).equals("")) {
			ThemeVo themVo = (ThemeVo) VOUtils.getBeanFromJsonData(json,
					ThemeVo.class);
			Map<String, List<Map<String, Object>>> busAnalysisMap = themeService
					.queryBusAnalysisData(themVo);
			// 组装成json
			for (String key : busAnalysisMap.keySet()) {
				if (key.equals("pieData")) {
					List<Map<String, Object>> list = busAnalysisMap.get(key);
					for (int i = 0; i < list.size(); i++) {
						Map<String, Object> map = list.get(i);
						strList.add(map.get("NAME").toString());
					}
					degreeOptionInfo.setDegreeInfo(list);
					degreeOptionInfo.setLegendInfo(strList);
					pieJson = VOUtils.getJsonData(degreeOptionInfo);
				}
				if (key.equals("crossData")) {
					CrossData crossData = new CrossData();
					List<String> typeList = new ArrayList<String>();
					List<CrossTree> seriesList = new ArrayList<CrossTree>();
					List<Map<String, Object>> list = busAnalysisMap.get(key);
					Map<String, List<String>> tempList = new HashMap<String, List<String>>();

					List<String> tkgyList = new ArrayList<String>();
					List<String> jwbkList = new ArrayList<String>();
					List<String> wbbkList = new ArrayList<String>();
					List<String> itemList = new ArrayList<String>();
					List<String> ydcjList = new ArrayList<String>();
					List<String> individualList = new ArrayList<String>();
					List<String> lsjzList = new ArrayList<String>();

					for (int j = 0; j < list.size(); j++) {
						Map<String, Object> map = list.get(j);
						typeList.add(map.get("TYPE").toString()); // 折线图 X轴

						tkgyList.add(map.get("F1").toString());
						jwbkList.add(map.get("F2").toString());
						wbbkList.add(map.get("F3").toString());
						itemList.add(map.get("F4").toString());
						ydcjList.add(map.get("F5").toString());
						individualList.add(map.get("F6").toString());
						lsjzList.add(map.get("F7").toString());

						tempList.put("f1", tkgyList);
						tempList.put("f2", jwbkList);
						tempList.put("f3", wbbkList);
						tempList.put("f4", itemList);
						tempList.put("f5", ydcjList);
						tempList.put("f6", individualList);
						tempList.put("f7", lsjzList);
					}

					for (int t = 0; t < strList.size(); t++) {
						CrossTree crossTree = new CrossTree();
						Map<String, List<String>> map1 = new HashMap<String, List<String>>();
						map1.put("normal", new ArrayList<String>());

						crossTree.setAreaStyle(map1);
						crossTree.setName(strList.get(t));
						crossTree.setType("line");
						crossTree.setStack("总量");

						String keys = ("f" + (t + 1)).toString();
						crossTree.setData(tempList.get(keys));
						seriesList.add(crossTree);
					}
					crossData.setLegendInfo(strList); // 折线图标题列
					crossData.setTypeInfo(typeList); // 折线图 X轴
					crossData.setSeriesInfo(seriesList); // 折线图数据

					crossJson = VOUtils.getJsonData(crossData);
					LOG.info("Cross折线图格式化的json数据是:=====" + crossJson);
				}
			}
			JSONObject obj = new JSONObject();
			obj.put("pieData", pieJson);
			obj.put("crossData", crossJson);
			createJSonData(obj.toString());
		}

		return AJAX;
	}
 
@Override
	public Map<String, List<Map<String, Object>>> queryBusAnalysisData(
			ThemeVo themVo) {
		Map<String,List<Map<String,Object>>> busAnalysisMap = new HashMap<String,List<Map<String,Object>>>();
		Map<String,Object> param=new HashMap<String,Object>();		
		param.put("STREET_ID",themVo.getStreet());	
		param.put("BEGIN_DATE",themVo.getBeginDate());	
		param.put("END_DATE",themVo.getEndDate());	
		param.put("TYPE",themVo.getType());
		List<Map<String,Object>> pieList = themeDao.queryBusAnalysisPieData(param);
		List<Map<String,Object>> crossList = themeDao.queryBusAnalysisCrossData(param);
		
		busAnalysisMap.put("pieData",pieList);
		busAnalysisMap.put("crossData",crossList);
		
		return busAnalysisMap;
	}

           看代码也知道了,Service及Dao 层返回的都是Map和List 之间互相嵌套,而 返回前台的JSON数据结构则是 DegreeOptionInfo 类

public class DegreeOptionInfo {
	
	public List<Map<String,Object>> degreeInfo;
	public List<String> legendInfo;
	public String seriesName;
	public List<String> degreeInfos;
	
	public DegreeOptionInfo(){
		this.degreeInfo = new ArrayList<Map<String,Object>>();
		this.legendInfo = new ArrayList<String>();
		this.degreeInfos = new ArrayList<String>();
	}

	public List<Map<String, Object>> getDegreeInfo() {
		return degreeInfo;
	}



	public void setDegreeInfo(List<Map<String, Object>> degreeInfo) {
		this.degreeInfo = degreeInfo;
	}



	public List<String> getLegendInfo() {
		return legendInfo;
	}

	public void setLegendInfo(List<String> legendInfo) {
		this.legendInfo = legendInfo;
	}

	public String getSeriesName() {
		return seriesName;
	}

	public void setSeriesName(String seriesName) {
		this.seriesName = seriesName;
	}

	public List<String> getDegreeInfos() {
		return degreeInfos;
	}

	public void setDegreeInfos(List<String> degreeInfos) {
		this.degreeInfos = degreeInfos;
	}
	
}
       折线图的实体类及JSON数据结构:

扫描二维码关注公众号,回复: 2904173 查看本文章
public class CrossData {
	
	public List<CrossTree> seriesInfo;
	public List<String> legendInfo;
	public List<String> typeInfo;
	
	public CrossData(){
		this.seriesInfo = new ArrayList<CrossTree>();
		this.legendInfo = new ArrayList<String>();
		this.typeInfo = new ArrayList<String>();
	}

	public List<CrossTree> getSeriesInfo() {
		return seriesInfo;
	}





	public void setSeriesInfo(List<CrossTree> seriesInfo) {
		this.seriesInfo = seriesInfo;
	}





	public List<String> getLegendInfo() {
		return legendInfo;
	}

	public void setLegendInfo(List<String> legendInfo) {
		this.legendInfo = legendInfo;
	}

	public List<String> getTypeInfo() {
		return typeInfo;
	}

	public void setTypeInfo(List<String> typeInfo) {
		this.typeInfo = typeInfo;
	}
}

public class CrossTree {
	private String name;
	private String type;
	private String stack;
	private Map<String,List<String>> areaStyle;
	private List<String> data;
	
	
	public CrossTree() {
	}

	public CrossTree(String name, String type, String stack,
			Map<String, List<String>> areaStyle, List<String> data) {
		super();
		this.name = name;
		this.type = type;
		this.stack = stack;
		this.areaStyle = areaStyle;
		this.data = data;
	}



	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getStack() {
		return stack;
	}
	public void setStack(String stack) {
		this.stack = stack;
	}
	public List<String> getData() {
		return data;
	}
	public void setData(List<String> data) {
		this.data = data;
	}

	public Map<String, List<String>> getAreaStyle() {
		return areaStyle;
	}

	public void setAreaStyle(Map<String, List<String>> areaStyle) {
		this.areaStyle = areaStyle;
	}
	
	
}
           最后,看一下相应的JSP效果图吧


   
 ******************************************************************************************

参考网址:

       饼图数据填充                    http://www.cnblogs.com/sillypasserby/p/6185703.html    
       折线图数据填充                http://www.cnblogs.com/Dreamer-1/p/5530221.html     
  


猜你喜欢

转载自blog.csdn.net/samile6899/article/details/78589373