【工具类】---JAVA图表日期工具类

由于部门业务主要聚焦于工业4.0的领域,最近涉及到了比较多的双碳(碳中和,碳排放)的数据统计和分析。凡是涉及到数据,则肯定会连带出各种图标数据,也就离不开时间和数据的关系。

因此为了方便,自己抽出了一份平时我写给自己用的日期图表工具类(折线图,柱状图)
首先是要有一个对应的x轴y轴返回类啦,可以根据传入的T来给到具体的y轴类型

/**
 * x轴y轴类,y轴可以传入具体的类型
 * @param 
 */
class TimeValChartVO<T> {

    List<String> xAxis;

    List<T> yAxis;

    public List<String> getxAxis() {
        return xAxis;
    }
.......
//省略Getter和Setter,toString,hashcode,equals

接着就是获得各种类型的x轴,(当天的时间点,当周的星期,当月的天,当年的月份)

    /**
     * 获取当天任意某个时间段里的每个时间点 ---(传入开始的时间点和结束的时间点)
     * @param startTime 开始时间点
     * @param endTime 结束时间点
     * @return
     */
    public static List<String> getDayXAxis(int startTime, int endTime) {
        //一个小时一次的查询
        ArrayList<String> x = new ArrayList<>();
        for (int i = startTime; i <= endTime; i++) {
            x.add(i + "点");
        }
        return x;
    }

    /**
     * 取本周任意某个时间段(几天内)里的星期 ---(传入开始的星期和结束的星期)
     * @param startTime 开始周几
     * @param endTime   结束周几
     * @return
     */
    public static List<String> getWeekDayXAxis(Date startTime, Date endTime) {
        List<String> x = new ArrayList<>();
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar c = Calendar.getInstance();
        c.setTime(startTime);
        //计算开始时间是周几
        int w = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        c.setTime(endTime);
        int e = c.get(Calendar.DAY_OF_WEEK) - 1;
        //判断总长度,比他小,就是在前面,比他大则
        int len = e > w ? Math.abs(e - w) + 1 : weekDays.length - w + e + 1;
        while (len > 0) {
            x.add(weekDays[w]);
            w = (w + 1) % weekDays.length;
            len--;
        }
        return x;
    }

    /**
     * 获取每个时间
     * @param formatStr 日期展示格式
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @return
     */
    public static List<String> getDateXAxisData(String formatStr, LocalDateTime startDate, LocalDateTime endDate){
        //日期格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatStr);
        ArrayList<String> x = new ArrayList<>();
        //遍历给定的日期期间的每一天
        for (int i = 0; !Duration.between(startDate.plusDays(i), endDate).isNegative(); i++) {
            //添加日期
            x.add(startDate.plusDays(i).format(formatter));
        }
        return x;
    }

    /**
     *  获取每个月份
     * @param formatStr 月份展示格式
     * @param startDate 开始月份
     * @param endDate 结束月份
     * @return
     */
    public static List<String> getMonthXAxisData(String formatStr, LocalDateTime startDate, LocalDateTime endDate){
        //日期格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatStr);
        List<String> xAxis = new ArrayList<>();
        //遍历给定的日期期间的每一天
        for (int i = 0; !Duration.between(startDate.plusMonths(i), endDate).isNegative(); i++) {
            //添加日期
            xAxis.add(startDate.plusMonths(i).format(formatter));
        }
        return xAxis;
    }

对应的参考SQL示例(具体的示例可以按需搜索):

        SELECT DATE(分组时间字段) AS 对象时间字段,SUM(统计的数值字段) AS 对象的数值字段 FROM 表名
        WHERE 分组时间字段 BETWEEN 开始时间 AND 结束时间
        GROUP BY 对象的数值字段
        ORDER BY 对象的数值字段 DESC

最后可以根据个人需要把返回的对象转成map,方便遍历处理,附上自己的转map方法(其中,keyFieldName对应map的key,valueFieldName对应map的key,T代表map的value具体类型):

/**
     * 把key-value对象转map
     * @param list
     * @param t
     * @param keyFieldName
     * @param valueFieldName
     * @return
     * @param 
     */
    private <T> Map<String, T> getDateNumsMap(List<?> list, Class<T> t,String keyFieldName,String valueFieldName) {
        Map<String, T> map = new HashMap<>(16);
        list.forEach(f ->{
            try {
                Field at = f.getClass().getDeclaredField("at");
                Field val = f.getClass().getDeclaredField("val");
                at.setAccessible(true);
                val.setAccessible(true);
                map.put((String) at.get(f),  (T)val.get(f));
            } catch (NoSuchFieldException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        });
        return map;
    }

然后还有我自己的一个遍历时间x轴,给sql缺少统计数据的value填上默认值(比如0,1,null那种)

 /**
     * 通过传入的时间列表和数据流,填充到对应的xy点位上
     * @param dateTimeList 完整的时间列
     * @param data 统计出来的数据集合
     * @param initVal 当map为空需要的默认值(0,null...)
     * @return
     * @param 
     */
    public <T> List<T> completionYAxisData(List<String> dateTimeList, Map<String,?> data, T initVal){
        ArrayList<T> dateList = new ArrayList<>(16);
        for(int i=0;i<xAxisData.size();i++){
            if(data == null ||data.get(xAxisData.get(i))==null){
                dateList.add(i,initVal);
            }else{
                dateList.add(i,(T)data.get(xAxisData.get(i)));
            }
        }
        return dateList;
    }

你可能感兴趣的:(Date,java,java,python,windows)