You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用D3.js将时间线图表转换为积分图表

D3.js 时序数据转积分图表实现方案

时序数据的积分图表通常分为两类:

  1. 累计求和积分:仅对采样点的数值做累加,适合采样间隔均匀的统计类场景
  2. 时间加权积分:对函数f(t)在时间维度做积分,适合需要计算时间维度累计总量的物理、业务统计场景

第一步:数据预处理

首先先对原始数据按时间戳升序排序,再根据需求选择对应积分计算逻辑:

累计求和积分转换代码

// 先按时间戳升序排序,避免原始数据时序乱序
const sortedData = array1.sort((a,b) => a.ts - b.ts)
// 累计求和计算积分值
const cumulativeIntegral = sortedData.reduce((result, current, index) => {
  const prevSum = index === 0 ? 0 : result[index-1].integralValue
  result.push({
    ts: current.ts,
    originalValue: current.value,
    integralValue: prevSum + current.value
  })
  return result
}, [])

时间加权积分转换代码(梯形法计算,结果更平滑准确)

const sortedData = array1.sort((a,b) => a.ts - b.ts)
const timeWeightedIntegral = sortedData.reduce((result, current, index) => {
  if (index === 0) {
    // 第一个采样点初始积分值设为0
    result.push({
      ts: current.ts,
      originalValue: current.value,
      integralValue: 0
    })
    return result
  }
  const prevItem = sortedData[index-1]
  // 计算两个采样点的时间差,单位和ts单位一致,示例中为秒
  const timeDelta = current.ts - prevItem.ts
  // 梯形法计算区间积分:(前值+现值)/2 * 时间差
  const intervalIntegral = (prevItem.value + current.value) / 2 * timeDelta
  result.push({
    ts: current.ts,
    originalValue: current.value,
    integralValue: result[index-1].integralValue + intervalIntegral
  })
  return result
}, [])

第二步:D3.js 渲染积分图表

积分图表的渲染逻辑和普通时序折线图基本一致,仅需要将y轴绑定的数值替换为计算得到的integralValue即可,核心渲染代码示例:

// 定义画布尺寸
const width = 800, height = 400, margin = {top: 20, right: 20, bottom: 30, left: 50}
const svg = d3.select('svg')
  .attr('width', width)
  .attr('height', height)

// 定义x轴时间比例尺
const xScale = d3.scaleTime()
  .domain(d3.extent(cumulativeIntegral, d => new Date(d.ts * 1000))) // 秒级时间戳转Date对象
  .range([margin.left, width - margin.right])

// 定义y轴积分值比例尺
const yScale = d3.scaleLinear()
  .domain(d3.extent(cumulativeIntegral, d => d.integralValue))
  .range([height - margin.bottom, margin.top])

// 生成折线路径
const linePath = d3.line()
  .x(d => xScale(new Date(d.ts * 1000)))
  .y(d => yScale(d.integralValue))
  .curve(d3.curveLinear) // 可替换为d3.curveMonotoneX实现平滑曲线效果

// 渲染折线
svg.append('path')
  .datum(cumulativeIntegral)
  .attr('fill', 'none')
  .attr('stroke', 'steelblue')
  .attr('stroke-width', 2)
  .attr('d', linePath)

// 渲染x、y轴和网格线等其余元素逻辑和普通时序图完全一致

注意事项

  • 若原始数据采样间隔不均匀,优先使用时间加权积分,结果更符合积分的数学定义
  • 累计求和积分仅适用采样间隔完全相等的场景,否则会出现统计偏差
  • 可根据业务需求调整积分初始值,仅需要修改reduce方法中第一个点的初始积分值即可

内容的提问来源于stack exchange,提问作者Dev M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 15:36:03