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

基于D3.js实现Path按时间戳切换strokeDasharray样式的需求

实现按时间切换路径虚实样式

问题背景

现有一组时序数据,每个数据对象包含时间戳数组、对应数值数组,以及一个分界时间dashtime。需要实现:早于dashtime的路径段用实线(strokeDasharray="0"),等于或晚于的用虚线(strokeDasharray="3")。

原始数据

let data = [{
  id: 1,
  times: [7619846500000, 7619860000000,7619873600000,7619887200000],
  values: [14.725565836745528, 14.725565836745529, 14.72556583674553],
  dashtime:[7619873600000]
},{
    id: 2,
    times: [7619846400000, 7619850000000,7619853600000,7619857200000,7619860800000],
    values: [14.725565836745528, 14.725565836745529, 14.72556583674553,14.72556583674553],
    dashtime:[7619853600000]
  }];

当前代码逻辑

const attributes = data.map((signal, signalIndex) => {
const X = signal?.times;
const Y = signal?.values;
const I = d3.range(X?.length);

const dAttributeGenerator = d3
  .line()
  .x((i) => xScale(X[i]))
  .y((i) => (yAxisCount !== 1 ? yScales[0](Y[i]) : yScales[0](Y[i])));
 
  const d = dAttributeGenerator(I)
  return d})

<Path
  d={d}
  fill={"none"}
  stroke={'blue'}
  strokeDasharray={"3"}
  style={{ transition: hasTransition ? "all 0.7s" : "" }}
/>

解决方案

单条Path无法实现分段样式,需将每个信号的路径拆分为实线段和虚线段两部分分别渲染:

1. 拆分路径数据

遍历信号数据,找到dashtime对应的分割点,生成两段路径的d属性:

const pathSegments = data.map(signal => {
  const { times, values, dashtime } = signal;
  const splitTime = dashtime[0];
  // 找到第一个大于等于分界时间的索引位置
  const splitIndex = times.findIndex(time => time >= splitTime);

  // 生成实线、虚线部分的点索引数组
  const solidIndices = d3.range(splitIndex);
  const dashIndices = d3.range(splitIndex, times.length);

  const lineGenerator = d3.line()
    .x((i) => xScale(times[i]))
    .y((i) => yScales[0](values[i]));

  return {
    // 至少2个点才生成有效路径
    solidD: solidIndices.length > 1 ? lineGenerator(solidIndices) : null,
    dashD: dashIndices.length > 1 ? lineGenerator(dashIndices) : null
  };
});

2. 渲染分段路径

在组件中分别渲染实线和虚线路径:

{pathSegments.map((segments, idx) => (
  <g key={data[idx].id}>
    {/* 实线路径:早于分界时间的部分 */}
    {segments.solidD && (
      <Path
        d={segments.solidD}
        fill="none"
        stroke="blue"
        strokeDasharray="0"
        style={{ transition: hasTransition ? "all 0.7s" : "" }}
      />
    )}
    {/* 虚线路径:等于或晚于分界时间的部分 */}
    {segments.dashD && (
      <Path
        d={segments.dashD}
        fill="none"
        stroke="blue"
        strokeDasharray="3"
        style={{ transition: hasTransition ? "all 0.7s" : "" }}
      />
    )}
  </g>
))}

关键说明

  • 用findIndex定位分界点,确保拆分位置准确
  • 仅当索引数组长度≥2时生成路径,避免无效的单点路径
  • 用<g>标签包裹同信号的两段路径,保证逻辑关联

内容的提问来源于stack exchange,提问作者Алексей Платов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:05:06