修改大屏计划实施进度

dev_xd
lj7788@126.com 2025-09-29 11:39:12 +08:00
parent 9c1c610c4a
commit 5ae359832c
1 changed files with 194 additions and 193 deletions

View File

@ -1,4 +1,7 @@
function aggregateDataByDate(executionData) { function aggregateDataByDate(executionData) {
if (executionData.length == 0) {
return [];
}
const dateMap = new Map(); const dateMap = new Map();
// 按start排序相同时按end排序 // 按start排序相同时按end排序
executionData.sort((a, b) => { executionData.sort((a, b) => {
@ -11,6 +14,7 @@ function aggregateDataByDate(executionData) {
const endB = new Date(b.end); const endB = new Date(b.end);
return endA - endB; return endA - endB;
}); });
// 获取整个时间范围 // 获取整个时间范围
let minDate = new Date(executionData[0].start); let minDate = new Date(executionData[0].start);
let maxDate = new Date(executionData[0].end); let maxDate = new Date(executionData[0].end);
@ -32,25 +36,43 @@ function aggregateDataByDate(executionData) {
date: dateStr, date: dateStr,
planned: 0, planned: 0,
completed: 0, completed: 0,
progressSum: 0,
progressCount: 0,
}); });
currentDate.setDate(currentDate.getDate() + 1); currentDate.setDate(currentDate.getDate() + 1);
} }
// 为每个任务创建日期范围 // 按新规则计算每个任务的计划天数和完成天数分布
executionData.forEach((task) => { executionData.forEach((task) => {
const startDate = new Date(task.start); const startDate = new Date(task.start);
const endDate = new Date(task.end); const endDate = new Date(task.end);
const days = task.days;
const process = task.process || 0;
const completedDays = days * process;
// 遍历任务的每一天 // 计算任务覆盖的总天数
const timeDiff = endDate.getTime() - startDate.getTime();
const totalTaskDays = Math.ceil(timeDiff / (1000 * 3600 * 24)) + 1;
// 按照100%、100%、100%...的方式分配完成天数
const currentTaskDate = new Date(startDate); const currentTaskDate = new Date(startDate);
while (currentTaskDate <= endDate) { let remainingCompletedDays = completedDays;
for (let i = 0; i < totalTaskDays; i++) {
const dateStr = currentTaskDate.toISOString().split("T")[0]; const dateStr = currentTaskDate.toISOString().split("T")[0];
if (dateMap.has(dateStr)) { if (dateMap.has(dateStr)) {
// 增加计划任务数 // 每天计划1天
dateMap.get(dateStr).planned += 1; dateMap.get(dateStr).planned += 1;
// 分配完成天数
if (remainingCompletedDays >= 1) {
// 完成1天
dateMap.get(dateStr).completed += 1;
remainingCompletedDays -= 1;
} else if (remainingCompletedDays > 0) {
// 完成剩余天数
dateMap.get(dateStr).completed += remainingCompletedDays;
remainingCompletedDays = 0;
}
} }
// 移动到下一天 // 移动到下一天
@ -58,59 +80,15 @@ function aggregateDataByDate(executionData) {
} }
}); });
// 统计完成任务(基于开始日期)
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) => { const result = Array.from(dateMap.values()).sort((a, b) => {
return new Date(a.date) - new Date(b.date); 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) => { result.forEach((item) => {
totalPlanned += item.planned; item.planned = Math.round(item.planned * 10) / 10;
// 检查日期是否在今天之后 item.completed = Math.round(item.completed * 10) / 10;
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; return result;
@ -119,170 +97,184 @@ function aggregateDataByDate(executionData) {
function makeTaskTrendOptions(that, datas) { function makeTaskTrendOptions(that, datas) {
// 填充统计数据表格 // 填充统计数据表格
const summaryData = aggregateDataByDate(datas); const summaryData = aggregateDataByDate(datas);
// 准备图表数据
// 准备图表数据 // 准备图表数据
const dates = summaryData.map((item) => item.date); 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; let tableCumulativePlanned = 0;
let tableCumulativeCompleted = 0;
summaryData.forEach((item) => {
// 计算累积数据
tableCumulativePlanned += item.planned;
tableCumulativeCompleted += item.completed;
item.cumulativePlanned = tableCumulativePlanned;
item.cumulativeCompleted = tableCumulativeCompleted;
});
// 获取今天的日期
const today = new Date();
today.setHours(0, 0, 0, 0);
// 处理柱形图数据
const plannedData = [];
const completedData = [];
summaryData.forEach((item) => {
// 计划任务天数始终显示
plannedData.push(item.planned);
// 检查日期是否在今天之后
const itemDate = new Date(item.date);
if (itemDate > today) {
// 今日之后的已完成任务天数设置为null
completedData.push(null);
} else {
// 今日及之前的已完成任务天数正常显示
completedData.push(item.completed);
}
}); });
const cumulativeCompleted = summaryData.map((item) => { // 计算累积数据用于图表
// 如果completed为null表示该日期在今日之后返回null let chartCumulativePlanned = 0;
if (item.cumulativeCompleted === null) { let chartCumulativeCompleted = 0;
return null; const cumulativePlannedData = [];
const cumulativeCompletedData = [];
// 计算总计划天数和总完成天数用于百分比计算
const totalPlannedDays = summaryData.reduce(
(sum, item) => sum + item.planned,
0
);
const totalCompletedDays = summaryData.reduce(
(sum, item) => sum + item.completed,
0
);
summaryData.forEach((item, index) => {
chartCumulativePlanned += item.planned;
chartCumulativeCompleted += item.completed;
cumulativePlannedData.push(
totalPlannedDays > 0
? Math.round((chartCumulativePlanned / totalPlannedDays) * 1000) / 10
: 0
);
// 检查日期是否在今天之后
const itemDate = new Date(item.date);
if (itemDate > today) {
// 今日之后的数据设置为null这样折线图就不会显示
cumulativeCompletedData.push(null);
} else {
cumulativeCompletedData.push(
totalPlannedDays > 0
? Math.round((chartCumulativeCompleted / totalPlannedDays) * 1000) /
10
: 0
);
} }
const totalTasks = summaryData[summaryData.length - 1].cumulativePlanned;
return totalTasks > 0 ? (item.cumulativeCompleted / totalTasks) * 100 : 0;
}); });
let is1K = that.$dpi() == "1K"; let is1K = that.$dpi() == "1K";
let is2K = that.$dpi() == "2K"; let is2K = that.$dpi() == "2K";
// 配置图表选项 // 配置图表选项
const option = { const option = {
tooltip: { tooltip: {
trigger: "axis", trigger: "axis",
formatter: function (params) { formatter: function (params) {
let planTotal = summaryData[summaryData.length - 1].cumulativePlanned;
let result = params[0].name + "<br/>"; 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) => { params.forEach((param) => {
// 处理null值和undefined的情况 if (
if (param.value === null || param.value === undefined) { param.seriesName.includes("天数") &&
result += param.marker + param.seriesName + ": 无数据<br/>"; !param.seriesName.includes("累积")
) {
if (typeof param.value !== "undefined") {
result +=
param.marker +
param.seriesName +
": " +
param.value +
" 天<br/>";
}
} else { } else {
result += if (typeof param.value !== "undefined") {
param.marker + result +=
param.seriesName + param.marker + param.seriesName + ": " + param.value + "%<br/>";
": " + }
param.value.toFixed(2) +
"%<br/>";
} }
}); });
result +=
"计划任务总天数:" +
planTotal.toFixed(2) +
"<br/>" +
"累积计划任务天数:" +
summaryData[params[0].dataIndex].cumulativePlanned.toFixed(2) +
"<br/>累积已完成任务天数:" +
summaryData[params[0].dataIndex].cumulativeCompleted.toFixed(2);
return result; return result;
}, },
axisPointer: { axisPointer: {
lineStyle: { lineStyle: {
color: "#57617B", color: "#57617B",
}, },
}, textStyle: {
textStyle: { fontSize: is1K ? 12 : is2K ? 18 : 20,
fontSize: is1K ? 12 : is2K ? 18 : 20, },
}, },
}, },
legend: { legend: {
icon: "rect", data: [
itemWidth: 14, "当天计划任务天数",
itemHeight: 10, "当天已完成任务天数",
itemGap: 15, "累积计划任务天数",
data: ["计划任务累积进度", "已完成任务累积进度"], "累积已完成任务天数",
top: -5, ],
textStyle: { textStyle: {
fontSize: is1K ? 12 : is2K ? 20 : 30, fontSize: is1K ? 12 : is2K ? 14 : 18,
color: "#c8dbfc", color: "#aaa",
}, },
}, },
grid: {
top: "10%",
left: "2%",
right: "3%",
bottom: "5%",
containLabel: true,
},
xAxis: { xAxis: {
boundaryGap: false,
type: "category", type: "category",
data: dates, data: dates,
axisLine: {
//坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: "#25597e",
type: "dashed",
},
},
axisTick: {
show: false,
},
axisLabel: { axisLabel: {
//坐标轴刻度标签的相关设置 fontSize: is1K ? 12 : is2K ? 14 : 18,
textStyle: { color: "#aaa",
color: "#c5d9fc",
margin: 20,
fontSize: 12,
},
}, },
}, },
yAxis: { yAxis: [
type: "value", {
name: "累积进度 (%)", type: "value",
axisLabel: { name: "任务天数",
formatter: "{value} %", position: "left",
//坐标轴刻度标签的相关设置 nameTextStyle: {
textStyle: { color: "#bbb" ,
color: "#c5d9fc", fontSize: is1K ? 14 : is2K ? 16 : 20,
margin: 20, },
fontSize: is1K ? 12 : is2K ? 16 : 20, axisLabel: {
fontSize: is1K ? 12 : is2K ? 14 : 18,
color: "#aaa",
}, },
}, },
nameTextStyle: { {
color: "#c5d9fc", type: "value",
fontSize: is1K ? 12 : is2K ? 18 : 24, name: "百分比 (%)",
}, position: "right",
axisLine: { nameTextStyle: {
//坐标轴轴线相关设置。数学上的x轴 color: "#bbb" ,
show: false, fontSize: is1K ? 14 : is2K ? 16 : 20,
lineStyle: { },
color: "#c5d9fc", axisLabel: {
type: "dashed", formatter: "{value} %",
fontSize: is1K ? 12 : is2K ? 14 : 18,
color: "#aaa",
}, },
}, },
axisTick: { ],
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: "#25597e",
type: "dashed",
},
},
},
dataZoom: [ dataZoom: [
{ {
type: "inside", type: "inside",
@ -296,31 +288,40 @@ function makeTaskTrendOptions(that, datas) {
], ],
series: [ series: [
{ {
name: "计划任务累积进度", name: "当天计划任务天数",
type: "line", type: "bar",
data: cumulativePlanned, data: plannedData,
smooth: true,
itemStyle: { itemStyle: {
color: "#36A2EB", color: "#36A2EB",
}, },
areaStyle: {
color: "#36A2EB",
opacity: 0.2,
},
}, },
{ {
name: "已完成任务累积进度", name: "当天已完成任务天数",
type: "line", type: "bar",
data: cumulativeCompleted, data: completedData,
connectNulls: false, // 不连接null值
smooth: true,
itemStyle: { itemStyle: {
color: "#FF6384", color: "#FF6384",
}, },
areaStyle: { },
color: "#FF6384", {
opacity: 0.2, name: "累积计划任务天数",
type: "line",
data: cumulativePlannedData,
itemStyle: {
color: "#1f77b4",
}, },
smooth: true,
yAxisIndex: 1,
},
{
name: "累积已完成任务天数",
type: "line",
data: cumulativeCompletedData,
itemStyle: {
color: "#d62728",
},
smooth: true,
yAxisIndex: 1,
}, },
], ],
}; };