# v0.11.0-alpha.8

> 相比 v0.11.0-alpha.7 的变更

Source: https://kcq.nebutra.com/zh/docs/changelog/v0-11-0-alpha-8


新功能 [#新功能]

* **第三方渲染层注册（破坏性）**: 新增 Controller 级 Layer 操作（注册、查询、移除、启用开关、请求重绘）与插件渲染能力，注册名开放为第三方字符串，同一 Controller 与插件共用 `ChartRendererAccess`，Scene 成为已挂载 Layer 的释放所有者。
* **价格轴滚轮缩放与光标价格锚点**: 价格轴画布位于绘图区之外，宿主滚轮监听收不到轴上事件；改为 core 按事件目标分流，以 PriceScale 在原生刻度空间补偿中心位移实现锚点缩放，线性、对数、百分比刻度共用同一套锚点规则，`Chart.scalePrice` 新增可选锚点参数。
* **统一可移动的价格轴设置菜单**: 将价格轴控制项收敛为向上展开的菜单，含当前模式勾选与左右侧放置，重置时按可见高低点重算纵向范围并保留所选刻度与范围模式；移除图表设置弹窗中的轴控制项。
* **价格轴悬浮快捷切换刻度**: 鼠标悬停价格轴时在轴按钮上方显示 A/L/% 快捷切换，复用菜单命令，指针移出即隐藏。
* **可选主题预设**: 新增可选主题预设（配色板 + 视觉主题），点击即应用并持久化，图表在弹窗保持打开时重渲染；预设只调整配色，不改其他设置。
* **绘图模板画布浮条**: 在画布浮条直接保存与应用图元样式模板，共用既有的按类型 IndexedDB 模板契约，应用模板只写入共有颜色字段并经 `updateBatch`；单选时才提供保存。
* **图元复制**: 新增画布工具栏按钮与 `drawings_copy` Agent 工具，通过同一 core 入口复制单选或多选图元；副本保留类型、样式、标签与参数，获得全新 ID 并可见未锁定，替换选中以便直接拖动，按时间轴 16px、价格轴 48px 偏移且近边缘翻转，整组记录为一步撤销。
* **图元显隐与批量删除**: 新增图元显隐开关（含 Agent 历史联动）以及批量删除与虚线框选图标的工具栏入口，替换原先的删除入口。
* **连续绘制开关与磁吸工具栏（破坏性）**: 左侧工具栏磁吸旁新增连续绘制开关，完成图元时保留当前工具；磁吸模式三档接入左工具栏，强磁吸改为无条件取最近 OHLC 价格，移除 `MAGNET_RADIUS_STRONG`。
* **K 线收盘倒计时按交易时段推算**: 倒计时改为解析当前品种注册的交易时段，日内周期按交易区间步进并跳过午休、收盘截断最后一根，日线结束于当日收盘；新增 `showLastPriceCountdown` 设置项（默认开启），关闭后不再派生文本并停止秒级刷新。
* **未来区交易日历与时间外推**: 新增 `projectTradingTimestamp` 纯函数按 `MarketSessionConfig.tradingDays` 外推未来时间，未来区时间轴刻度与纵向网格由日历驱动，无日历时以 `T`、`T+1`、`T+2` 相对索引占位，十字线与横竖绘图锚点共用同一外推入口；MT5 会话补注册，跨视图缩放锚点跟随指针槽位。
* **未来区可滚动与十字线外延**: 指针越过最后一根 K 线时十字线按尾部槽位步长吸附未来槽位，滚动上限按未来区屏数放行，缩放后不再被拉回数据右缘。

Bug 修复 [#bug-修复]

* **共享 GPU 后端绘制区域错绑**: `ChartRenderer` 在构建帧时依次调用所有 Pane 的 `beginFrame` 后才 `scene.paint`，共享 GPU 后端绘制时仍绑定最后一个 Pane，导致主图 K 线被画到副图区域；`FramePaint` 改为携带 SurfaceRegion 与后端，由 Scene 在分发每批次图层前绑定区域并传递 clear 标志，Overlay 批次保持 `clear: false`。
* **拖拽图元时跳帧**: 帧去重只比较正式文档，导致拖拽过程被判定为未变化而跳帧，只有抬起后才跳到落点；每个 Pane 增加正式图元画布，正式层按 committed 投影复用几何与像素，会话层消费拖拽覆盖、预览与框选。
* **切换品种后价格轴停在旧区间**: 锁定价格对 K 线比例时切换品种会沿用上一个品种的手动范围快照与纵向变换；现在主品种身份变化时由 kernel 原子提交品种并清空手动范围，新行情首个有效帧据此重算自动范围再继续锁定。
* **主图图例配置失效**: Vue 图例配置调用了已移除的 `updateRendererConfig`，图表挂载即抛 `TypeError` 中断；改为经 `updateOptionsFacade` 写入 chart options，由 `optionsState` 统一持有，两个图例 Layer 每帧读取配置快照。
* **最新价标签未按刻度格式化**: 标签硬编码价格文本，切到百分比刻度后仍显示价格；改为与刻度、十字线价签共用同一显示语义解析器。
* **未归一化品种被判数据源不支持**: `unknown` 的 assetClass（如 GoTDX 恒指 HSI）不在源声明范围内，整源被判不支持，Router 在请求前抛 `SourceRoutingError`；新增唯一判定入口 `isFilterableAssetClass`，registry、router 与 protocol 三处筛选点统一复用。
* **十字线标签对比度不足**: 三处十字线标签使用通用 label token，深色下底色近黑导致标签糊在轴背景；回归专用的 `crosshairLabelBg` / `crosshairLabelText`（对比度 8.79:1），浅色模式不变。
* **MT5 未来区时间外推整体失效**: 内建会话注册表缺少 MT5，品种会话解析抛错使 `futureSession` 恒为 null；补注册 `MT5 -> FOREX_MARKET_SESSION`（24/5 主场景）。
* **水平图元锚点携带 futureOffset**: `completeDrawing` 无差别传 `{ timestamp, futureOffset, price }`，与水平锚 `futureOffset?: never` 的契约冲突；改为水平命令仅传 price，未来区落点可按价格创建水平线。
* **绘图时十字线消失**: 绘图预览先消费指针移动导致十字线被隐藏；改为绘图期间保留悬停更新并以虚线渲染两条标线。
* **默认 K 线提示框空白**: 提示框挂载即渲染，而可见性只在订阅内解析（订阅时不触发）；改为初始隐藏、setup 时求值一次，数据变化时重新求值。
* **Android WebView 不跟随系统主题**: 补充系统主题跟随判定，使 WebView 内嵌场景也能随系统深浅色切换。
* **下拉触发器文字下沿被裁切**: `dropdown__value` 同时使用 `line-height: 1` 与 `overflow: 隐藏`，省略号裁切区截断了字体下沿笔画；改为 `1.4`。
* **领域错误码常量缺失**: SCALE\_/FOOTPRINT\_/AVWAP\_/INDICATOR\_/HEATMAP\_/MTF\_/CHART\_TYPE\_/REPLAY\_/DEPTH\_ 错误码引用了 `errors.ts` 未导出的常量对象，导致 core 无法通过类型检查；补齐常量并统一文件格式。

架构与重构 [#架构与重构]

* **Layer 成为 Scene 唯一绘制契约（破坏性）**: `Layer<TFrame>` / `Scene<TFrame>` 泛型化，`Layer.pane` 用具体 paneId 取代丢弃 id 的 paneRole，`Layer.paint` 直接接收帧上下文；pane 匹配、可见性、role 过滤、z 排序与逐 Layer 异常隔离上移到 `createScene`，`Scene.paint(frame)` 一次画完所有 pane。
* **退役 RendererPlugin（破坏性）**: 删除 `RendererPlugin` / `RendererPluginWithHost`、`RendererPluginManager`、`updateRendererConfig` 与 `createLayerFromPlugin` / `wrapRendererAsLayer`；约 70 个渲染器工厂与指标 scale 统一返回原生 `Layer<RenderContext>`，指标接缝集中到 `indicatorRendererLayer.ts`，状态统一经 `context.indicatorStateReader` 读取。
* **未来区空间由视口派生（破坏性）**: 移除 `futureScreens` 图表选项，改为响应式几何统一派生内容宽度、滚动上限与未来槽位数，并保留末尾两个数据槽位，使平移无法把视口整体移入未来区；默认未来区由 3 屏收窄为 1 屏。
* **图表视图切换集中化（破坏性）**: 周期与对比视图经同一决策解析，使对比命令保留分时模式；重写几何、价格轴与指针编排并移除影子状态，`Chart.applyRenderState` 改接受 `zoomLevel` 或 `kWidth`/`slotWidth`，`Chart.setSymbols` 拒绝多个主品种（对比改用 `setComparisonSpecs`）。
* **命中测试几何归入 foundation/geometry（破坏性）**: 新增业务无关的 `foundation/geometry` 作为 2D 值类型与纯谓词的唯一归属，替换绘图、marker、自定义 marker 形状、K 线/窗格判定与框选各自重写的 point-in-circle、AABB、两点成矩形与线段/矩形求交；`ScreenPoint` 更名为 `Point` 并下沉，`engine/drawing` 不再导出 `ScreenPoint`。
* **绘图模板领域归入 core**: 模板读写（types/impl/codec + IndexedDB store）从 Vue 层的两套并存实现收敛到 core，模板列表按「仓库实例 + 图元类型」共享为唯一状态源，样式与文本位置解析拆为 `resolveTemplateStyle` 与 `resolveTemplateLabel`，菜单行操作抽到 `DrawingTemplateMenu` 供画布浮条与设置弹窗共用。
* **Provider 模块语义分层**: 数据层按 `types.ts + impl/` 布局重组，并将 `packages/core/src/data` 的硬编码字符串替换为具名常量（`AUTO_SOURCE_ID`、`LATEST_TRADING_DATE`、`OLDER_DATA_STATUS.EXHAUSTED`、`V1_ENDPOINTS`、`JSON_HEADERS`、`CN_SESSION_ID`）。
* **内建数据源注册单一真源**: 内建源清单集中到 core（`provider/sources/index.ts`），以 `market-data/sources/` 语义子路径与逐源深导入暴露，取代 `dist` 路径通配导出；web-component 入口改为强引用内建源，避免被 `sideEffects: false` tree-shake 掉，并补静态 capabilities 让无头引导不再死锁。
* **绘图工具与磁吸常量集中化**: 从绘图契约发布 `DrawingTool` 与 `MagnetMode` 表并派生类型，交互层、工具表与 Vue 工具栏的运行时比较点统一消费。
* **倒计时时间并入帧输入**: 倒计时此前在 timer 延迟、帧去重版本键与 paint 内三处各自现取 `Date.now()`；改为在 derive 开始时从可注入 Clock 读一次并随快照下发 `remainingMs` 与 `countdownText`，版本键改用派生文本，timer 由帧事务副作用阶段统一续订。
* **帧内容版本化**: `ChartRenderer` 在帧事务 derive 阶段按值比较（`Object.is`）主层与交互层内容版本，命中即跳过 prepare、清屏与绘制；仅交互层变化时复用缓存几何只重画 overlay，主层像素保留。WebGL 上下文启用 `preserveDrawingBuffer` 保证跳帧期间可见内容持续显示。
* **Vue 组件逻辑抽取**: 将 `KLineChart.vue` 内联的默认提示框逻辑抽为 `useKLineTooltip`、交互订阅抽为 `useInteractionBridge`，并在卸载时取消订阅与断开 ResizeObserver。
* **工具栏按钮共享样式**: 抽出 `control-button.css` 统一品种选择、比较按钮与下拉触发器的尺寸、主题色、悬停、展开态、焦点环与窄屏降级，Dropdown 继续通过 `--dropdown-trigger-*` 支持主题定制，工具栏阴影改由 UI token 派生。
* **BaseTooltip 统一悬浮提示**: 原生 `title` 无法主题化且与 DropMenu 封装行为不一致，价格轴快捷按钮、Agent 头部按钮与 Dropdown 触发器改由 BaseTooltip 渲染，Dropdown 新增 `ariaLabel` prop。

性能 [#性能]

* **图层几何保留与整帧跳过**: 数据与视口不变时仍逐帧重建 K 线/Ichimoku 几何并全量重画；新增 `retainedGeometry`（按 key 保留几何并计数重建）与 `retainedProjection`（合成 dataRevision、展示输入、轴映射与 kLineCenters 判定复用），配合帧内容版本跳过整帧。实测几何准备 P50 由 0.3-6.9ms 降到 0.00ms，geometryBuildCount 600 → 1（18/18 场景），WebGPU ichimoku 10000 由 116.4 升至 185.2/199.7 FPS、jank 由 63.7% 降到 8.0%/0.2%。
* **未来区槽位换算收敛为单一事实来源**: 未来区槽位换算抽为 `futureBarCount` 纯函数，三处调用点共享物理像素量纲实现。

工程 [#工程]

* **设置页横向滚动**: `BaseTabs` 溢出时把滚轮映射到 `scrollLeft` 并在边缘透传给页面，拖拽改在 document 上运行，解决窄窗口下设置弹窗无法滚动。
* **测试夹具与断言收敛**: 抽出 `mountChart` / `makeBars` / `getModeHandlers` / `emitResize`、`scrollContainerStub`、共享 HAND 模式挂载与两级 bar 夹具，并把图例、图表 DPR、价格轴、未来区与磁吸用例改为表驱动或复用共享工厂，移除重复断言与全部 `as unknown as` 强转。
* **拆分过胖的渲染器测试**: 拆分超长渲染器测试文件并共享 Layer store 替身。
* **依赖升级**: 将 `vite` 升级至 8.3.1、`vitest` 升级至 5.0.2。
* **格式化与导入排序**: 应用 Biome 导入排序与格式化，并修正 agent-runtime 的 tsconfig path 映射写法与工具栏阴影硬编码色。

文档 [#文档]

* **设计决策文档新增**: 新增主题预设、资产类别 unknown 过滤、数据层模块布局、绘图复制、绘图会话图层、帧内容版本、帧倒计时时间、未来区默认屏数、未来区两数据槽位、最后价格时段倒计时、未来槽位相对标签、价格轴菜单、价格轴滚轮缩放、退役 RendererPlugin 契约、Scene 窗格区域绑定与图表视图切换等设计决策文档。
* **渲染管线文档补充第三方 Layer 接入**: `docs/rendering/rendering-pipeline.md` 增补第三方 Layer 与指标注册章节，覆盖运行时契约与接入示例。
* **PR 流程要求人工测试**: 将贡献流程中「中间不经过 E2E 测试、视觉回归测试」改为「中间不经过用户手动测试」。
* **数据源与架构文档同步**: 更新架构文档与 BaoStock/MT5 数据源说明以匹配 Provider 语义分层。
