• 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>
    持久层参考代码

         

  • 相关阅读:
    YC创始人格雷厄姆为何不喜欢大学生创业?
    在创业的道路上,让公司生存下去是做重要的!
    农村90后李传帅的创业故事
    创业公司的出头之日在哪里?
    创业者不能盲目的跟风,不然结局很凄凉
    小程序到底适不适合创业者
    共享经济的涨潮与退潮就在一瞬间
    互联网行业进入焦虑时代,如何才能做到攻守有道?
    88
    JZOJ.5331【NOIP2017模拟8.23】壕游戏
  • 原文地址:https://www.cnblogs.com/enchaolee/p/12035716.html
Copyright © 2020-2023  润新知