如何用Recharts将时间序列数据按15分钟间隔聚合生成连续折线/面积图
实现思路
- 核心逻辑是将时间戳按指定间隔划分到不同的「时间桶」,按桶聚合后计算平均值,天然支持跨多日的聚合需求
- 聚合间隔可自由配置,15分钟、1小时、1天都可通过修改参数实现
- 如果你的业务需求是展示每个时段的平均指标走势,仅按时段求平均值即可满足要求,若有最大值、分位数等统计需求可在此基础上扩展
完整实现代码
首先封装通用时间聚合函数,可自定义聚合间隔、聚合字段:
/** * 按指定时间间隔聚合时间序列数据 * @param {Array} rawData 原始数据数组,每个元素需包含created字段(Date类型或时间戳数字) * @param {Number} intervalMin 聚合间隔,单位为分钟,比如15就是15分钟聚合,60就是1小时聚合 * @param {Array} metrics 要聚合的指标字段名,比如['sentiment', 'magnitude'] * @returns {Array} 聚合后的数据,每个元素包含时间桶起始时间、各指标平均值、数据点数量 */ function aggregateByTimeInterval(rawData, intervalMin, metrics) { const intervalMs = intervalMin * 60 * 1000; const buckets = {}; rawData.forEach(item => { // 计算当前数据所属的时间桶起始时间戳 const timestamp = item.created instanceof Date ? item.created.getTime() : item.created; const bucketKey = Math.floor(timestamp / intervalMs) * intervalMs; // 初始化桶 if (!buckets[bucketKey]) { buckets[bucketKey] = { count: 0 }; metrics.forEach(metric => { buckets[bucketKey][metric] = 0; }); } // 累加指标值和计数 buckets[bucketKey].count += 1; metrics.forEach(metric => { buckets[bucketKey][metric] += item[metric] || 0; }); }); // 转换为数组格式,计算平均值,按时间排序 return Object.keys(buckets).map(key => { const bucket = buckets[key]; const result = { created: new Date(Number(key)), count: bucket.count }; metrics.forEach(metric => { result[`${metric}Avg`] = bucket[metric] / bucket.count; }); return result; }).sort((a, b) => a.created.getTime() - b.created.getTime()); }
和你现有代码结合使用的示例:
export default function generateLineGraphPointsSentiment(sentimentData, intervalMin = 15) { if (!sentimentData) return []; const rawPoints = []; Object.keys(sentimentData).forEach(key => { sentimentData[key].forEach(k => { rawPoints.push({ created: new Date(k.created * 1000), sentiment: k.sentiment, magnitude: k.magnitude, }); }); }); // 按指定间隔聚合,这里聚合sentiment和magnitude两个指标 return aggregateByTimeInterval(rawPoints, intervalMin, ['sentiment', 'magnitude']); }
使用说明
- 调用
generateLineGraphPointsSentiment时传入第二个参数即可调整聚合间隔,比如传60就是按1小时聚合,传1440就是按1天聚合 - 聚合后返回的数据每个元素包含
created(时间桶起始时间)、sentimentAvg(平均情绪值)、magnitudeAvg(平均强度值)、count(该时间段内的数据点数),可直接用于折线图渲染 - 如果需要展示原始时间点的分布,也可以保留count字段做辅助展示
内容的提问来源于stack exchange,提问作者LeCoda
相关产品推荐
相关产品推荐

