做 Web 看盘 / 多图联动时,最常见的体验问题往往不是画线难看,而是:
日线上点某根 K,分钟图跳到的位置总觉得偏了一截。
这篇文章只谈前端与客户端侧的时间对齐,不聊策略,也不荐股。如果你也在 Canvas / WebGL 上做金融图表,希望能直接对照排查。
先冻结三个概念
在改渲染之前,先把名词写死,否则日志对不上:
- 时间桶(bucket) :一根 K 对应的半开或闭区间,例如
[bar_start, bar_end)。 - 闭合器(closer):当前图画「进行中 bar」还是「仅已闭合 bar」。
- 对齐策略(policy) :含左不含右、对齐到 bucket 起始,或对齐到收盘时刻------三种都合理,混用最难查。
我在结果对象里强制带:
ts
type AlignMeta = {
symbol: string
higherInterval: string
lowerInterval: string
dayBar: [number, number] // [start, end) exchange ms
cursorTs: number
policy: 'half_open_left' | 'align_start' | 'align_close'
closer: 'forming' | 'closed_only'
session: string
tz: string
}
没有 policy + closer + session 的联看 bug,三个月后自己也复现不了。
第一步:打印桶边界,而不是猜像素
日线的「一天」从哪个 timestamp 起算?分钟线是否含夜盘?跨境品种有没有夏令时?
固定日志模板:
text
symbol=
higher=1D lower=1m
day_bar=[start, end)
cursor_ts=
minute_bars_in_range=n
policy=half_open_left
closer=closed_only
session=
tz=
很多「偏了一截」在这一步结束:日线用交易所日历日,分钟却按 UTC 切桶;或 A 股午休被当成缺棒省略,导致索引整体漂移。
第二步:闭合器要显式,且两图一致或可解释
分钟图画的是进行中 bar,日线若只显示已收盘,十字线映射会出现系统性偏移:用户点的是「今天这根」,分钟却跳到昨天最后一根已闭合 K。
两种产品策略都合理:
- 严格闭合:高周期未收盘时,低周期映射到上一根已闭合高周期的区间;
- 进行中联动:高周期 forming bar 也参与映射,但 UI 必须标「未收盘」。
坑在于:一边 silently forming、一边 silently closed_only,看起来像随机 bug。
第三步:对齐策略写进缓存键
常见两种:
- 含左不含右
[start, end):cursorTs = end时落到下一根; - 对齐到 bucket 起始 :光标落在区间内任意点,都映射到该桶的
bar_start。
混用会表现为:偶尔对、偶尔错。工程上我把 policy 放进联看缓存键,和 symbol / intervals / adjust / session 同级------换策略等于换缓存,避免旧映射污染新规则。
命中测试同样走数据坐标(时间戳 + 价格),不要用屏幕像素近似去「吸」到最近一根蜡烛;缩放后像素吸附会掩盖桶边界错误。
一个最小复现(发给数据 / 行情同事)
- symbol + 市场后缀
- 高/低周期
- 点击的高周期
bar_start / bar_end - 期望的分钟区间 vs 实际跳转区间
policy/closer/ 时区- 客户端版本
连续三天日志字段一致,再改 UI 动画或「吸附手感」。否则你会在缓动曲线里浪费一周。
小结
- 联看 bug 优先查桶边界与会话,再查渲染;
closer与policy必须显式且可进缓存键;- 十字线映射用 exchange time,不用本地墙钟;
- 复现清单比截图争论更有效。
我是观潮 TideView 开发者(介绍与反馈:GitHub zhihaoli18874/tideview,非完整开源)。
欢迎只挑「夜盘切日」或「午休缺棒」的边界案例拍砖。
站点:guanchaotv.com/?utm_source...
(完)