JavaScript计算时间段重叠 实现visjs时间轴负载分段统计
JavaScript实现时间段重叠拆分与负载统计
核心逻辑
实现分为4步:
- 统一将原始时间字符串转换为时间戳,降低时间比较的复杂度
- 收集所有原始时间段的起止时间点,排序后去重得到时间切片边界
- 遍历相邻两个边界组成的子时间段,统计该时间段被多少个原始时间段覆盖
- 按需求拼接
load字段,将时间戳转回指定格式的字符串即可
完整实现代码
// 时间字符串转时间戳 function parseTime(timeStr) { return new Date(timeStr).getTime(); } // 时间戳转要求的字符串格式 function formatTime(timestamp) { const d = new Date(timestamp); const year = d.getFullYear(); const month = String(d.getMonth() + 1).padStart(2, '0'); const day = String(d.getDate()).padStart(2, '0'); const hour = String(d.getHours()).padStart(2, '0'); const minute = String(d.getMinutes()).padStart(2, '0'); const second = String(d.getSeconds()).padStart(2, '0'); return `${year}-${month}-${day} ${hour}:${minute}:${second}`; } // 核心处理函数 function processTimeSegments(originalSegments) { const total = originalSegments.length; // 1. 转换原始数据为时间戳格式 const timestampSegments = originalSegments.map(item => ({ start: parseTime(item.start), end: parseTime(item.end) })); // 2. 收集所有时间点并排序去重 const allTimePoints = []; timestampSegments.forEach(seg => { allTimePoints.push(seg.start, seg.end); }); // 排序并去重 const sortedUniquePoints = [...new Set(allTimePoints)].sort((a, b) => a - b); // 3. 遍历每个子区间统计覆盖数 const result = []; for (let i = 0; i < sortedUniquePoints.length - 1; i++) { const currentStart = sortedUniquePoints[i]; const currentEnd = sortedUniquePoints[i + 1]; // 统计覆盖当前子区间的原始段数量 let coverCount = 0; timestampSegments.forEach(seg => { // 左闭右开逻辑避免边界重复统计 if (currentStart >= seg.start && currentEnd <= seg.end) { coverCount++; } }); // 只有覆盖数大于0的区间才保留(可根据需求调整) if (coverCount > 0) { result.push({ start: formatTime(currentStart), end: formatTime(currentEnd), load: `${coverCount}/${total}` }); } } return result; } // 测试 const originalData = [ { start: "2021-09-02 02:00:00", end: "2021-09-05 02:00:00"}, { start: "2021-09-03 02:00:00", end: "2021-09-04 02:00:00"}, { start: "2021-09-03 02:00:00", end: "2021-09-03 20:00:00"} ]; console.log(processTimeSegments(originalData));
输出结果
执行代码后得到的输出和你期望的格式完全一致:
[ { start: "2021-09-02 02:00:00", end: "2021-09-03 02:00:00", load: "1/3" }, { start: "2021-09-03 02:00:00", end: "2021-09-03 20:00:00", load: "3/3" }, { start: "2021-09-03 20:00:00", end: "2021-09-04 02:00:00", load: "2/3" }, { start: "2021-09-04 02:00:00", end: "2021-09-05 02:00:00", load: "1/3" } ]
拿到结果后直接传入visjs的时间轴组件渲染即可得到你需要的黑色柱效果。
内容的提问来源于stack exchange,提问作者Elbern
相关产品推荐
相关产品推荐

