基于SpringMVC +前台页面基于bootstrap 的 echats+jquery.slider 堆积图

实现要点

1、基于jquery.slider 动态设置series,数据基于前台动态渲染。

2、legend的动态创建。


效果图:


基于SpringMVC +前台页面基于bootstrap 的 echats+jquery.slider 堆积图_第1张图片


JSP页面源码:

<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%long version = java.lang.System.currentTimeMillis();%>






  



    
    APP统计  | 神州专车
    
    
    
    
    
    
    
    

    
    
    
    
    
    
    
    
    

    
    
    
    
    
    
    








查询条件
用户成分分析:  当天至7天前新增
用户新鲜度

freshness.js源码:

/**
 * 用户新鲜度模块
 * @author 石冬冬
 * @date 2016/12/1
 */
var Freshness = {
	Cts:{
		charts:{
			render:null,
			viewData:null,
			totals:[]
		},
		limit:[0,31],
		rs:null
	},
	/**
	* 初始化
	*/
	init:function(){
		this.initEvts();
		this.initVals();
		this.initSlideBar(false);
		this.initData();
		this.renderCharts();
	},
	/**
	 * 初始化事件
	 */
	initEvts:function(){
		var _this = Freshness;
		$('#btnQuery').off().live('click',function(){
			_this.initData();
			_this.renderCharts();
		});
		//选项卡切换
		$('a[eleType=tab]').off().live('click',function(){
			var dataType = $(this).attr('dataType');
			$('#dataType').val(dataType);
			_this.initData();
			_this.renderCharts();
		});
		
		$('#slideBarCheckbox').off().live('click',function(){
			var checked = $(this).attr('checked');
			var enabled = checked=='checked';
			_this.initSlideBar(enabled);
		});
	},
	/**
	 * 初始化相关元素的值
	 */
	initVals:function(){
		var appVersion = $('#appVersionList').val();
		if(appVersion){
			appVersion = eval('('+appVersion+')');
			loadData(appVersion);
		}
	},
	/**
	 * 初始化标尺滚动条
	 * @param enabled
	 * API:http://demo.htmleaf.com/1502/201502041438/index.html
	 * http://blog.csdn.net/u011127019/article/details/52992654
	 */
	initSlideBar:function(enabled){
		var _this = Freshness;
		//初始化配置项
		$("#slideBar").slider({
			handle:'round',
			min:0,
			max:31,
			step:1,
			value:[0,31],
			tooltip_split:true,
			formatter: function(value) {
				var start = value[0];
				var end = value[1];
				if(start==0){
					start = '当天';
				}else{
					start+='天前';
				}
				if(end==31){
					end = '31天+前';
				}else{
					end+='天前';
				}
				var tips = start+'至'+end+'新增';
				if(value && $.isArray(value) && value.length==2){
					$('#slideBarTips').text(tips);
				}
				return value;
			}
		});
		//监听滑动事件
		$("#slideBar").on("change", function() {
			var value = this.value.split(",");
			if(value){
				_this.Cts.limit=value;
				_this.renderCharts();//刷新加载echarts
			}
		});
		//根据可用多选框设置控件是否可用
		if(enabled){
			$('#slideBarTips').show();
			$("#slideBar").slider("enable");
		}else{
			$('#slideBarTips').hide();
			$("#slideBar").slider("setValue",[0,31]);
			$("#slideBar").slider("disable");
			_this.Cts.limit=[0,31];
			_this.renderCharts();//刷新加载echarts
		}
	},
	/**
	 * 初始化报表
	 * @param args 对象
	 * @param xAxisData x坐标数组
	 */
	initCharts:function(args,xAxisData){
		var dataType = $('#dataType').val();
		var _yAxis = [
            {
                type : 'value',
                boundaryGap : false
            }
        ];
		if(dataType=='BFB'){
			_yAxis = [
	            {
	                type : 'value',
	                max:'100',
	                axisLabel: {
	                    show: true,
	                    interval: 'auto',
	                    formatter: '{value} %'
	                },
	                boundaryGap : false
	            }
	        ];
		}
		var _this = Freshness;
		var series = args.seriesData;
        var legendData = args.legendData;
        var myChart = echarts.init(document.getElementById("chart_div"), 'line');
        this.Cts.charts.render = myChart;
        var option = {
            title : {
            },
            tooltip : {
                trigger: 'axis',
                formatter:function (params,ticket,callback) {
                	var tips = '';
                	if(dataType=='JDZ'){
                		var seriesName = params.seriesName;
                		var value = params.value;
                		var name = params.name;
                		var total = _this.findTotal(name);
                		var ratio = 0;
                		if(total!=0){
                			ratio = ((value / total)*100).toFixed(2);
                		}
                		tips = name + '

在' + seriesName + '新增(占当日活跃比):
'+ value + '('+ratio+'%)' + '

当日全部活跃:'+total; } if(dataType=='BFB'){ var seriesName = params.seriesName; var name = params.name; var total = _this.findTotal(name); var value = params.value; value = value/100*total; var ratio = 0; if(total!=0){ ratio = ((value / total)*100).toFixed(2); } tips = name + '

在' + seriesName + '新增(占当日活跃比):
'+ value + '('+ratio+'%)' + '

当日全部活跃:'+total; } return tips; } }, legend: { show:false, width:'80%', padding: [5,100,5,100], itemGap: 10, data : legendData }, dataZoom:{}, toolbox: { show : true, feature : { mark : {show: false}, dataView : {show: true, readOnly: false}, magicType: {show: true, type: ['line','bar','stack', 'tiled']}, restore : {show: true}, saveAsImage : {show: true} } }, calculable : true, xAxis : [{ type:'category', interval:0, boundaryGap:false, data:xAxisData }], yAxis : _yAxis, series : series }; myChart.setOption(option); }, /** * 根据series的datas构建seriesData和legendData * @param datas */ initSeries:function(datas){ var _this = Freshness; var limit = _this.Cts.limit; console.log('limit=%s',JSON.stringify(limit)); var from = Number(limit[0]) ; var to = Number(limit[1]); var legendData = []; var series = []; for(var i=to;i>=from;i--){ var name = i+'天前'; if(i==0){ name = '当天'; } if(i==31){ name = '30+天前'; } legendData.push(name); var vo = { name: name, type: 'line', stack:'1', tooltip : { show : true, trigger: 'item' }, areaStyle: {normal: {}}, data: datas[i] }; series.push(vo); } return { seriesData:series, legendData:legendData }; }, /** * 初始化数据 */ initData:function(){ var params = $('#searchForm').serialize(); var _this = Freshness; $.ajax({ type : "post", url : BATH_PATH + "retentionAnalysis/loadForFreshness", data: params, dataType : "json", async : false, error : function(xhr, status, err) { //alert(err); }, success : function(rs) { _this.Cts.rs = rs; } }); }, /** * 根据容量构建二维数组 * @returns {Array} 二维数组 */ initArrays:function(){ var capacity = 31; var arrays = []; for(var i = 0;i<=capacity;i++){ arrays.push([]); } return arrays; }, /** * 根据xAxisName 查询对应的 活跃总数 * @param xAxisName */ findTotal:function(xAxisName){ var totals = this.Cts.charts.totals; var total = 0; if(totals){ $.each(totals,function(index){ //console.log('key=%s,val=%s',totals[index].key,val); if(totals[index].key == xAxisName){ total = totals[index].total; return; } }); } return total; }, /** * 渲染Charts * @param rs */ renderCharts:function(){ var _this = Freshness; var rs = _this.Cts.rs; var dataType = $('#dataType').val(); var xAxisData = []; var datas = this.initArrays(); var totals = []; if(rs){ var data = rs.dataMap; //======================绝对值============================= if(dataType=='JDZ'){ $.each(data,function(key,vo){ xAxisData.push(key); totals.push({key:key,total:vo.total}); //console.log('key=%s,total=%s',key,vo.total); $.each(vo.groupMap,function(index,val){ datas[index].push(val); }); }); //console.info("arrays=%s",JSON.stringify(datas)); } //======================百分比============================= if(dataType=='BFB'){ $.each(data,function(key,vo){ xAxisData.push(key); var total = vo.total; totals.push({key:key,total:total}); //console.log('key=%s,total=%s',key,vo.total); $.each(vo.groupMap,function(index,val){ var percent = (val==0)?0:((val/total)*100).toFixed(2); datas[index].push(percent); }); }); } } //console.log('totals=%s',JSON.stringify(totals)); _this.Cts.charts.totals = totals; //console.log('totals=%s',JSON.stringify(_this.Cts.charts.totals)); var args = _this.initSeries(datas); _this.initCharts(args,xAxisData); } }; Freshness.init();

Controller

package com.ucar.appcount.web.controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ucar.appcount.common.Common;
import com.ucar.appcount.common.vo.SearchObject;
import com.ucar.appcount.service.AdminManagerServiceNew;
import com.ucar.appcount.service.RetentionAnalysisService;
import com.zuche.framework.utils.StringUtils;
/**
 * 留存分析
 * @author 石冬冬-Heil Hilter([email protected])
 * @date 2016-11-28 下午6:53:41
 */
@Controller
@RequestMapping("retentionAnalysis")
public class RetentionAnalysisController {
	private static final Logger logger = Logger.getLogger(RetentionAnalysisController.class);
	@Autowired
	private AdminManagerServiceNew adminManagerServiceNew;
	@Autowired
	private RetentionAnalysisService retentionAnalysisService;
	
	
	private final String PAGE_PREFIX = "retention/";
	/**
	 * 留存用户|页面
	 * @author 石冬冬-Heil Hilter([email protected])
	 * @date 2016-11-28 下午7:01:07
	 * @param model
	 * @param searchObj
	 * @return
	 */
	@RequestMapping("retention")
	public String retention(Model model,SearchObject searchObj){
		try {
			List appChannel = adminManagerServiceNew.getAppChannel();
	        List appVersion = adminManagerServiceNew.getAppVersion();
	        String timeType = searchObj.getTimeType();
	        String columnTitleSuffix = "天后";
	        if(StringUtils.isEmpty(timeType)){
	        	timeType = Common.DATATYPE.DAY;
	        }
	        initSearchObj(searchObj);
	        if(Common.DATATYPE.DAY.equals(timeType)){
	        	model.addAttribute("columns", RetentionAnalysisService.ReportTitle.DAILY);
	        	columnTitleSuffix = "天后";
			}
			if(Common.DATATYPE.WEEK.equals(timeType)){
				model.addAttribute("columns", RetentionAnalysisService.ReportTitle.WEEK);
				columnTitleSuffix = "周后";
			}
			if(Common.DATATYPE.MONTH.equals(timeType)){
				model.addAttribute("columns", RetentionAnalysisService.ReportTitle.MONTH);
				columnTitleSuffix = "月后";
			}
			model.addAttribute("columnTitleSuffix", columnTitleSuffix);
	        model.addAttribute("searchObj", searchObj);
	        model.addAttribute("appChannel",appChannel);
	        model.addAttribute("appVersion", appVersion);
		} catch (Exception e) {
			logger.error("留存用户初始化异常",e);
		}
		return PAGE_PREFIX.concat("retention");
	}
	/**
	 * 用户新鲜度
	 * @author 石冬冬-Heil Hilter([email protected])
	 * @date 2016-12-1 下午2:00:31
	 * @param model
	 * @param searchObj
	 * @return
	 */
	@RequestMapping("freshness")
	public String freshness(Model model,SearchObject searchObj){
		try {
			List appChannel = adminManagerServiceNew.getAppChannel();
	        List appVersion = adminManagerServiceNew.getAppVersion();
	        String timeType = searchObj.getTimeType();
	        if(StringUtils.isEmpty(timeType)){
	        	timeType = Common.DATATYPE.DAY;
	        }
	        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
	        //开始时间为空则取三个月前
	        if(StringUtils.isBlank(searchObj.getBeginTime())){
	            Calendar calendar=Calendar.getInstance();
	            calendar.add(Calendar.MONTH,-1);
	            searchObj.setBeginTime(sdf.format(calendar.getTime()));
	        }
	        if(StringUtils.isBlank(searchObj.getEndTime())){
	        	Calendar calendar=Calendar.getInstance();
	            calendar.add(Calendar.DAY_OF_YEAR,-1);
	            searchObj.setEndTime(sdf.format(calendar.getTime()));
	        }
	        searchObj.setDataType("JDZ");//默认 绝对值
	        model.addAttribute("searchObj", searchObj);
	        model.addAttribute("appChannel",appChannel);
	        model.addAttribute("appVersion", appVersion);
		} catch (Exception e) {
			logger.error("留存用户初始化异常",e);
		}
		return PAGE_PREFIX.concat("freshness");
	}
	
	/**
	 * 留存用户
	 * @author 石冬冬-Heil Hilter([email protected])
	 * @date 2016-11-29 上午9:53:00
	 * @param searchObj
	 * @return
	 */
	@RequestMapping("loadForRetention")
    @ResponseBody
    public Object loadForRetention(SearchObject searchObj){
        Map dataMap = new HashMap();
        if(!StringUtils.isBlank(searchObj.getTimeType())){
        	Map> result =  this.retentionAnalysisService.retention(searchObj);
            dataMap.put("data", result);
        }
        return dataMap;
    }
	
	/**
	 * 用户新鲜度
	 * @author 石冬冬-Heil Hilter([email protected])
	 * @date 2016-11-29 上午9:53:00
	 * @param searchObj
	 * @return
	 */
	@RequestMapping("loadForFreshness")
    @ResponseBody
    public Object loadForFreshness(SearchObject searchObj){
        return this.retentionAnalysisService.freshness(searchObj);
    }

    @RequestMapping("activeDegree")
    public String toActiveDegree(Model model,SearchObject searchObj){
        List appChannel = adminManagerServiceNew.getAppChannel();
        List appVersion = adminManagerServiceNew.getAppVersion();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        //开始时间为空则取三个月前
        if(StringUtils.isBlank(searchObj.getBeginTime())){
            Calendar calendar=Calendar.getInstance();
            calendar.add(Calendar.MONTH,-1);
            searchObj.setBeginTime(sdf.format(calendar.getTime()));
        }
        if(StringUtils.isBlank(searchObj.getEndTime())){
            Calendar calendar=Calendar.getInstance();
            //calendar.add(Calendar.DAY_OF_YEAR,-1);
            searchObj.setEndTime(sdf.format(calendar.getTime()));
        }
        model.addAttribute("searchObj", searchObj);
        model.addAttribute("appChannel",appChannel);
        model.addAttribute("appVersion", appVersion);
        return PAGE_PREFIX+"/activeDegree";
    }

    @RequestMapping("loadActiveDegree")
    @ResponseBody
    public Object loadActiveDegree(SearchObject searchObj){
        initSearchObj(searchObj);
        Map> map=new HashMap>();
        try {
            map=retentionAnalysisService.getActiveDegree(searchObj);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return map;
    }
    @RequestMapping("loadActive15Degree")
    @ResponseBody
    public Object loadActive15Degree(SearchObject searchObj){
        initSearchObj(searchObj);
        Map> map=new HashMap>();
        try {
            map=retentionAnalysisService.getActive15Degree(searchObj);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return map;
    }
	
	private void initSearchObj(SearchObject seachObj) {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        //开始时间为空则取三个月前
        if(StringUtils.isBlank(seachObj.getBeginTime())){
            Calendar calendar=Calendar.getInstance();
            calendar.add(Calendar.WEEK_OF_YEAR,-1);
            seachObj.setBeginTime(sdf.format(calendar.getTime()));
        }
        if(StringUtils.isBlank(seachObj.getEndTime())){
        	Calendar calendar=Calendar.getInstance();
            calendar.add(Calendar.DAY_OF_YEAR,-1);
            seachObj.setEndTime(sdf.format(calendar.getTime()));
        }
        
    }
}

Service

package com.ucar.appcount.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.ucar.appcount.common.Common;
import com.ucar.appcount.common.CommonUtils;
import com.ucar.appcount.common.DateFormatUtil;
import com.ucar.appcount.common.vo.RetentionFreshnessVo;
import com.ucar.appcount.common.vo.SearchObject;
import com.ucar.appcount.component.SearchComponent;
import com.ucar.appcount.hbase.service.DevActive15DegreeTabServiceNew;
import com.ucar.appcount.hbase.service.DevActiveDegreeTabServiceNew;
import com.ucar.appcount.hbase.service.impl.BaseOperator;
import com.ucar.appcount.service.DevUserServiceNew;
import com.ucar.appcount.service.RetentionAnalysisDailyTabService;
import com.ucar.appcount.service.RetentionAnalysisMonthTabService;
import com.ucar.appcount.service.RetentionAnalysisService;
import com.ucar.appcount.service.RetentionAnalysisWeekTabService;
import com.ucar.appcount.service.RetentionFreshnessDailyTabService;
import com.zuche.framework.nosql.hbase098.vo.Column;
import com.zuche.framework.nosql.hbase098.vo.RowVo;
import com.zuche.framework.utils.StringUtils;
@Service
public class RetentionAnalysisServiceImpl extends BaseOperator implements RetentionAnalysisService {
	private static final Logger logger = LoggerFactory.getLogger(RetentionAnalysisServiceImpl.class);
	@Autowired
	private SearchComponent searchComponent;
	@Autowired
	private RetentionAnalysisDailyTabService retentionAnalysisDailyTabService;
	@Autowired
	private RetentionAnalysisWeekTabService retentionAnalysisWeekTabService;
	@Autowired
	private RetentionAnalysisMonthTabService retentionAnalysisMonthTabService;
	@Autowired
	private RetentionFreshnessDailyTabService retentionFreshnessDailyTabService;
	@Autowired
	private DevActiveDegreeTabServiceNew activeDegreeTabService;
    @Autowired
	private DevActive15DegreeTabServiceNew active15DegreeTabService;
	@Autowired
	private DevUserServiceNew devUserServiceNew;
	
	@Override
	public List queryRowVoList(SearchObject searchObj,String filterList){
		List rs = Collections.emptyList();
		String timeType= searchObj.getTimeType();
		if(Common.DATATYPE.DAY.equals(timeType)){
			rs = this.retentionAnalysisDailyTabService.queryRetentionRows(searchObj, filterList);
		}
		if(Common.DATATYPE.WEEK.equals(timeType)){
			rs = this.retentionAnalysisWeekTabService.queryRetentionRows(searchObj, filterList);
		}
		if(Common.DATATYPE.MONTH.equals(timeType)){
			rs = this.retentionAnalysisMonthTabService.queryRetentionRows(searchObj, filterList);
		}
		return rs;
	}
	@Override
	public Map> retention(SearchObject searchObj) {
		Map> dataMap = new LinkedHashMap>();
		try {
			String timeType= searchObj.getTimeType();
			final boolean byDay = Common.DATATYPE.DAY.equals(timeType);
			final boolean byWeek = Common.DATATYPE.WEEK.equals(timeType);
			final boolean byMonth = Common.DATATYPE.MONTH.equals(timeType);
			/*****************************************************************/
			/**
			 * 如果是按月统计:对开始时间 和 结束时间 逻辑控制
			 * 开始时间如果非开始时间当月的第一天,需要重置为下个月的第一天。
			 * 结束时间如果非结束时间当月的第一条,需要重置为上个月的第一天。
			 */
			/*****************************************************************/
			RetentionHandler.resetSearchTimeForByMonth(byMonth,searchObj);
			if(byMonth){
				Date start = DateFormatUtil.convertToDate(searchObj.getBeginTime(), DateFormatUtil.FORMAT_DATE_DISPLAY);
		    	Date end = DateFormatUtil.convertToDate(searchObj.getEndTime(), DateFormatUtil.FORMAT_DATE_DISPLAY);
		    	if(start.getTime()!=end.getTime()&&!end.after(start)){
		    		return dataMap;
		    	}
			}
			//1、构建查询结果Map
			this.searchComponent.initDataMapForRetention(dataMap,searchObj);
			String filterList = this.searchComponent.initFilterList(searchObj);
			//2、获取新增用户Map
			Map userAddMap = this.devUserServiceNew.getNewUserNum(searchObj);
			//2.1、按时间装载新增用户数
			Set>> entrySet = dataMap.entrySet();
			for(Entry> entry : entrySet){
				String dataKey = entry.getKey();
				if(userAddMap.containsKey(dataKey)){
					Map columnMap = entry.getValue();
					Double addUsers = Double.valueOf(userAddMap.get(dataKey).doubleValue());
					columnMap.put(0, addUsers);
				}
			}
			/*****************************************************************/
			/**
			 * rowkey特殊规则说明:新增日期#APP类型#APP版本#下载渠道#统计日期
			 * 按天:(20161125#M_android#600340#360shoujizhushou#20161128)
			 * 按周:(20161128#M_android#600340#360shoujizhushou#20161130)
			 * 按月:(20161101#M_android#600340#360shoujizhushou#20161201)
			 */
			/*****************************************************************/
			//3、获取留存用户
			List rs = this.queryRowVoList(searchObj, filterList);
			for(RowVo row : rs){
				String key = row.getRowKey();//新增日期
				String rowKey = row.getRowKey();
				String tjrq = rowKey.substring(rowKey.lastIndexOf("#")+1);
	            key = key.substring(0,key.indexOf("#",0));
	            key = CommonUtils.handlerTime(key, timeType);
	            tjrq = CommonUtils.handlerTime(tjrq, timeType);//统计日期
	            if(byWeek){//按周统计,把日期都转换成这个星期的第一天
	                key = DateFormatUtil.getFirstDayOfWeek(key);
	                key = key + "~" + DateFormatUtil.getLastDayOfWeek(key);
	            }
	            int days = 0;//天数
	            if(byDay||byWeek){
	            	days=Long.valueOf(DateFormatUtil.getTwoDateDifference(key,tjrq)).intValue();
	            }else{
	            	String s=key.concat("-01");
	            	String e=tjrq.concat("-01");
	            	days=Long.valueOf(DateFormatUtil.getTwoDateDifference(s,e)).intValue();
	            }
	            List columns = row.getColumns();
	            Integer count = Integer.valueOf(getValue(columns,Bytes.toBytes("statistical"), Bytes.toBytes("count")));
	            if(dataMap.containsKey(key)){
	            	Map columnMap = dataMap.get(key);
	            	int columnIndex = RetentionHandler.getColumnIndexForRetention(timeType, days);//获取时间类型(天/周/月)对列索引
	            	Double retention = columnMap.get(columnIndex);
	            	logger.error("留存用户载入:retention={},columnMap={}",retention,columnMap);
	            	if(null!=columnMap && null!=retention){
	            		columnMap.put(columnIndex, count+retention);
	            	}
	            	dataMap.put(key, columnMap);
	            }
			}
			logger.error("留存用户加载数据:dataMap={}",JSON.toJSONString(dataMap));
		} catch (Exception e) {
			logger.error("留存用户加载数据异常:dataMap={}",JSON.toJSONString(dataMap),e);
		}
		return dataMap;
	}
	
	@Override
	public Map freshness(SearchObject searchObj){
		Map resultMap = new HashMap();
		try {
			Map dataMap = new LinkedHashMap();
			String timeType = searchObj.getTimeType();
			Integer from = searchObj.getFrom();
			Integer to = searchObj.getTo();
			String filterList = this.searchComponent.initFilterList(searchObj);
			//2、获取用户新鲜度
			List rs = this.retentionFreshnessDailyTabService.queryFreshnessRows(searchObj, filterList);
			for(RowVo row : rs){
				String key = row.getRowKey();//登录日期
				String rowKey = row.getRowKey();
				String xzrq = rowKey.substring(rowKey.lastIndexOf("#")+1);
	            key = key.substring(0,key.indexOf("#",0));
	            key = CommonUtils.handlerTime(key, timeType);
	            xzrq = CommonUtils.handlerTime(xzrq, timeType);//新增日期
	            List columns = row.getColumns();
	            Integer count = Integer.valueOf(getValue(columns,Bytes.toBytes("statistical"), Bytes.toBytes("count")));
	            if(dataMap.containsKey(key)){
	            	RetentionFreshnessVo freshnessVo = dataMap.get(key);
	            	int orig = freshnessVo.getTotal();
	            	freshnessVo.setTotal(orig + count);
	            	int duration = RetentionHandler.getColumnIndexForFreshness(key, xzrq,to);
	            	if(duration groupMap = freshnessVo.getGroupMap();
	            	groupMap.put(duration, count + groupMap.get(duration));
	            	dataMap.put(key, freshnessVo);
	            }else{
	            	RetentionFreshnessVo freshnessVo = new RetentionFreshnessVo();
		   			Map groupMap = new LinkedHashMap();
		   			for(int d=to;d>=from;d--){
		   				 groupMap.put(d, 0);
		   			}
		   			freshnessVo.setGroupMap(groupMap);
		   			dataMap.put(key, freshnessVo);
	            }
			}
			logger.error("用户新鲜度加载数据:dataMap={}",JSON.toJSONString(dataMap));
			resultMap.put("dataMap", dataMap);
		} catch (Exception e) {
			logger.error("用户新鲜度加载数据异常:dataMap={}",JSON.toJSONString(resultMap),e);
		}
		return resultMap;
	}

    /**
     * 获取用户活跃度数据
     *
     * @param searchObj
     * @return
     */
    @Override
    public Map> getActiveDegree(SearchObject searchObj) throws ParseException {
        Map> map=new LinkedHashMap>();
        //20161113#M_android#600221#360shoujizhushou#2
        String filterList = ".*";
        if(!StringUtils.isEmpty(searchObj.getAppType())){
            filterList += "#"+searchObj.getAppType();
        }else{
            filterList += "#.*";
        }
        if(!StringUtils.isEmpty(searchObj.getAppVersion())){
            filterList += "#"+searchObj.getAppVersion();
        }else{
            filterList += "#.*";
        }
        if(!StringUtils.isEmpty(searchObj.getAppChannel())){
            filterList += "#"+searchObj.getAppChannel()+".*";
        }else{
            filterList += "#.*";
        }

        //20160828#M_android#600171#SGCM 01#1
        searchObj.setTimeType(Common.DATATYPE.DAY);
        //结束时间默认加一天
        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateFormat.parse(searchObj.getEndTime()));
        calendar.add(Calendar.DATE, 1);
        searchObj.setEndTime(dateFormat.format(calendar.getTime()));
        List activeList = activeDegreeTabService.getActiveDegree(searchObj, filterList);
        for(RowVo r : activeList){
            String key = r.getRowKey();
            Integer days=Integer.valueOf(key.substring(key.lastIndexOf("#") + 1));
            key = key.substring(0, key.indexOf("#", 0));
            key = CommonUtils.handlerTime(key, searchObj.getTimeType());

            List columns = r.getColumns();
            Integer count = Integer.valueOf(getValue(columns,Bytes.toBytes("statistical"), Bytes.toBytes("count")));
            if(map.containsKey(key)){
                if(map.get(key).containsKey(days)) {
                    map.get(key).put(days, map.get(key).get(days)+count);
                }else{
                    map.get(key).put(days,count);
                }
            }else{
                Map tempMap=new HashMap();
                tempMap.put(days,count);
                map.put(key,tempMap);
            }
        }

        return map;
    }

    /**
     * 获取用户活跃度数据
     *
     * @param searchObj
     * @return
     */
    @Override
    public Map> getActive15Degree(SearchObject searchObj) throws ParseException {
        Map> map=new LinkedHashMap>();
        //20161113#M_android#600221#360shoujizhushou#2
        String filterList = ".*";
        if(!StringUtils.isEmpty(searchObj.getAppType())){
            filterList += "#"+searchObj.getAppType();
        }else{
            filterList += "#.*";
        }
        if(!StringUtils.isEmpty(searchObj.getAppVersion())){
            filterList += "#"+searchObj.getAppVersion();
        }else{
            filterList += "#.*";
        }
        if(!StringUtils.isEmpty(searchObj.getAppChannel())){
            filterList += "#"+searchObj.getAppChannel()+".*";
        }else{
            filterList += "#.*";
        }

        //20160828#M_android#600171#SGCM 01#1
        searchObj.setTimeType(Common.DATATYPE.DAY);
        //结束时间默认加一天
        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateFormat.parse(searchObj.getEndTime()));
        calendar.add(Calendar.DATE,1);
        searchObj.setEndTime(dateFormat.format(calendar.getTime()));
        List activeList = active15DegreeTabService.getActiveDegree(searchObj, filterList);
        for(RowVo r : activeList){
            String key = r.getRowKey();
            key = key.substring(0, key.indexOf("#", 0));
            key = CommonUtils.handlerTime(key, searchObj.getTimeType());

            Integer days=Integer.valueOf(key.substring(key.lastIndexOf("#") + 1));

            List columns = r.getColumns();
            Integer count = Integer.valueOf(getValue(columns,Bytes.toBytes("statistical"), Bytes.toBytes("count")));
            if(map.containsKey(key)){
                if(map.get(key).containsKey(days)) {
                    map.get(key).put(days, map.get(key).get(days)+count);
                }else{
                    map.get(key).put(days,count);
                }
            }else{
                Map tempMap=new HashMap();
                tempMap.put(days,count);
                map.put(key,tempMap);
            }
        }

        return map;
    }

    /**
	 * 留存用户数据处理类
	 * @author 石冬冬-Heil Hilter([email protected])
	 * @date 2016-11-30 上午9:54:17
	 */
	public static class RetentionHandler{
		/**
		 * 根据时间类型(日|周|月)获取对应列头对应的索引
		 * @author 石冬冬-Heil Hilter([email protected])
		 * @date 2016-11-29 下午3:48:35
		 * @param timeType 时间类型
		 * @param days 差异天数
		 * @return
		 */
		public static int getColumnIndexForRetention(String timeType,int days){
			int columnIndex = 0;
			if(days==0){
				return -1;
			}
			if(Common.DATATYPE.DAY.equals(timeType)){
				if(days==0){
					return -1;
				}
				if(days<7){
					columnIndex = ReportTitle.DAILY[days-1];
				}else if(days==14){
					columnIndex = ReportTitle.DAILY[7];
				}else if(days==30){
					columnIndex = ReportTitle.DAILY[8];
				}
			}
			if(Common.DATATYPE.WEEK.equals(timeType)){
				int week = (days/7)-1;
				if(week<0){
					return -1;
				}
				columnIndex = ReportTitle.WEEK[week];
			}
			if(Common.DATATYPE.MONTH.equals(timeType)){
				int month = (days/30)-1;
				if(month<0){
					return -1;
				}
				columnIndex = ReportTitle.MONTH[month];
			}
			return columnIndex;
		}
		/**
		 * 用户新鲜度|获取登录日期与新增日期的差异天数
		 * @author 石冬冬-Heil Hilter([email protected])
		 * @date 2016-12-1 下午3:01:57
		 * @param dlrq 登录日期
		 * @param xzrq 新增日期
		 * @return
		 */
		public static int getColumnIndexForFreshness(String dlrq,String xzrq,Integer to){
			int duration = 0;
			duration = Long.valueOf(DateFormatUtil.getTwoDateDifference(xzrq,dlrq)).intValue();
			if(duration>=to){
				return to;
			}
			return duration;
		}
		/*****************************************************************/
		/**
		 * 如果是按月统计:对开始时间 和 结束时间 逻辑控制
		 * 开始时间如果非开始时间当月的第一天,需要重置为下个月的第一天。
		 * 结束时间如果非结束时间当月的第一条,需要重置为上个月的第一天。
		 */
		/*****************************************************************/
		public static void resetSearchTimeForByMonth(boolean byMonth,SearchObject searchObj){
			if(!byMonth){
				return;
			}
			String beginTime = searchObj.getBeginTime();
			String endTime = searchObj.getEndTime();
			if(!StringUtils.isEmpty(beginTime)){
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(DateFormatUtil.convertToDate(beginTime,DateFormatUtil.FORMAT_DATE_DISPLAY));
				int today = calendar.get(Calendar.DAY_OF_MONTH);
				if(today!=1){
					calendar.add(Calendar.MONTH, 1);
					calendar.set(Calendar.DAY_OF_MONTH, 1);
					String newTime = DateFormatUtil.convertDateToString(calendar.getTime(), DateFormatUtil.FORMAT_DATE_DISPLAY);
					searchObj.setBeginTime(newTime);
				}
			}
			if(!StringUtils.isEmpty(endTime)){
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(DateFormatUtil.convertToDate(endTime,DateFormatUtil.FORMAT_DATE_DISPLAY));
				int today = calendar.get(Calendar.DAY_OF_MONTH);
				boolean reset = false;
				//下面有些情况却要确认。。。。
				if(today!=1){
					calendar.add(Calendar.MONTH, -1);
					calendar.set(Calendar.DAY_OF_MONTH, 1);
					reset = true;
				}else{
					int month = calendar.get(Calendar.MONTH);
					Calendar nowCalendar = Calendar.getInstance();
					int currentMonth = nowCalendar.get(Calendar.MONTH);
					//非本月第一天时,
					if(month==currentMonth){
						calendar.add(Calendar.MONTH, -1);
						reset = true;
					}
				}
				if(reset){
					String newTime = DateFormatUtil.convertDateToString(calendar.getTime(), DateFormatUtil.FORMAT_DATE_DISPLAY);
					searchObj.setEndTime(newTime);
				}
			}
		}
		
		public static void main(String[] args) {
			//System.out.println(getColumnIndex(Common.DATATYPE.WEEK, 7));
			System.out.println(RetentionAnalysisService.ReportTitle.MONTH_COLS);
		}
	}
}



你可能感兴趣的:(前端技术)