java实现折线图统计数据

           需求:可以分别按日,周,月进行统计交易总额。后台接收参数为type,string。其中type为查询类型,string接收的为“yyyy-mm-dd”格式的字符串。按周统计的话是计算一周的交易总额,按月的话是计算一个月的交易总额;按周或者按月都是通过传过来的字符串去解析周数或月份。默认查询:日前推30天,周前推12周,月前推12个月。

           注意:1,周计数策略统一为iso标准策略计算;每周一为一周的第一天,第一个自然周最少要4天;

                           相关参考链接:

                                                    https://blog.csdn.net/wysnxzm/article/details/89095495

                                                    https://blog.csdn.net/sayWhat_sayHello/article/details/80589304  ;

                                                    https://blog.csdn.net/lifuxiangcaohui/article/details/50953018

                      2,数据的补全策略,通过事先运算出该时间范围内的所有应展示的统计数据与实际mysql中查询出来的数据进行对比,如果不存在响应map中则添加一条值为0的记录。

           参考代码

  1 public OpenAPiJsonResult shopTradeTrend(AppSession session, GetTradeTrendRequest request) throws Exception {
  2         WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY, 4);
  3         // 查询条件
  4         String queryData = request.getQueryDate();
  5         Integer queryType = request.getType();
  6 
  7         List<String> responseDate = Lists.newArrayList();
  8         if (Objects.isNull(queryType) && StringUtils.isBlank(queryData)) {
  9             // 默认按日,展示当前日期前推30天的数据
 10             request.setType(0);
 11             request.setStartDate(LocalDate.now().minusDays(29).toString());
 12             request.setEndDate(LocalDate.now().plusDays(1).toString());
 13             responseDate = DateUtil.findDates(LocalDate.now().minusDays(30).toString(), LocalDate.now().toString());
 14         } else if (Objects.nonNull(queryType)) {
 15             if (queryType == 0) {
 16                 // 按日,默认查30天
 17                 if (StringUtils.isBlank(queryData)) {
 18                     request.setStartDate(LocalDate.now().minusDays(29).toString());
 19                     request.setEndDate(LocalDate.now().plusDays(1).toString());
 20                     responseDate = DateUtil.findDates(LocalDate.now().minusDays(30).toString(), LocalDate.now().toString());
 21                 } else {
 22                     LocalDate queryDate = DateUtil.stringToLocalDate(queryData);
 23                     request.setStartDate(queryDate.minusDays(29).toString());
 24                     request.setEndDate(queryDate.plusDays(1).toString());
 25                     responseDate = DateUtil.findDates(queryDate.minusDays(30).toString(), queryDate.toString());
 26                 }
 27             } else if (queryType == 1) {
 28                 // 按周,默认查当前周前推12周的数据
 29                 if (StringUtils.isBlank(queryData)) {
 30                     int nowWeekNo = LocalDate.now().get(weekFields.weekOfYear());
 31                     String weekStartDate = DateUtil.getWeekDays(LocalDate.now().getYear(), nowWeekNo, -11);
 32                     request.setStartDate(weekStartDate);
 33                     request.setEndDate(LocalDate.now().plusDays(1).toString());
 34                     responseDate = new ArrayList<>(Objects.requireNonNull(DateUtil.getWeekBetween(weekStartDate, LocalDate.now().toString())));
 35                 } else {
 36                     LocalDate date = DateUtil.stringToLocalDate(queryData);
 37                     int nowWeekNo = date.get(weekFields.weekOfWeekBasedYear());
 38                     request.setStartDate(DateUtil.getWeekDays(date.get(weekFields.weekBasedYear()), nowWeekNo, -11));
 39                     request.setEndDate(DateUtil.getDateByYearAndWeekNo(date.get(weekFields.weekBasedYear()), nowWeekNo).plusDays(1).toString());
 40                     responseDate = new ArrayList<>(Objects.requireNonNull(DateUtil.getWeekBetween(DateUtil.getWeekDays(date.get(weekFields.weekBasedYear()), nowWeekNo, -11), DateUtil.getDateByYearAndWeekNo(date.get(weekFields.weekBasedYear()), nowWeekNo).toString())));
 41                 }
 42             } else {
 43                 // 按月,默认查12个月
 44                 if (StringUtils.isBlank(queryData)) {
 45                     String startMonth = DateUtil.dateMinusMonth(LocalDate.now().getYear() + "" + LocalDate.now().getMonthValue(), -11);
 46                     request.setStartDate(startMonth.substring(0, 4) + "-" + startMonth.substring(4, 6) + "-01");
 47                     request.setEndDate(LocalDate.now().plusDays(1).toString());
 48 
 49                     responseDate = DateUtil.getMonthBetween(startMonth.substring(0, 4) + "-" + startMonth.substring(4, 6), LocalDate.now().getYear() + "-" + LocalDate.now().getMonthValue());
 50                 } else {
 51                     LocalDate date = DateUtil.stringToLocalDate(queryData);
 52                     String startMonth = DateUtil.dateMinusMonth(date.getYear() + "" + date.getMonthValue(), -11);
 53                     request.setStartDate(startMonth.substring(0, 4) + "-" + startMonth.substring(4, 6) + "-01");
 54                     String endDate = DateUtil.getLastDay(date.getYear() + "-" + date.getMonthValue() + "-01");
 55                     request.setEndDate(DateUtil.stringToLocalDate(endDate).plusDays(1).toString());
 56                     responseDate = DateUtil.getMonthBetween(startMonth.substring(0, 4) + "-" + startMonth.substring(4, 6), date.getYear() + "-" + date.getMonthValue());
 57                 }
 58             }
 59         }
 60         List<TradeTrendResponse> responseList = orderService.selectCountTradeTrend(session.getOrgId(), session.getStoreId(), request.getType(), request.getStartDate(), request.getEndDate());
 61 
 62         // 因为mysql month,week,day函数返回的数据在1-9内的都不带0,需要拼装成规范月,周,日数据
 63         List<String> convertData = Stream.of("1", "2", "3", "4", "5", "6", "7", "8", "9").collect(toList());
 64         if (Objects.isNull(request.getType()) || request.getType() == 0) {
 65             List<String> hasData = Lists.newArrayList();
 66             TreeMap<LocalDate, Double> responseMap = Maps.newTreeMap();
 67             // 按日
 68             responseList.forEach(x -> {
 69                 if (convertData.contains(x.getMonthNo())) {
 70                     x.setMonthNo("0" + x.getMonthNo());
 71                 }
 72                 if (convertData.contains(x.getDayNo())) {
 73                     x.setDayNo("0" + x.getDayNo());
 74                 }
 75                 String str = x.getYearNo() + "-" + x.getMonthNo() + "-" + x.getDayNo();
 76                 responseMap.put(DateUtil.stringToLocalDate(str), x.getAmount());
 77                 hasData.add(str);
 78             });
 79             responseDate.removeAll(hasData);
 80             responseDate.forEach(noData -> {
 81                 responseMap.put(DateUtil.stringToLocalDate(noData), 0.00);
 82             });
 83             return OpenAPiJsonResult.success(responseMap);
 84         } else if (request.getType() == 1) {
 85             // 按周
 86             List<String> hasData = Lists.newArrayList();
 87             TreeMap<String, Double> map = Maps.newTreeMap();
 88             responseList.forEach(x -> {
 89                 map.put(x.getWeekNo().substring(0, 4) + "第" + x.getWeekNo().substring(4, 6) + "周", x.getAmount());
 90                 hasData.add(x.getWeekNo());
 91             });
 92             responseDate.removeAll(hasData);
 93             responseDate.forEach(noData -> {
 94                 map.put(noData.substring(0, 4) + "第" + noData.substring(4, 6) + "周", 0.00);
 95             });
 96             if (map.size() > 12) {
 97                 map.remove(map.firstKey());
 98             }
 99             return OpenAPiJsonResult.success(map);
100         } else {
101             // 按月
102             List<String> hasData = Lists.newArrayList();
103             TreeMap<String, Double> map = Maps.newTreeMap();
104             responseList.forEach(x -> {
105                 if (convertData.contains(x.getMonthNo())) {
106                     x.setMonthNo("0" + x.getMonthNo());
107                 }
108                 String str = x.getYearNo() + "-" + x.getMonthNo();
109                 map.put(str + "月", x.getAmount());
110                 hasData.add(str);
111             });
112             responseDate.removeAll(hasData);
113             responseDate.forEach(noData -> {
114                 map.put(noData + "月", 0.00);
115             });
116             return OpenAPiJsonResult.success(map);
117         }
118     }
业务层参考代码
  1   /**
  2      * 根据当前周号,计算n周前或后的周一日期
  3      *
  4      * @param year
  5      * @param week
  6      * @param targetNum
  7      * @return
  8      */
  9     public static String getWeekDays(int year, int week, int targetNum) {
 10         // 计算目标周数
 11         if (week + targetNum > 52) {
 12             year++;
 13         } else if (week + targetNum <= 0) {
 14             year--;
 15             week += targetNum + 52;
 16         } else {
 17             week += targetNum;
 18         }
 19 
 20         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 21         Calendar cal = Calendar.getInstance();
 22 
 23         // 设置每周的开始日期
 24         cal.setFirstDayOfWeek(Calendar.MONDAY);
 25 
 26         cal.set(Calendar.YEAR, year);
 27         cal.set(Calendar.WEEK_OF_YEAR, week);
 28         cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
 29 
 30         // 该周周一
 31         String beginDate = sdf.format(cal.getTime());
 32 
 33         cal.add(Calendar.DAY_OF_WEEK, 6);
 34         // 该周周日
 35         String endDate = sdf.format(cal.getTime());
 36 
 37         return beginDate;
 38     }
 39 
 40     /**
 41      * 根据年,周号,获取该周周日
 42      *
 43      * @return
 44      */
 45     public static LocalDate getDateByYearAndWeekNo(int year, int week) {
 46         WeekFields weekFields2 = WeekFields.of(DayOfWeek.MONDAY, 4);
 47         LocalDate sunday = LocalDate.now()
 48                 .withYear(year)
 49                 .with(weekFields2.weekOfYear(), week)
 50                 .with(weekFields2.dayOfWeek(), 7L);
 51 
 52         return sunday;
 53     }
 54 
 55     /**
 56      * 日期加、减几月
 57      *
 58      * @param str
 59      * @param amount 正数加,负数减
 60      * @return
 61      * @throws Exception
 62      */
 63     public static String dateMinusMonth(String str, int amount) throws Exception {
 64         SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
 65         Date dt = sdf.parse(str);//将字符串生成Date
 66         Calendar rightNow = Calendar.getInstance();
 67         rightNow.setTime(dt);//使用给定的 Date 设置此 Calendar 的时间。
 68         rightNow.add(Calendar.MONTH, amount);// 日期减1个月
 69         Date dt1 = rightNow.getTime();//返回一个表示此 Calendar 时间值的 Date 对象。
 70         String reStr = sdf.format(dt1);//将给定的 Date 格式化为日期/时间字符串,并将结果添加到给定的 StringBuffer。
 71         return reStr;
 72     }
 73 
 74     /**
 75      * 获取某个月最后一天
 76      *
 77      * @param datadate
 78      * @return
 79      * @throws Exception
 80      */
 81     public static String getLastDay(String datadate) throws Exception {
 82         Date date = null;
 83         String day_last = null;
 84         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
 85         date = format.parse(datadate);
 86 
 87 //创建日历
 88         Calendar calendar = Calendar.getInstance();
 89         calendar.setTime(date);
 90         calendar.add(Calendar.MONTH, 1); //加一个月
 91         calendar.set(Calendar.DATE, 1);//设置为该月第一天
 92         calendar.add(Calendar.DATE, -1);//再减一天即为上个月最后一天
 93         day_last = format.format(calendar.getTime());
 94         return day_last;
 95     }
 96 
 97     /**
 98      * 获取时间段内,所有天
 99      *
100      * @param dBegin
101      * @param dEnd
102      * @return
103      * @throws ParseException
104      */
105     public static List<String> findDates(String dBegin, String dEnd) throws ParseException {
106         //日期工具类准备
107         DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
108         //设置开始时间
109         Calendar calBegin = Calendar.getInstance();
110         calBegin.setTime(format.parse(dBegin));
111         //设置结束时间
112         Calendar calEnd = Calendar.getInstance();
113         calEnd.setTime(format.parse(dEnd));
114         //装返回的日期集合容器
115         List<String> datelist = new ArrayList<String>();
116         // 每次循环给calBegin日期加一天,直到calBegin.getTime()时间等于dEnd
117         while (format.parse(dEnd).after(calBegin.getTime())) {
118             // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
119             calBegin.add(Calendar.DAY_OF_MONTH, 1);
120             datelist.add(format.format(calBegin.getTime()));
121         }
122         return datelist;
123     }
124 
125     /**
126      * 获取一段时间内,所有月份
127      *
128      * @param minDate
129      * @param maxDate
130      * @return
131      * @throws ParseException
132      */
133     public static List<String> getMonthBetween(String minDate, String maxDate) throws ParseException {
134         ArrayList<String> result = new ArrayList<String>();
135         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月
136 
137         Calendar min = Calendar.getInstance();
138         Calendar max = Calendar.getInstance();
139 
140         min.setTime(sdf.parse(minDate));
141         min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
142 
143         max.setTime(sdf.parse(maxDate));
144         max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
145 
146         Calendar curr = min;
147         while (curr.before(max)) {
148             result.add(sdf.format(curr.getTime()));
149             curr.add(Calendar.MONTH, 1);
150         }
151 
152         return result;
153     }
154 
155     /**
156      * 获取时间段内所有的周,注意:需要指定周计数策略
157      *
158      * @param startStr
159      * @param endStr
160      * @return
161      */
162     @SuppressWarnings("all")
163     public static Set<String> getWeekBetween(String startStr, String endStr) {
164         WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY, 4);
165         LocalDate start = DateUtil.stringToLocalDate(startStr);
166         LocalDate end = DateUtil.stringToLocalDate(endStr);
167         int startY = start.get(weekFields.weekBasedYear());
168         int startW = start.get(weekFields.weekOfWeekBasedYear());
169         int endY = end.get(weekFields.weekBasedYear());
170         int endW = end.get(weekFields.weekOfWeekBasedYear());
171         List<Integer> convertData = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).collect(toList());
172         Set<String> response = Sets.newTreeSet();
173         if (endY - startY == 0) {// 同一年
174             for (int i = startW; i <= endW; i++) {
175                 if (convertData.contains(i)) {
176                     response.add(endY + "0" + i);
177                 } else {
178                     response.add(endY + "" + i);
179                 }
180             }
181             return response;
182         } else if (endY - startY == 1) { // 这里因业务只统计跨度为12周的数据,所以只考虑年差距在一年的情况
183             String lastDay = startY + "-12-31";  // 获取起始年最大周数
184             int maxWeek = DateUtil.stringToLocalDate(lastDay).get(weekFields.weekOfYear());
185             for (int i = startW; i <= maxWeek; i++) {
186                 if (convertData.contains(i)) {
187                     response.add(startY + "0" + i);
188                 } else {
189                     response.add(startY + "" + i);
190                 }
191             }
192             for (int j = 1; j <= endW; j++) {
193                 if (convertData.contains(j)) {
194                     response.add(endY + "0" + j);
195                 } else {
196                     response.add(endY + "" + j);
197                 }
198             }
199             return response;
200         } else {// 暂不考虑
201             return null;
202         }
203     }
工具类参考代码
 1   <select id="selectCountTradeTrend" resultMap="CountPayTrend">
 2         select
 3         <if test="queryType == 0">
 4             MONTH(pay_time) as month_no,
 5             DAY(pay_time) as day_no,
 6         </if>
 7         <if test="queryType == 1">
 8             yearweek(pay_time,3) as week_no,
 9         </if>
10         <if test="queryType == 2">
11             MONTH(pay_time) as month_no,
12         </if>
13         YEAR(pay_time) as year_no,
14         SUM(practical_deal_price) as amount
15         from
16         <include refid="tableName"/>
17         <where>
18             org_id = #{orgId}
19             and store_id = #{storeId}
20             and is_del = 0
21             <if test="startDate != null and startDate != ''">
22                 and pay_time &gt;= #{startDate}
23             </if>
24             <if test="endDate != null and endDate != ''">
25                 and pay_time &lt;= #{endDate}
26             </if>
27         </where>
28         GROUP BY
29         <if test="queryType == 0">
30             DAY(pay_time)
31         </if>
32         <if test="queryType == 1">
33             yearweek(pay_time,3)
34         </if>
35         <if test="queryType == 2">
36             MONTH(pay_time)
37         </if>
38     </select>
持久层参考代码

 

     

posted @ 2019-12-13 16:09  梦飞翔up  阅读(5953)  评论(1编辑  收藏  举报