YZProjectCloud/yanzhu-bigscreen/src/views/schedule/task_trend.js

333 lines
8.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

function aggregateDataByDate(executionData) {
const dateMap = new Map();
// 按start排序相同时按end排序
executionData.sort((a, b) => {
const startA = new Date(a.start);
const startB = new Date(b.start);
if (startA.getTime() !== startB.getTime()) {
return startA - startB;
}
const endA = new Date(a.end);
const endB = new Date(b.end);
return endA - endB;
});
// 获取整个时间范围
let minDate = new Date(executionData[0].start);
let maxDate = new Date(executionData[0].end);
// 遍历所有任务,找到最小和最大日期
executionData.forEach((task) => {
const startDate = new Date(task.start);
const endDate = new Date(task.end);
if (startDate < minDate) minDate = startDate;
if (endDate > maxDate) maxDate = endDate;
});
// 初始化每一天的数据
const currentDate = new Date(minDate);
while (currentDate <= maxDate) {
const dateStr = currentDate.toISOString().split("T")[0];
dateMap.set(dateStr, {
date: dateStr,
planned: 0,
completed: 0,
progressSum: 0,
progressCount: 0,
});
currentDate.setDate(currentDate.getDate() + 1);
}
// 为每个任务创建日期范围
executionData.forEach((task) => {
const startDate = new Date(task.start);
const endDate = new Date(task.end);
// 遍历任务的每一天
const currentTaskDate = new Date(startDate);
while (currentTaskDate <= endDate) {
const dateStr = currentTaskDate.toISOString().split("T")[0];
if (dateMap.has(dateStr)) {
// 增加计划任务数
dateMap.get(dateStr).planned += 1;
}
// 移动到下一天
currentTaskDate.setDate(currentTaskDate.getDate() + 1);
}
});
// 统计完成任务(基于开始日期)
executionData.forEach((task) => {
if (task.process !== null) {
const startDate = task.start;
if (dateMap.has(startDate)) {
dateMap.get(startDate).completed += 1;
dateMap.get(startDate).progressSum += task.process;
dateMap.get(startDate).progressCount += 1;
}
}
});
// 转换为数组并按日期排序
const result = Array.from(dateMap.values()).sort((a, b) => {
return new Date(a.date) - new Date(b.date);
});
// 获取今天的日期
const today = new Date();
today.setHours(0, 0, 0, 0);
// 计算累积进度
let totalPlanned = 0;
let totalCompleted = 0;
let totalProgressSum = 0;
let totalProgressCount = 0;
result.forEach((item) => {
totalPlanned += item.planned;
// 检查日期是否在今天之后
const itemDate = new Date(item.date);
if (itemDate > today) {
// 今日之后的数据设置为null
item.completed = null;
item.progressSum = null;
item.progressCount = null;
} else {
totalCompleted += item.completed || 0;
totalProgressSum += item.progressSum || 0;
totalProgressCount += item.progressCount || 0;
}
// 添加累积数据
item.cumulativePlanned = totalPlanned;
// 对于今日之后的数据cumulativeCompleted也设置为null
if (new Date(item.date) > today) {
item.cumulativeCompleted = null;
} else {
item.cumulativeCompleted = totalCompleted;
}
item.cumulativeProgress =
totalProgressCount > 0 ? totalProgressSum / totalProgressCount : 0;
});
return result;
}
function makeTaskTrendOptions(that, datas) {
// 填充统计数据表格
const summaryData = aggregateDataByDate(datas);
// 准备图表数据
const dates = summaryData.map((item) => item.date);
const cumulativePlanned = summaryData.map((item) => {
const totalTasks = summaryData[summaryData.length - 1].cumulativePlanned;
return totalTasks > 0 ? (item.cumulativePlanned / totalTasks) * 100 : 0;
});
const cumulativeCompleted = summaryData.map((item) => {
// 如果completed为null表示该日期在今日之后返回null
if (item.cumulativeCompleted === null) {
return null;
}
const totalTasks = summaryData[summaryData.length - 1].cumulativePlanned;
return totalTasks > 0 ? (item.cumulativeCompleted / totalTasks) * 100 : 0;
});
let is1K = that.$dpi() == "1K";
let is2K = that.$dpi() == "2K";
// 配置图表选项
const option = {
tooltip: {
trigger: "axis",
formatter: function (params) {
let result = params[0].name + "<br/>";
// 查找当前日期的数据
const currentItem = summaryData.find(
(item) => item.date === params[0].name
);
if (currentItem) {
// 计算统计数据
const totalDays = summaryData.length; // 总天数
// 计划完成天数(有计划任务的天数)
const plannedDays = summaryData.filter(
(item) => item.planned > 0
).length;
// 实际完成天数处理
let actualCompletedDays = 0;
const currentDate = new Date(currentItem.date);
const today = new Date();
today.setHours(0, 0, 0, 0);
if (currentDate > today) {
// 今日之后的日期,使用之前最大的完成天数值
const pastData = summaryData.filter((item) => {
const itemDate = new Date(item.date);
return itemDate <= today && item.completed > 0;
});
actualCompletedDays = pastData.length;
} else {
// 今日及之前的日期,使用当前的实际完成天数
actualCompletedDays = summaryData.filter((item) => {
const itemDate = new Date(item.date);
return itemDate <= currentDate && item.completed > 0;
}).length;
}
result += "总天数: " + totalDays + " 天<br/>";
result += "计划天数: " + plannedDays + " 天<br/>";
result += "完成天数: " + actualCompletedDays + " 天<br/>";
}
params.forEach((param) => {
// 处理null值和undefined的情况
if (param.value === null || param.value === undefined) {
result += param.marker + param.seriesName + ": 无数据<br/>";
} else {
result +=
param.marker +
param.seriesName +
": " +
param.value.toFixed(2) +
"%<br/>";
}
});
return result;
},
axisPointer: {
lineStyle: {
color: "#57617B",
},
},
textStyle: {
fontSize: is1K ? 12 : is2K ? 18 : 20,
},
},
legend: {
icon: "rect",
itemWidth: 14,
itemHeight: 10,
itemGap: 15,
data: ["计划任务累积进度", "已完成任务累积进度"],
top: -5,
textStyle: {
fontSize: is1K ? 12 : is2K ? 20 : 30,
color: "#c8dbfc",
},
},
grid: {
top: "10%",
left: "2%",
right: "3%",
bottom: "5%",
containLabel: true,
},
xAxis: {
boundaryGap: false,
type: "category",
data: dates,
axisLine: {
//坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: "#25597e",
type: "dashed",
},
},
axisTick: {
show: false,
},
axisLabel: {
//坐标轴刻度标签的相关设置
textStyle: {
color: "#c5d9fc",
margin: 20,
fontSize: 12,
},
},
},
yAxis: {
type: "value",
name: "累积进度 (%)",
axisLabel: {
formatter: "{value} %",
//坐标轴刻度标签的相关设置
textStyle: {
color: "#c5d9fc",
margin: 20,
fontSize: is1K ? 12 : is2K ? 16 : 20,
},
},
nameTextStyle: {
color: "#c5d9fc",
fontSize: is1K ? 12 : is2K ? 18 : 24,
},
axisLine: {
//坐标轴轴线相关设置。数学上的x轴
show: false,
lineStyle: {
color: "#c5d9fc",
type: "dashed",
},
},
axisTick: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: "#25597e",
type: "dashed",
},
},
},
dataZoom: [
{
type: "inside",
start: 0,
end: 100,
},
{
start: 0,
end: 100,
},
],
series: [
{
name: "计划任务累积进度",
type: "line",
data: cumulativePlanned,
smooth: true,
itemStyle: {
color: "#36A2EB",
},
areaStyle: {
color: "#36A2EB",
opacity: 0.2,
},
},
{
name: "已完成任务累积进度",
type: "line",
data: cumulativeCompleted,
connectNulls: false, // 不连接null值
smooth: true,
itemStyle: {
color: "#FF6384",
},
areaStyle: {
color: "#FF6384",
opacity: 0.2,
},
},
],
};
return option;
}
export default {
makeTaskTrendOptions,
};