需求来源:后端返回所有时间数组和数值数组,前端按天、周、月进行统计用于图表的展示。
实现效果如下:原始数据是两个数组,date数组存放日期,value数组存放日期对应的数值,经过按周分组和按月分组输出week和month(2020-02-27是周四,2020-03-02是周一,2020-03-09也是周一,符合要求)
封装了两个方法,代码如下:groupByWeek和groupByMonth,输入值均为date-日期数组和value-值数组
const date = ["2020-02-27","2020-02-28","2020-02-29","2020-03-01", "2020-03-02", "2020-03-03", "2020-03-04", "2020-03-05", "2020-03-06", "2020-03-07", "2020-03-08", "2020-03-09", "2020-03-10", "2020-03-11", "2020-03-12", "2020-03-13", "2020-03-14", "2020-03-15", "2020-03-16", "2020-03-17", "2020-03-18", "2020-03-19", "2020-03-20", "2020-03-21"];
const value = [0,0,0,3, 2, 2, 6, 5, 3, 5, 4, 8, 5, 8, 9, 9, 0,4,6,7,8,1,2,3];
console.log({date});
console.log({value});
const week = groupByWeek(date, value);
const month = groupByMonth(date, value);
console.log({week});
console.log({month});
// 按周分组
function groupByWeek(date, value) {
const weekDay = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
const weekDate = [];
let newDate = [];
let newValue = [];
/*遍历,把所有日期转为星期X*/
date.forEach((item) => {
const myDate = new Date(Date.parse(item));
weekDate.push(weekDay[myDate.getDay()]);
});
/*从前往后找第一个“星期日”,返回下标*/
const index = weekDate.findIndex((value)=>{
return value=="星期日";
});
if(index >= 0){ //日期数组内可以找到"星期日"
/*以周为单位开始分组*/
// 第一个周为一个数组,其他的按7天开始分组
const date1 = date.slice(0,index+1);
const date2 = date.slice(index+1,date.length);
const value1 = value.slice(0,index+1);
const value2 = value.slice(index+1,value.length);
newDate.push(date1[0]);
newValue.push(eval(value1.join("+")));
const result = dataGroupFunc(date2, value2, 7);
newDate = newDate.concat(result.newArr1);
newValue = newValue.concat(result.newArr2);
} else { //日期数组内找不到"星期日"
newDate = date;
newValue = [eval(value.join("+"))];
}
return {
newDate: newDate,
newValue:newValue
};
// 图表数据分组方法:arr1-图表横坐标,arr2-图表纵坐标数据,group-以几条数据为一组
function dataGroupFunc(arr1, arr2, group) {
const newArr1 = [];
const newArr2 = [];
for(let i = 0; i < arr1.length;) {
newArr1.push(arr1[i]);
let count = 0;
for (let j = i; j < i+group; j++) {
if (arr2[j]){
count += arr2[j];
}
}
newArr2.push(count);
i+=group;
}
return {
newArr1: newArr1,
newArr2: newArr2
}
}
}
// 按月分组
function groupByMonth(date, value) {
const newDate = [];
const newValue = [];
const newDate1 = [];
const newValue1 = [];
const monthArr = [];
const indexArr = [];
/*遍历,把所有日期的月份取出*/
date.forEach((item) => {
item.split('-');
monthArr.push(item.split('-')[1]);
});
group(monthArr, 0 , 0);
/*根据分好组的下标信息开始截取原始数组*/
indexArr.forEach((item) => {
newDate1.push(date.slice(item[0],item[item.length-1]+1));
newValue1.push(value.slice(item[0],item[item.length-1]+1));
});
/*把每个分组的第一项拿出用于图表横坐标的值*/
newDate1.forEach((item) => {
newDate.push(item[0]);
});
/*计算纵坐标的和值*/
newValue1.forEach((item) => {
newValue.push(eval(item.join("+")));
});
return {
newDate: newDate,
newValue: newValue
};
//数组相同项合一组记录下标
function group(arr, index, index1) {
if (index < arr.length) {
indexArr[index1] = [index];
for(let i=index+1; i<arr.length; i++){
if (arr[i] == arr[index]){
indexArr[index1].push(i);
} else {
group(arr, i, index1+1);
break;
}
}
}
}
}