
本文介绍一种基于 map 的高效数据重构方法,用于将原始分散的设备、报告与临床评估数据,按精确起止时间合并为单一记录,并自动生成符合 gantt 图 tooltip 需求的分组文本(如“device: ph, humidity”)。
本文介绍一种基于 map 的高效数据重构方法,用于将原始分散的设备、报告与临床评估数据,按精确起止时间合并为单一记录,并自动生成符合 gantt 图 tooltip 需求的分组文本(如“device: ph, humidity”)。
在构建 D3.js 甘特图时,原始数据常以细粒度事件形式存在——同一时间段内多个传感器读数、报告或临床评估并行发生。但可视化层(尤其是 tooltip 和条形渲染)要求每个时间区间仅对应一条聚合记录,且需清晰区分类型来源(如 device → “Device”,report → “Report”),同时保留各类型下的具体文本项(如 "pH"、"humidity")。直接使用 reduce 或嵌套 filter 易导致性能下降与逻辑混乱;而采用 Map 按时间键(starting_time$ending_time)进行哈希分组,兼具高效性、可读性与插入顺序保真性。
以下为完整实现方案:
function alertBreakdown(arr) {
const groupedData = new Map();
for (const obj of arr) {
// 构建唯一时间键:确保起止时间完全一致才合并
const key = `${obj.starting_time}$${obj.ending_time}`;
let grouped = groupedData.get(key);
if (!grouped) {
// 首次遇到该时间段,初始化分组对象(复用原对象结构)
grouped = { obj, typeTextMap: new Map() };
groupedData.set(key, grouped);
}
// 按 type 归集 text 值(支持同一 type 多个 text,如重复 pH 记录)
const texts = grouped.typeTextMap.get(obj.type) || [];
grouped.typeTextMap.set(obj.type, [...texts, obj.text]);
}
// 将 Map 转为最终数组,生成标准化 text 与 type 字段
return Array.from(groupedData.values(), ({ obj, typeTextMap }) => ({
...obj,
text: Array.from(typeTextMap, ([type, texts]) =>
`${transformTypeName(type)}: ${texts.join(", ")}`
).join(", "),
type: Array.from(typeTextMap.keys()).join(", ")
}));
}
// 类型名格式化:camelCase → Pascal Case(如 clinicianAssessment → Clinician Assessment)
const transformTypeName = type =>
type.replace(/\b\w/g, c => c.toUpperCase())
.replace(/([A-Z])([a-z])/g, (_, p1, p2) => `${p1} ${p2}`);关键设计说明:
- ✅ 精准分组:以 starting_time$ending_time 为复合键,避免仅按日期(如 YYYY-MM-DD)粗粒度聚合导致跨时段误合并;
- ✅ 类型语义保留:transformTypeName 自动将 device → "Device"、clinicianAssessment → "Clinician Assessment",提升 tooltip 可读性;
- ✅ 顺序一致性:Map 的迭代顺序严格遵循首次插入顺序,确保输出数组与原始数据时序逻辑一致;
- ⚠️ 注意事项:若原始数据中存在 type 值拼写不规范(如 "clinicianassessment" 缺少大写),建议预处理统一格式;更健壮的做法是将显示标签(如 { type: "device", label: "Device" })直接内置于源数据,而非依赖运行时转换。
调用示例:
console.log(alertBreakdown(originalArray));
// 输出结果中,相同起止时间的 device 条目将合并为:
// { text: "Device: pH, humidity", starting_time: ..., ending_time: ..., type: "device" }
// 跨类型重叠(如 report + clinicianAssessment 同一时段)则生成:
// { text: "Report: swelling, Clinician Assessment: level of pain", ... }该方案兼顾性能(O(n) 时间复杂度)、可维护性与扩展性,可无缝集成至 D3.js 数据预处理流程,为甘特图交互提供语义清晰、结构统一的数据基础。

















