基于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,提问作者Алексей Платов
相关产品推荐
相关产品推荐

