Java,处理不连续的时间段统计值用于制作折线图

用于统计的折线图点类NumberVO

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="数据统计类")
public class NumberVO {

    @ApiModelProperty(value = "统计属性的名称,如镇名、举报来源")
    private String name;

    @ApiModelProperty(value = "统计数量")
    private Integer number;

    @ApiModelProperty(value = "占总体比例")
    private Double rate;

}
/**
     * 根据传入的类型处理表格数据,填补数据量为零的天数、月份统计点,以便前端做折线图展现
     *
     * @param data
     * @param startTime
     * @param endTime
     * @param type
     * @return List<NumberVO>
     */
    private List<NumberVO> toChart(List<NumberVO> data, String startTime, String endTime, int type) {
        LocalDate start = LocalDate.of(Integer.parseInt(startTime.substring(0, 4)), Integer.parseInt(startTime.substring(5, 7)), Integer.parseInt(startTime.substring(8, 10)));
        LocalDate end = LocalDate.of(Integer.parseInt(endTime.substring(0, 4)), Integer.parseInt(endTime.substring(5, 7)), Integer.parseInt(endTime.substring(8, 10)));
        //data里有不连续的天数,月份统计值等
        if (type == 1) {
            int startDayOfYear = start.getDayOfYear();
            int endDayOfYear = end.getDayOfYear();
            //计算时间段内一共有多少天
            int days = endDayOfYear - startDayOfYear + 1;
            //折线图的下标用具体天数
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            List<NumberVO> result = new ArrayList<>(days);
            LocalDate temp = start;
            //为每一天生成统计对象,如果没有统计值则为0,以生成连续的天数数组用于绘图
            for (int i = 0; i < days; i++) {
                NumberVO item = new NumberVO();
                int theDay = temp.getDayOfMonth();
                item.setName(dateTimeFormatter.format(temp));
                item.setNumber(0);
                //遍历统计值数组取到对应天的统计值
                for (NumberVO numberVO : data) {
                    if (Integer.parseInt(numberVO.getName()) == theDay) {
                        item.setNumber(numberVO.getNumber());
                        break;
                    }
                }
                result.add(item);
                //转到下一天
                temp = temp.plusDays(1);
            }
            //返回连续天数的统计结果
            return result;
        }
        if (type == 2) {
            //按周统计时时间跨度不能过大,此处是小于等于六个月
            int startWeek = getWeekNumber(start);
            int endWeek = getWeekNumber(end);
            int weeks;
            if (endWeek > startWeek) {
                weeks = endWeek - startWeek + 1;
            } else {
                weeks = endWeek + 52 - startWeek + 1;
            }
            List<NumberVO> result = new ArrayList<>(weeks);
            int temp = startWeek;
            for (int i = 0; i < weeks; i++) {
                NumberVO item = new NumberVO();
                item.setName(temp + "");
                item.setNumber(0);
                //遍历统计值数组取到对应天的统计值
                for (NumberVO numberVO : data) {
                    if (Integer.parseInt(numberVO.getName()) == temp) {
                        item.setNumber(numberVO.getNumber());
                        break;
                    }
                }
                result.add(item);
                //转到下一周
                temp++;
                if (temp > 52) {
                    temp = temp - 52;
                }
            }
            //返回连续周数
            return result;
        }
        if (type == 3) {
            //折线图的下标用具体月份
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
            List<NumberVO> result = new ArrayList<>();
            int months = 0;
            LocalDate temp = start;
            //为每月生成统计对象,如果没有统计值则为0,以生成连续的月份数组用于绘图
            while (true) {
                NumberVO item = new NumberVO();
                int theMonth = temp.getMonth().getValue();
                int theYear = temp.getYear();
                item.setName(dateTimeFormatter.format(temp));
                //先默认为0
                item.setNumber(0);
                //去匹配数据库统计数据
                for (NumberVO numberVO : data) {
                    //按月统计时,NumberVO里的rate是借用该属性从数据库带出来的年份值
                    int itemYear = Integer.parseInt(String.valueOf(numberVO.getRate()).substring(0, 4));
                    //年份月份一样,说明是当前月的数据
                    if (Integer.parseInt(numberVO.getName()) == theMonth && itemYear == theYear) {
                        //如有统计值,替换默认值
                        item.setNumber(numberVO.getNumber());
                        // 取到此条数据后,跳出取数循环
                        break;
                    }
                }
                result.add(item);
                if (temp.getMonth().equals(end.getMonth()) && temp.getYear() == end.getYear()) {
                    //跳出条件1,当刚刚处理的月份已经达结束月份时,结束循环
                    break;
                }
                //开始处理下一个月
                temp = temp.plusMonths(1);
                months++;
                if (months > 36) {
                    //跳出条件2,预防死循环,最多统计三年时长
                    break;
                }
            }
            //返回连续月份的统计结果
            return result;
        }
        return null;
    }

用于计算周数的方法

    private int getWeekNumber(LocalDate localDate) {
        //获取当前时间第X周
        /*
        public static WeekFields of(DayOfWeek firstDayOfWeek, int minimalDaysInFirstWeek)
        从第一天和最小日期获得WeekFields的实例。
        第一天的每周定义ISO DayOfWeek ,即一周中的第一天。 第一周的最小天数定义一个月或一年中必须存在的天数,从第一天开始,在将一周计算为第一周之前。 值1将计算作为第一周的一部分的月或年的第一天,而值7将要求整个七天在新的月或年中。

        WeekFields实例是单例; 对于firstDayOfWeek和minimalDaysInFirstWeek的每个唯一组合,将返回相同的实例。

        参数
        firstDayOfWeek - 一周的第一天,不是null
        minimalDaysInFirstWeek - 第一周的最小天数,从1到7
         */
        WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY, 4);
        int weekNumber = localDate.get(weekFields.weekOfYear());
        return weekNumber;
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值