修改大屏计划实施进度
parent
9c1c610c4a
commit
5ae359832c
|
@ -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("累积")
|
||||||
} else {
|
) {
|
||||||
|
if (typeof param.value !== "undefined") {
|
||||||
result +=
|
result +=
|
||||||
param.marker +
|
param.marker +
|
||||||
param.seriesName +
|
param.seriesName +
|
||||||
": " +
|
": " +
|
||||||
param.value.toFixed(2) +
|
param.value +
|
||||||
"%<br/>";
|
" 天<br/>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (typeof param.value !== "undefined") {
|
||||||
|
result +=
|
||||||
|
param.marker + param.seriesName + ": " + param.value + "%<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: {
|
|
||||||
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: {
|
legend: {
|
||||||
//坐标轴刻度标签的相关设置
|
data: [
|
||||||
|
"当天计划任务天数",
|
||||||
|
"当天已完成任务天数",
|
||||||
|
"累积计划任务天数",
|
||||||
|
"累积已完成任务天数",
|
||||||
|
],
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: "#c5d9fc",
|
fontSize: is1K ? 12 : is2K ? 14 : 18,
|
||||||
margin: 20,
|
color: "#aaa",
|
||||||
fontSize: 12,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: "category",
|
||||||
|
data: dates,
|
||||||
|
axisLabel: {
|
||||||
|
fontSize: is1K ? 12 : is2K ? 14 : 18,
|
||||||
|
color: "#aaa",
|
||||||
},
|
},
|
||||||
yAxis: {
|
},
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
type: "value",
|
type: "value",
|
||||||
name: "累积进度 (%)",
|
name: "任务天数",
|
||||||
|
position: "left",
|
||||||
|
nameTextStyle: {
|
||||||
|
color: "#bbb" ,
|
||||||
|
fontSize: is1K ? 14 : is2K ? 16 : 20,
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
fontSize: is1K ? 12 : is2K ? 14 : 18,
|
||||||
|
color: "#aaa",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "value",
|
||||||
|
name: "百分比 (%)",
|
||||||
|
position: "right",
|
||||||
|
nameTextStyle: {
|
||||||
|
color: "#bbb" ,
|
||||||
|
fontSize: is1K ? 14 : is2K ? 16 : 20,
|
||||||
|
},
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
formatter: "{value} %",
|
formatter: "{value} %",
|
||||||
//坐标轴刻度标签的相关设置
|
fontSize: is1K ? 12 : is2K ? 14 : 18,
|
||||||
textStyle: {
|
color: "#aaa",
|
||||||
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: [
|
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,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue