diff --git a/yanzhu-bigscreen/src/views/schedule/planSchedule.vue b/yanzhu-bigscreen/src/views/schedule/planSchedule.vue index 0a8c0949..721c16e8 100644 --- a/yanzhu-bigscreen/src/views/schedule/planSchedule.vue +++ b/yanzhu-bigscreen/src/views/schedule/planSchedule.vue @@ -1,1160 +1,1241 @@ \ No newline at end of file diff --git a/yanzhu-bigscreen/src/views/schedule/task_trend.js b/yanzhu-bigscreen/src/views/schedule/task_trend.js new file mode 100644 index 00000000..d0c78afa --- /dev/null +++ b/yanzhu-bigscreen/src/views/schedule/task_trend.js @@ -0,0 +1,332 @@ +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 + "
"; + // 查找当前日期的数据 + 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 + " 天
"; + result += "计划天数: " + plannedDays + " 天
"; + result += "完成天数: " + actualCompletedDays + " 天
"; + } + + params.forEach((param) => { + // 处理null值和undefined的情况 + if (param.value === null || param.value === undefined) { + result += param.marker + param.seriesName + ": 无数据
"; + } else { + result += + param.marker + + param.seriesName + + ": " + + param.value.toFixed(2) + + "%
"; + } + }); + 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, +};