gis-view-webgl2 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +0 -24
  2. package/dist/gis-view.css +1 -1
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.d.ts +524 -33
  5. package/dist/index.js +1 -1
  6. package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +156 -8
  7. package/docs/GisView.md +6 -6
  8. package/docs/ai/06-/344/274/232/350/257/235/347/264/242/345/274/225/344/270/216/345/244/215/346/237/245/346/226/271/346/263/225.md +157 -7
  9. package/docs/demos/BackgroundDemo.vue +600 -0
  10. package/docs/demos/ChannelDemo.vue +145 -3
  11. package/docs/demos/StyleDemo.vue +280 -69
  12. package/docs/demos/api-index.js +35 -19
  13. package/docs/demos/demos.js +26 -18
  14. package/docs/demos/gis-view-demo/demo.css +76 -0
  15. package/docs/demos/gis-view-demo/panels/StylePanels.vue +24 -8
  16. package/docs/demos/gis-view-demo/panels/ViewPanels.vue +33 -3
  17. package/docs/demos/gis-view-demo/useGisViewDemo.js +236 -22
  18. package/docs/format/02-/350/212/202/347/202/271/344/270/216/347/272/277/350/267/257.md +1 -1
  19. package/docs/format/03-/346/213/220/347/202/271/350/243/205/351/245/260/344/270/216/346/240/267/345/274/217.md +3 -3
  20. package/docs/from0/06-/344/273/216/346/225/260/346/215/256/345/210/260/345/256/236/344/276/213-/350/247/243/346/236/220/345/261/202.md +13 -11
  21. package/docs/from0/15-/351/231/204/345/275/225-/345/270/270/351/207/217/351/200/237/346/237/245/344/270/216/350/270/251/345/235/221/346/270/205/345/215/225.md +1 -1
  22. package/docs/index.html +2 -2
  23. package/docs/internals/10-/350/247/204/345/210/231/346/235/241/344/273/266/344/270/216/347/212/266/346/200/201/346/240/267/345/274/217.md +3 -3
  24. package/docs/internals/13-/351/271/260/347/234/274/345/233/276.md +1 -1
  25. package/docs/internals/14-/350/203/214/346/231/257/345/261/202.md +1 -0
  26. package/docs/internals/15-03-/351/200/220/350/275/256/350/256/260/345/275/225-/346/200/247/350/203/275/344/270/216/344/277/256/345/244/215-/344/270/213.md +199 -0
  27. package/docs/internals/17-/350/260/203/350/257/225/344/270/216/346/211/251/345/261/225/345/273/272/350/256/256.md +1 -1
  28. package/docs/internals/18-/346/200/247/350/203/275/345/256/236/346/265/213/344/270/216WebGPU/350/257/204/344/274/260.md +32 -0
  29. package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +1 -1
  30. package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +217 -26
  31. package/docs/manual/07-/346/214/207/351/222/210/344/270/216/350/246/201/347/264/240/347/274/226/350/276/221.md +2 -2
  32. package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +37 -4
  33. package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +58 -1
  34. package/docs/manual/11-/346/240/267/345/274/217/344/270/216/350/247/204/345/210/231.md +59 -8
  35. package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +1 -1
  36. package/docs/manual/13-/345/212/250/346/225/210/344/270/216/345/233/276/345/205/203.md +220 -2
  37. package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +77 -16
  38. package/docs/manual/15-/345/257/274/345/207/272/344/270/216/351/233/206/346/210/220.md +30 -17
  39. package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +11 -4
  40. package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +17 -8
  41. package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +128 -4
  42. package/docs/manual/19-/350/257/273/346/225/260/344/270/216/346/213/226/346/213/275/351/242/204/350/247/210.md +2 -2
  43. package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +13 -1
  44. package/docs/manual/21-/350/257/264/346/230/216/344/270/216/345/270/270/350/247/201/351/227/256/351/242/230.md +4 -1
  45. package/docs/steps/index.html +1 -1
  46. package/docs/steps/selftest-demo.html +2 -2
  47. package/docs/steps/selftest-demos.html +626 -11
  48. package/docs/steps/selftest-docs.html +8 -4
  49. package/docs/steps/selftest-features.html +1428 -2
  50. package/docs/steps/selftest-perf.html +296 -25
  51. package/docs/steps/selftest-scale.html +61 -3
  52. package/docs/steps/selftest-select.html +303 -1
  53. package/docs/steps/step-06-style.js +3 -2
  54. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  # AI 对话汇总
2
2
 
3
- > 一页读完 gis-view 的 AI 协作史:39 个会话、197 轮需求,按「关键决策 → 演进主线 → 精选问答」整理。
3
+ > 一页读完 gis-view 的 AI 协作史:39 个会话、211 轮需求,按「关键决策 → 演进主线 → 精选问答」整理。
4
4
  > 原先拆开的 01 ~ 05 已合并到这里;逐会话文件、历史增量索引与复查命令统一放在 [维护索引](ai/06-会话索引与复查方法.md)。
5
5
 
6
6
  这份汇总不是使用手册。组件行为以 [GisView 手册](GisView.md) 和 [数据格式](数据格式.md) 为准,实现细节与逐轮证据在 [GisView 实现原理](GisView实现原理.md) 的 `internals/15-*`、`16-*`。这里只回答三件事:当时为什么这么定、后来怎么演进、现在该从哪里继续查。
@@ -20,11 +20,11 @@
20
20
 
21
21
  | 项目 | 结论 |
22
22
  | --- | --- |
23
- | 对话范围 | 2026-09-15 ~ 2026-10-29,39 个会话、197 轮;10-14 之后主要为现有会话的增量轮次 |
24
- | 产品形态 | 一个无内置界面的 `createGisView(dom, options)` WebGL2 矢量视图,交互与视觉效果通过配置、事件和实例方法组合 |
23
+ | 对话范围 | 2026-09-15 ~ 2026-11-02,39 个会话、211 轮;10-14 之后主要为现有会话的增量轮次 |
24
+ | 产品形态 | 一个默认无控制面板的 `createGisView(dom, options)` WebGL2 矢量视图;鹰眼图、图例与背景编辑器按需开启,交互与视觉效果通过配置、事件和实例方法组合 |
25
25
  | 核心对象 | 节点、线路、通道(多回线 / 分组)、拐点、装饰、标签、覆盖层、鹰眼图、扩展图形 |
26
26
  | 技术路线 | WebGL2 批量渲染 + HTML / Canvas 覆盖层 + 网格索引 + 增量更新 + Worker 筛选与搜索 |
27
- | 当前公开面 | 274 个实例成员、100 个 options、266 个数据字段、44 个事件、17 个功能开关、16 个分组 |
27
+ | 当前公开面 | 283 个实例成员、107 个 options、275 个数据字段、44 个事件、17 个功能开关、16 个分组 |
28
28
  | 维护方式 | 文档双向对账、API 索引生成、14 个自测页与无头浏览器回归;每轮记录同步到本页与维护索引 |
29
29
 
30
30
  ## 关键技术决策
@@ -84,7 +84,155 @@
84
84
 
85
85
  先分清组件与宿主:本组件只负责接收已经整理好的点线数据,`initData` 只应在挂载时调用一次;若宿主定时重建数据,先查宿主路由、监听与 `gisTools.js` / `buildNewData`。SVG 被画成圆通常是宿主传入了错误的 `symbol` 或 `pointRules`,直流标记则要确认装饰类型与数据映射。历史排查见维护索引的 10-12 旁支记录。
86
86
 
87
- ## 当前轮次:README 精简与维护规则(2026-10-29)
87
+ ## 当前轮次:toggleSelect 节点 / 线路 / 通道 / 分组核验与 visualMap 多目标门控(2026-11-02)
88
+
89
+ - **需求来源**:根目录 `修改.txt` —— ① 检查 `toggleSelect` 是否真的生效;② 续查对线路、通道和通道分组的取消是否生效;③ 反馈再次点击通道 / 线路 / 分组不会取消、只有节点能取消;④ 前一轮的 `visualMap` 交互没有效果、不会隐藏网架。
90
+ - **toggleSelect 根因与修复**:入口原先只看命中的那一条线路 `result.selected`。通道分组 / 整条通道只选中一部分,或点到组内、通道内的另一条回线时,这个值可能为 false,点击于是落到普通单选并重新选上,看起来只有节点能取消。现在 `engine.js` 抽出 `selectionScopeKeysOf()` 按 `channelSelectMode` 取得完整范围,`toggleSelect` 用范围 `anySelected` 判断,并以 `removeOnly` 整批取消;Ctrl / 多选仍保持原来的“整批取反 / 补缺”语义。独立线路、通道单条、完整分组、部分分组、完整通道、部分通道都有真实指针回归;`onClick` / `onSelectChange` 的动作名都是 `toggleSelect`。`selftest-select` 新增 6 条,107 → **113/0**。
91
+ - **toggleSelect 跨模式补充**:继续在真实 `?demo=full` 中复核发现默认 `channelSelectMode: 'line'` 下,先用 `selectFeatures` / 右键菜单完整选中一条通道或分组,再点回线只删除命中那一条,剩余成员仍在选中,视觉上仍像“通道 / 分组没有取消”。`engine.js` 新增 `selectionToggleScopeKeysOf()`:`line` 模式下若命中回线所属通道已完整选中,优先整条移除;否则若所属分组已完整选中,整组移除;部分选中仍按当前 `channelSelectMode` 摊开。真实指针复核:3 回线通道完整选中后点击其中一条,选中集由 3 条变为空。`selftest-select` 再增 2 条跨模式回归,113 → **115/0**;手册 03 / 08、`types.d.ts`、组件 README 同步。
92
+ - **GisEdit 配置链路复核与取消级联**:`D:\work\gis-view\src\components\GIS\GisEdit.vue` 实际配置为 `selectionKinds: ['point', 'lines']`、`channelSelectMode: 'channel'`。归一化后不含 `channel`,而 `toggleSelect` 取消分支仍检查了 `selectionKinds`,通道回线(分组回线也按 `channel` 归类)因此进不了取消路径;线路大多挂在通道下,用户看到的就是通道 / 线路 / 分组都不会取消。`engine.js` 移除该门控,保留开关、选中范围与双击判定;`selectionKinds` 继续只约束框选与 Ctrl / 多选。级联高亮改为在点击分流前判断这一下是否会取消:取消时直接清旧状态,避免同一击先发非空再发 `null`;接口 `deselect` / `selectFeatures` 的 remove / 清空经 `setSelection` 真正移除选中项时,也同步收掉级联并只补一条 `onCascadeHighlight(null)`。`selftest-select` 用真实 GisEdit 配置新增通道 / 分组回归,115 → **117/0**;`selftest-features` 新增 toggleSelect / deselect / remove 三条级联取消回归,839 → **842/0**。
93
+ - **visualMap 根因**:内部状态此前只保存单个 `target`,不写 `target` 时门控只落到 `heatmap.target` 的第一项 `point`;`new.json` 节点又没有 `max_loading_rate`,图例首项值域退化成空;Demo 构建通道时也没补这一列,`channel` 目标无值可判。三者叠加后,用户看到的图例既没有可用的值域,也不会隐藏线路 / 通道。
94
+ - **修复口径**:`visual-map.js` 内部快照与签名改带 `targets`,未显式写 `target` 时展示值域按 `point → line → channel` 选第一个真正有数值的目标,门控仍覆盖全部启用目标;`heatmap.js` 按目标组判断是否允许上色;`engine.js` 同时计算落选节点、独立线路与整条落选通道的成员回线,不再在第一个 `target` 处提前返回;`setVisualMapState()` 的影响面也按目标组判断。公开 API 不新增 `targets` 字段,计数保持 283 个实例成员 / 107 options / 275 数据字段。
95
+ - **Demo**:`buildNewData` 与 `buildSampleData` 的通道补成员最大 `max_loading_rate`;Demo 默认落选策略改为 `network`,面板提示明确不写 `target` 时三类一起门控。真实 `?demo=full` 复核:new.json 7368 节点 / 12811 线路 / 9230 通道,重新随机后图例自动切到 `point`(0.401 ~ 1.5),取消首段后可见节点 / 线路由 2123 / 4058 降到 0 / 0。
96
+ - **核心文件**:`src/gis-view/visual-map.js`、`heatmap.js`、`engine.js`、`create.js`、`types.d.ts`、`src/gis-view/README.md`;`docs/manual/03` / `07` / `08` / `11` / `13`、`docs/GisView.md`、Demo 组合式函数与样式面板、`selftest-features.html`、`selftest-select.html`、本页与维护索引。
97
+ - **验证**:`node --check src/gis-view/engine.js`、`npx tsc --noEmit`、API 索引、`npm run check:docs`、`npm run build`、`git diff --check` 通过;`selftest-select` **117/0**、`selftest-features` **842/0**、`selftest-actions` **96/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-perf` **197/0**。真实 `?demo=full` 用 3 回线通道和实际指针事件复核:完整通道选中后点击一条,选中集由 3 条变为空。性能页首次组合运行出现 192/5,失败项均为既有「线路标签候选复用」的排版时序,单独复跑全绿。
98
+
99
+ ## 上一轮次:再次选中取消、visualMap 落选门控与交互快路径(2026-11-01)
100
+
101
+ - **需求来源**:根目录 `修改.txt` 三条 —— ① 新增取消选中开关,默认关闭,单击、双击、Ctrl 先选中的路径都能再次操作取消;② 继续优化交互性能;③ `visualMap` 落选后应与热力图 / 网架联动,可选择消失对应网架或对应热力。按用户补充「不考虑分组详情」,本轮不扩展分组详情查询。
102
+ - **toggleSelect**:顶层 `options.toggleSelect` 缺省 `false`,由 `create.js` 透传引擎并支持 `updateOptions`。单击模式下第二次普通单击已选要素取反;`selectTrigger: 'dblClick'` 下由第二下取反、再次双击取消;Ctrl / ⌘ 先选中后再普通单击也取消。双击每轮只取反一次,不影响普通 `onClick` / `onDblClick` 的派发顺序;取反时 `onClick.action.type` 与 `onSelectChange.action.type` 都是 `toggleSelect`。
103
+ - **outOfRange**:`visualMap.outOfRange` 缺省 `'heatmap'`,只退出同一 `target` / `field` 的热力并恢复普通样式;`'network'` 额外隐藏落选节点、独立线路或整条通道成员,并从拾取与包围盒消失;`'none'` 不参与内置门控,只保留 `onChange`。`network` 的 `channel` 按声明收集全部成员回线,`line` 不误伤通道回线;数据、筛选、选中集与分组声明不变。图例状态、读数与 `onChange` 载荷都带 `outOfRange`。
104
+ - **交互性能**:引擎把筛选基线隐藏与 visualMap 视觉隐藏分成两套集合,解析时取并集;`network` 隐藏集合不变时 `setVisualMapState()` 返回 `hiddenChanged: false`,不重建场景。点 / 线热力样式缓存键分开,图例只影响节点时不再重算线路那一半;通道成员收集按通道声明一次完成。鹰眼图在 `network` 下同步隐藏,即使显式配置 `minimap.heatmap` 也不遮挡该语义。
105
+ - **Demo 与文档**:Demo 增加 `toggleSelect` 开关与落选值下拉;手册 03 / 08 / 13 / 14、`docs/GisView.md`、组件 README、API 索引同步。`selftest-select` 新增 5 条覆盖普通、双击、Ctrl、事件动作与关闭态;`selftest-features` 新增 8 条覆盖三种 `outOfRange`、节点 / 独立线路 / 通道、数据与筛选不变、隐藏集合快路径与鹰眼图同步。性能页的标签稳态用例改用 `progressiveInit: false` + `labelOptimize: true` 并显式等待 `isLayoutReady()`,避免锚点视图因发散渲染未完成而把第七轮首次真实排版误记成整屏重量。
106
+ - **核心文件**:`src/gis-view/engine.js`、`create.js`、`heatmap.js`、`visual-map.js`、`update-policy.js`、`types.d.ts`;`docs/manual/03` / `08` / `13` / `14`、`docs/GisView.md`、`src/gis-view/README.md`、Demo 组合式函数与面板、`selftest-select.html` / `selftest-features.html` / `selftest-perf.html`、本页、维护索引与 15.111。
107
+ - **验证**:`npx tsc --noEmit`、`npm run check:docs`、`npm run build`、`git diff --check` 通过;API 索引为 283 个实例成员(278 方法 + 5 属性)/ 107 options / 275 数据字段;串行自测 `selftest-select` **107/0**、`selftest-features` **836/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-perf` **197/0**。
108
+
109
+ ## 2026-11-01 更早轮次:热力密度几何隔离、线路热力连续与 visualMap 运行时门控(2026-11-01)
110
+
111
+ - **需求来源**:根目录 `修改.txt` 三条 —— ① 开启热力图后平移 / 缩放时仍有部分线路热力先消失再出现;② 开启热力图后背景也跟着异常放大缩小;③ `visualMap` 交互没有实际效果,应与 ECharts 一样影响热力表现。
112
+ - **背景缩放根因**:密度场虽然有自己的 `heatDensityBuffer`,绘制时却仍沿用背景图片的 `imageVao`;背景图片四边形一变,密度层就跟着缩放。现在新增独立 `heatDensityVao`,`drawImageQuad()` 可按层绑定几何,背景与密度场各用自己的 VAO,销毁时一并释放。
113
+ - **线路热力连续**:线路热力不再按 `interacting || cameraMoving` 在合并管线、细线快路径和两遍光晕之间切换。普通 / 自动浅底配置始终走 `drawHeatLineBatch()`;加法混合或驱动属性槽位不匹配时始终走两遍 `drawLineHeatGlow()`。自动画质降档也不再关闭线路热力;节点光晕仍可在交互期让路。
114
+ - **visualMap 实际门控**:`visual-map.js` 把当前分段 / 区间发成内部纯数据状态,`create.js` 在首帧及后续选择变化时交给引擎内部的 `setVisualMapState()`;`heatmap.js` 在选区外返回不参与热力。只门控与图例同 `target`、同 `field` 的要素,落选值回普通样式,不删除数据、不改筛选;分段空选择关闭对应热力,连续尺按闭区间判断。默认继承主图热力的鹰眼图也使用同一份状态,显式 `minimap.heatmap` 仍独立;没有新增公开实例成员 / options / 数据字段。
115
+ - **回归与文档**:`selftest-features` 增加分段勾选 / 取消、连续尺区间门控、密度权重、继承鹰眼图同选区与显式 `minimap.heatmap` 独立断言;`selftest-perf` 增加“图片背景不影响密度场几何”和逐条线路在运动 / 停稳帧的采样,两个用例都走真正的最终 PASS / FAIL。手册 03 / 11 / 13 / 14 / 15、`docs/GisView.md`、类型注释、组件 README 与 Demo 提示同步改成“内置门控 + onChange 额外联动”。
116
+ - **核心文件**:`src/gis-view/engine.js`、`heatmap.js`、`visual-map.js`、`create.js`、`types.d.ts`、`src/gis-view/README.md`;`docs/manual/03` / `11` / `13` / `15`、`docs/GisView.md`、`docs/demos/gis-view-demo/useGisViewDemo.js`、`panels/StylePanels.vue`、`docs/steps/selftest-features.html` / `selftest-perf.html`、本页、维护索引与 15.110。
117
+ - **验证**:`node --check`、`npx tsc --noEmit`、`npm run check:docs`、`npm run build`、`git diff --check` 通过;串行自测 `selftest-features` **828/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-perf` **197/0**。性能页此前一次完整运行曾出现既有的“改一条可见标签之后的定向重排不读布局”读数断言失败(1313 次),最终复跑未再出现,与本轮热力改动无调用关系。
118
+
119
+ ## 2026-10-31 轮次:线路热力交互连续显示与 visualMap 自定义交互
120
+
121
+ - **需求来源**:根目录 `修改.txt` 三条 —— ① 开启热力图后平移 / 缩放时线路热力先消失再出现;② 继续优化热力图交互性能;③ 图例支持完全自定义与交互,参考 ECharts `visualMap`。
122
+ - **热力连续性**:`buildLineInstances()` 重铺线路实例时补 `heat: line.heat ?? 0`,修复相机移动后热力值归零;`LINE_VERTEX_SHADER` 改为把带符号的 `a_corner.y` 传到片元、再取 `abs(v_edge)`,修复插值后恒为 1 导致光晕衰减失效。交互 / 相机运动帧新增 `HEAT_LINE_FRAGMENT_SHADER` 与 `heatLineProgram`,一笔同时画本色核与光晕,预乘普通混合避免重叠线推白;停稳后的两遍仍按 `glow.blend`。
123
+ - **性能收口**:密度场四边形改用静态 `heatDensityBuffer`,交互 / 相机运动期跳过重烤、停稳补烤;节点光晕在交互期让路,线路热力经合并管线保持连续可见,减少圆面片和额外线绘制。
124
+ - **visualMap 交互**:`interactive` / `selectedMode` / `selected` / `range` / `calculable` 落地;分段支持点击与 Enter / Space 单选 / 多选,连续尺支持区间遮罩、双滑块、拖动单端 / 整体和方向键 / Shift / Alt / PageUp / PageDown / Home / End。`onChange` 一帧合并,载荷带 `source` / `reason` / `originalEvent` / `rangeRatios` 等;受控 `updateOptions({ visualMap })` 不回声。
125
+ - **完全自定义**:`render(context)` 可返回 DOM / DocumentFragment / HTML 字符串或直接写 `context.body`,上下文提供 `setSelection` / `setRange` / `clearSelection` / `emitChange`,可选择继续使用内置交互。`getVisualMap()` 同步返回交互状态、选择、区间与比例。
126
+ - **Demo 与文档**:热力面板增加图例交互 / 完全自定义开关和 `onChange` 读数;手册 03 / 11 / 13 / 15 / 16 / 17 / 18、`docs/GisView.md`、组件 README 与自测页同步。公开面保持 283 个实例成员(278 方法 + 5 属性)/ 106 options / 274 数据字段。
127
+ - **核心文件与验证**:核心为 `src/gis-view/shaders.js`、`engine.js`、`heatmap.js`、`visual-map.js`、`create.js`、`types.d.ts`、`gis-view.css`、Demo 与手册。`node --check`、`npx tsc --noEmit`、API 索引 / `npm run check:docs`、`npm run build`、`git diff --check` 通过;串行自测 `selftest-features` **823/0**、`selftest-perf` **195/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**。
128
+
129
+ ## 同日上一轮:visualMap 图例与图例专用快路径(2026-10-31)
130
+
131
+ - **需求来源**:根目录 `修改.txt` 两条 —— ① 参考 ECharts `visualMap`,增加类似图例,并结合 ruler 样式;② 继续优化组件性能。
132
+ - **图例能力**:新增 `visualMap` option 与 `src/gis-view/visual-map.js`。`ruler` / `continuous` 画连续渐变尺与刻度,`piecewise` 画分段色块;支持 ECharts 风格 `pieces`(`gte` / `gt` / `lte` / `lt` / `min` / `max`)、显式 `domain` / `min` / `max`、`colors` / `stops` / `opacity`、标题与单位、格式化、方向 / 定位 / 尺寸、外部容器与自定义样式。不写字段 / 值域 / 色带时继承 `heatmap`;没有热力图也能按 `field` 独立扫值域。
133
+ - **边界与接入**:不配 / `null` / `enabled: false` 时不挂载节点;`getVisualMapElement()` 给根节点,`getVisualMap()` 给类型、目标、字段、值域、颜色、刻度 / 分段读数。默认 `pointer-events: none`,交互式区间图例由使用方在这层 DOM 上扩展。
134
+ - **性能快路径**:图例与画布共用 `createHeatmapRamp()` 的色带插值;更新走 rAF 合帧与渲染签名缓存,同一签名零 DOM 写入。数据变化只记脏并在下一帧按需重扫,图例侧自动值域在本次配置生命周期内复用自身解析缓存;显式 `domain`、以及两端都写死的 `min` / `max` 都跳过扫描。`updateOptions({ visualMap })` 绕过引擎场景、鹰眼图与标签层重排,连续滑块只保留每帧一次重画。
135
+ - **Demo 与文档**:热力图面板增加「显示图例」与「连续尺 / 分段」控件,默认跟随当前热力图。手册 03 / 11 / 13 / 15 / 16 / 17 / 18、组件 README、文档中心与四个自测页同步;实例成员 281 → **283**(方法 276 → **278**,属性仍 5),options 105 → **106**,数据字段 273 → **274**,分组仍 16。
136
+ - **核心文件**:`src/gis-view/visual-map.js`、`heatmap.js`、`create.js`、`gis-view.css`、`types.d.ts`、`src/gis-view/README.md`;手册 03 / 11 / 13 / 15 / 16 / 17 / 18、`docs/index.html`、Demo 样式面板与组合式函数、`docs/steps/selftest-features.html` / `selftest-perf.html` / `selftest-demos.html` / `selftest-docs.html`、API 索引、本页、维护索引与 15.108。
137
+ - **验证**:`npx tsc --noEmit`、`node --check`(图例 / 热力图 / 组件入口 / Demo)、`node docs/steps/gen-api-index.mjs`、`gen-api-index.mjs --check`、`npm run check:docs`(283 个实例成员 / 278 个方法 / 5 个属性 / 106 个 options / 274 个数据字段)、`npm run build`、`git diff --check` 通过;浏览器自测 `selftest-features` **808/0**、`selftest-perf` **190/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-demo` **133/0**。
138
+
139
+ ## 上两轮:fitSpacing.minDistance 精确落位与指定节点组间距(2026-10-30)
140
+
141
+ - **需求来源**:根目录 `修改.txt` 三条 —— ① `minDistance` 一旦设置就必须按该屏幕距离显示,不能因为初始值或“贴边”限制只能变大;② 新增方法,传一组节点返回整组的 `minDistance` / `maxDistance`;③ 文档说明两者如何按坐标与放大比例计算。
142
+ - **精确屏距根因**:`fitSpacingAdjustment()` 原来用 `Math.max(普通适应比例, minDistance / 最近世界距离)`,并再用 `maxZoom` 截断;因此目标比例比当前小时完全不生效。现在 `minDistance` 分支直接令 `target = minDistance / nearestWorldDistance`,放大 / 缩小都覆盖普通适应,`maxZoom` 仅兼容保留,最终只受 `minScale` / `maxScale` 夹取;相机中心仍沿用普通包围盒中心。
143
+ - **指定节点组读数**:新增 `getPointsSpacing(refs)`,支持单个或数组的 id / 下标 / `{ id }` / `{ index }`,复用 `resolveCopySources()` 去重并按数据顺序定位;以这组节点的世界坐标调用 `measurePointSpacing()`,再把距离乘当前 `camera.scale`,返回与 `getPointSpacing()` 同形的 `count` / `minDistance` / `maxDistance` / `nearest` / `farthest`。它只统计显式节点,筛选 / 隐藏不影响;`getPointSpacing()` 仍只读当前可见节点。
144
+ - **公式文档**:手册 03 / 14 / 16 / 17 / 18 写明 `d_world = sqrt((x2-x1)² + (y2-y1)²)`、`d_screen = d_world * camera.scale`;`minDistance` 的目标比例是 `minDistance / d_world_nearest`,`maxDistance` 是 `min(普通适应比例, maxDistance / d_world_farthest)`。最近距离只取不同坐标节点的最小正距离,最远距离走凸包直径。
145
+ - **Demo 与公开面**:样式面板移除已失效的「最大放大」输入,`maxZoom` 从类型注释标为兼容字段;实例成员 280 → **281**(方法 275 → **276**),options 仍 105、数据字段仍 273、分组仍 16。
146
+ - **核心文件**:`src/gis-view/engine.js`、`create.js`、`types.d.ts`、`src/gis-view/README.md`;`docs/manual/03` / `14` / `16` / `17` / `18`、`docs/demos/gis-view-demo/useGisViewDemo.js`、`panels/StylePanels.vue`、`docs/steps/selftest-scale.html`、`selftest-docs.html`、`selftest-demos.html`、`docs/demos/api-index.js`、本页、维护索引与 15.107。
147
+ - **验证**:`npx tsc --noEmit`、`node docs/steps/gen-api-index.mjs`、`npm run check:docs`(281 个实例成员 / 276 个方法 / 105 个 options / 273 个数据字段)、`npm run build`(仅既有大 chunk 提示)、`git diff --check` 通过;浏览器串行自测 `selftest-features` **794/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-demo` **133/0**;`selftest-scale` **126 通过 / 2 失败**,5 条新增断言全过,2 条仍是既有筛选回调时序(`onFilter 0 条`)。
148
+
149
+ ## 上三轮:背景文字同帧刷新与 fitSpacing.minDistance 上限修复(2026-10-30)
150
+
151
+ - **需求来源**:根目录 `问题.txt` 两条 —— ① 拖动 GeoJSON 背景时仍有晃动,文字尤其明显;② `fitSpacing.minDistance` 有时怎么调都不生效,而 `maxDistance` 正常,怀疑内部还有强制限制。
152
+ - **背景文字根因**:内置背景编辑器每帧先更新 WebGL 背景与编辑框,但区域文字由 `setBackgroundLabels()` 排进下一帧 rAF;底图已经移动、文字还停在上一位置,合成后就是拖影 / 晃动。
153
+ - **同帧刷新**:`overlay.refreshBackgroundLabels()` 改为立即按当前相机重投影,并取消已经排队但尚未执行的那一帧;内置编辑器的 `applyBackground()` 在 `updateBackground()` + `refresh({ reflow: false })` 之后同步调用它,底图、编辑框与区域文字在同一任务内提交,不再互相错一帧。
154
+ - **minDistance 根因**:距离公式本身没有额外限制,真正截住比例的是缺省 `maxScale: 20000`。经纬度、小数坐标等小量纲数据的最近世界距离可能只有 `0.00536`,`20000 × 0.00536 ≈ 107.2px`,所以 `minDistance` 调到 200 / 1000 / 5000 都停在同一屏距。
155
+ - **缺省上限**:`engine.js` 新增 `DEFAULT_MAX_SCALE = 1000000000`,未显式配置时用它;使用方显式写的 `maxScale` 仍然优先,并继续作为 `fitSpacing` 的最后一道夹取。手册补上「固定屏距时先看 `maxScale` / `maxZoom`,用 `getPointSpacing()` 核对」的排查口径。
156
+ - **回归覆盖**:`selftest-features` 用标准 `FeatureCollection` 确保区域名确实生成文字,并断言 `updateBackgroundEdit({ center })` 返回时文字 transform 已经变化;`selftest-scale` 增加最近世界距离 `0.01`、目标 `minDistance: 1000` 的小量纲用例,断言比例超过旧上限且实际屏距≈1000px;Demo 面板缺省值同步。
157
+ - **核心文件**:`src/gis-view/engine.js`、`overlay.js`、`create.js`、`types.d.ts`、`README.md`;`docs/manual/03` / `14`、`docs/from0/15`、`docs/demos/api-index.js`、`docs/demos/gis-view-demo/useGisViewDemo.js`、`docs/steps/selftest-features.html`、`selftest-scale.html`、`selftest-demo.html`、本页、维护索引与 15.106。
158
+ - **验证**:`npx tsc --noEmit` 0 错;`node docs/steps/gen-api-index.mjs` 更新 280 个实例成员的索引;`npm run check:docs` 全绿(280 个实例成员 / 105 个 options / 273 个数据字段);`npm run build` 通过;`git diff --check` 通过。浏览器串行自测:`selftest-features` **794/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-demo` **133/0**;`selftest-scale` **121 通过 / 2 失败**,新增的小量纲断言通过,两条失败仍是既有筛选回调时序(`onFilter 0 条`)。
159
+
160
+ ## 上四轮:内置背景编辑器与旋转按钮命中修复(2026-10-30)
161
+
162
+ - **需求来源**:根目录 `修改.txt` 两条 —— ① 旋转按钮始终不旋转;② 把整块背景编辑模式做成内置模块,通过方法开启和配置,不再由 Demo 纯手写。
163
+ - **旋转按钮修复**:旧 Demo 的 `.bg-edit-layer` 整体是 `pointer-events: none`,缩放手柄与轮廓单独恢复 `auto`,但旋转按钮漏了同一个设置,因此按钮可见却收不到指针。内置编辑器为旋转按钮显式恢复 `pointer-events: auto`;`selftest-demos` 改用 `document.elementFromPoint()` 验证按钮真实可命中,再拖动旋转,避免只对按钮直接派发合成事件而漏掉命中问题。
164
+ - **内置编辑器**:新增 `background-editor.js`,由 `create.js` 懒初始化并公开 `beginBackgroundEdit(options)` / `updateBackgroundEdit(patch)` / `endBackgroundEdit()` / `getBackgroundEdit()`。编辑器支持移动、锁比例四角等比缩放、解锁八向缩放、可选第九个旋转点、Shift 15° 吸附、`fitView`、编辑框颜色 / 填充 / 线宽 / 虚线 / 手柄尺寸与形状,以及 `onChange` / `onEnd` 读数。
165
+ - **写回与生命周期**:图片写回 `background.image.corners`,GeoJSON 写回 `geoJsonStyle.bounds + rotation`,底色、透明度、阴影与其它 GeoJSON 样式原样保留。进入自动打开 `backgroundEditing`,退出恢复进入前的值;没有图片 / GeoJSON 时只报 `onWarning`;未使用时不创建 DOM / 监听,实例销毁时一并清理。
166
+ - **同帧刷新**:指针拖动合并到 RAF,帧内先 `updateBackground()` 再 `refresh({ reflow: false })`,随后同步手柄、输入框与读数,底图和编辑层不会再错开一帧。
167
+ - **Demo 与公开面**:`BackgroundDemo.vue` 删除手写拖动、缩放、旋转、投影与编辑框 CSS,只调用内置 API;实例成员 276 → **280**,options 仍 105、数据字段仍 273、Demo 仍 23。
168
+ - **核心文件**:`src/gis-view/background-editor.js`(新增)、`gis-view.css`、`create.js`、`types.d.ts`;`docs/demos/BackgroundDemo.vue`、`demos.js`、`docs/manual/03` / `14` / `16` / `17` / `18` / `21`、`docs/internals/14`、`docs/steps/selftest-demos.html`、`selftest-features.html`、`selftest-docs.html`、本页、维护索引与 15.105。
169
+ - **验证**:`npx tsc --noEmit`、`node docs/steps/gen-api-index.mjs`、`npm run check:docs`(280 个实例成员 / 105 个 options / 273 个数据字段)、`npm run build`、`git diff --check` 通过;浏览器串行自测 `selftest-features` **793/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**。
170
+
171
+ ## 上五轮:背景编辑 4 / 8 / 9 点、旋转开关与可定制编辑框(2026-10-30)
172
+
173
+ - **需求来源**:根目录 `修改.txt` 五条 —— ① 只有开启旋转时才显示旋转按钮;② 取消宽高锁定后从四角改为常见八点,开启旋转后变成九点,并考虑背景角度;③ 背景编辑框样式支持自定义;④ 修复移动背景图的轻微晃动;⑤ 全部在 demo 中体现。
174
+ - **编辑点与旋转**:`BackgroundDemo.vue` 锁定比例时仍显示四角等比缩放;解锁后增加上下左右四个边中点,共八个缩放手柄;旋转开关独立于宽高锁定,只有勾选“允许旋转”才生成顶部旋转点和旋转连线,因此解锁并开启旋转时共九个编辑点。关闭旋转只收起旋转点,保留当前角度与八个缩放手柄。
175
+ - **旋转后的缩放**:缩放手柄先按背景旋转角把指针换算到未旋转局部坐标。角手柄可同时改局部宽高,锁比例时按相对位移更大的轴推导另一边;四边手柄只改所在边的局部宽度或高度,并固定对边中点。光标方向与边手柄朝向也按当前角度换算,避免旋转后拖动方向错位。
176
+ - **可定制编辑框**:demo 通过 CSS 变量实时调整轮廓颜色、填充、线宽、虚线、手柄尺寸与圆形 / 方形外观,覆盖轮廓、旋转连线、缩放手柄与旋转点;这些是使用方编辑 UI 的样式,不新增组件 options,组件仍只负责背景渲染与 `backgroundEditing` 交互锁。
177
+ - **晃动修复**:指针移动时不再同步刷新文本框和编辑手柄,只更新待提交状态并按动画帧合并;刷新帧内先 `updateBackground()`,再用 `refresh({ reflow: false })` 立即重绘底图,随后同步宽高读数与手柄位置,使 WebGL 背景和 DOM 编辑层落在同一帧。
178
+ - **Demo 与测试**:添加背景后仍自动进入编辑模式并放回视野;面板新增旋转开关、编辑点计数、颜色 / 线宽 / 虚线 / 手柄尺寸 / 形状控件。`selftest-demos` 覆盖默认四点、开旋转五点、解锁八点、解锁并旋转九点、旋转 30° 后边手柄只改局部宽度并固定对边、样式变量实时生效、关闭旋转收起按钮,以及指针移动时手柄不抢先且与底图同帧落位。
179
+ - **文档与公开面**:演示简介、手册 03 / 14 / 21 同步编辑点、旋转开关、样式边界与同帧刷新口径;实例成员仍 276、options 仍 105、数据字段仍 273、Demo 仍 23。
180
+ - **核心文件**:`docs/demos/BackgroundDemo.vue`、`docs/demos/demos.js`、`docs/manual/03-配置项.md`、`docs/manual/14-视图与筛选.md`、`docs/manual/21-说明与常见问题.md`、`docs/steps/selftest-demos.html`、本页、维护索引、15.104。
181
+ - **验证**:`npx tsc --noEmit`、`npm run check:docs`(276 个实例成员 / 105 个 options / 273 个数据字段)、`npm run build`、`git diff --check` 通过;浏览器串行自测 `selftest-features` **786/0**、`selftest-demos` **440/0**、`selftest-docs` **139/0**。
182
+
183
+ ## 上六轮:背景移动 / 旋转、背景编辑模式与网架整体显隐(2026-10-30)
184
+
185
+ - **需求来源**:根目录 `修改.txt` 两条 —— ① 背景可以调整位置并旋转;调整背景时网架不能拖拽、点击或以其他方式操作,但能和背景一起整体放大缩小,相当于只编辑背景或进入背景编辑模式;② Demo 明显有问题。此前同日一轮已补背景添加、四角调整与网架整体显隐 / 透明度,本轮在其上完成移动、旋转与编辑模式,并修好 Demo 的旧文案、旧状态和交互缺口。
186
+ - **背景移动与旋转**:`background.geoJsonStyle.bounds` 把整份解析后的 GeoJSON 独立缩放 / 平移到目标世界矩形,`geoJsonStyle.rotation` 再绕目标矩形中心顺时针旋转;填充、描边、点、逐区域范围、重心与区域文字一起变换,`rawBounds` 保持原始坐标,解析后的 `bounds` 是旋转后的轴对齐外框。图片用旋转后的 `image.corners` 表达同一位置 / 角度,不改原始数据。
187
+ - **背景编辑模式**:新增顶层 `backgroundEditing`。打开后节点、线路、通道的悬停、点击、选中、拖拽、拐点编辑、框选、右键与数据快捷键全部停用,DOM 标签也不再抢指针;滚轮缩放与 `fitView` 保留,因此网架和背景仍作为一个整体缩放。配置走表现型快路,不重建场景,也不改数据、选中、历史或相机。
188
+ - **Demo 修复与体验**:「背景与网架」增加背景内部拖动、四角缩放、顶部圆点旋转、Shift 15° 吸附、±15° 按钮、精确角度输入、适应背景与进入 / 退出编辑模式;添加背景后自动进入编辑并放回视野,编辑覆盖层上的滚轮转发给画布。图片与 GeoJSON 分别写 `corners` 与 `bounds + rotation`,隐藏 / 压淡网架和整体透明度能力保留。
189
+ - **文档与公开面**:手册 03 / 14 / 16 / 18 / 21、类型声明、API 索引与三页自测同步;options 104 → 105,数据字段 272 → 273,实例成员仍 276,Demo 仍 23。
190
+ - **核心文件**:`src/gis-view/engine.js`、`background.js`、`create.js`、`overlay.js`、`update-policy.js`、`types.d.ts`;`docs/demos/BackgroundDemo.vue`、`demos.js`、`docs/demos/api-index.js`、`docs/manual/03` / `14` / `16` / `18` / `21`、`docs/steps/selftest-features.html`、`selftest-demos.html`、`selftest-docs.html`、本页与维护索引、15.102 / 15.103。
191
+ - **验证**:`npx tsc --noEmit`、`node docs/steps/gen-api-index.mjs`、`npm run check:docs`(276 个实例成员 / 105 个 options / 273 个数据字段)、`npm run build`、`git diff --check` 通过;浏览器串行自测 `selftest-features` **786/0**、`selftest-demos` **433/0**、`selftest-docs` **139/0**。
192
+
193
+ ## 上七轮:交互样式优先级回归、单 / 多要素样式 Demo 与详情查询(2026-10-30)
194
+
195
+ - **需求来源**:根目录 `修改.txt` 三条 —— ① 选中 / 框选 / 多选 / 级联等交互颜色始终最高,不受规则束缚;② 增加修改单个或多个节点 / 线路样式的 demo;③ 说明如何查询单个或多个节点、线路、通道的详情。按本轮补充要求,分组详情不纳入改动。
196
+ - **交互样式优先级**:现有解析链保持「状态样式 / 热力图 > override 规则 > 要素自身 > 普通规则 > 全局样式 > 默认值」不变;核对窄样式快路径只在无规则、无热力图时启用,不会绕过状态层。新增浏览器回归覆盖单选、动态切换 override 规则、多选节点 / 线路、框选节点 / 线路与级联,证明颜色不会被强制规则改回业务色;线路框选沿用 `lineSelectStyle`。
197
+ - **单 / 多要素样式 Demo**:`StyleDemo.vue` 增加节点与线路下拉、`updatePoint` / `updateLine` 单条按钮、`patchPoints` / `patchLines` 批量按钮、原始数据恢复,以及悬停 / 单选 / 多选 / 框选 / 级联五种交互样式颜色。面板同时显示选中、级联和补丁读数,可直接对比「规则强制覆盖」与交互状态的层级。
198
+ - **详情查询**:Demo 增加 `getPoint` / `getLine` / `getChannel` 单查与 `listPoints` / `listLines` / `getChannels` 批量读数;手册 18 新增「单条 / 多条要素详情」,说明 id / 下标引用、`null` 与空数组、`indexes` / `inView` / `limit` / `withScreen` / `visibleOnly` 选项、节点 / 线路 / 通道返回字段,以及按 id 先查下标再批量查询的写法。手册 11 把单 / 多要素样式合成一节,并明确交互颜色高于任何规则。
199
+ - **核心文件**:`docs/demos/StyleDemo.vue`、`docs/demos/demos.js`、`docs/manual/11-样式与规则.md`、`docs/manual/18-逐方法示例.md`、`docs/steps/selftest-features.html`、`docs/steps/selftest-demos.html`、本页、维护索引与 15.101。
200
+ - **验证**:`npx tsc --noEmit`、`npm run check:docs`(276 个实例成员 / 102 个 options / 270 个数据字段)、`npm run build`、`git diff --check` 通过;`selftest-features` 778/0、`selftest-demos` 415/0、`selftest-docs` 138/0。未改公开 API,API 计数不变。
201
+
202
+ ## 上八轮:规则优先级分层、单要素样式说明与解析性能(2026-10-30)
203
+
204
+ - **需求来源**:根目录 `修改.txt` 四条 —— ① 规则样式始终高于外层 `pointStyle` / `lineStyle`,但默认低于要素自身样式;② 单条规则可用 `override: true` 压过要素自身样式;③ 补充单个节点 / 单条线路改颜色、尺寸、图标等样式的方法;④ 继续优化组件性能。
205
+ - **规则优先级**:统一为「状态样式 / 热力图 > override 规则 > 要素自身样式 > 普通规则 > 外层 `pointStyle` / `lineStyle` > 默认值」。普通规则不再被外层样式遮住,但也不会抢要素自己写的字段;所有层都按字段生效,未写字段继续向下回落,状态样式与热力图始终最高。同一层多条规则仍按声明顺序后命中覆盖先命中。
206
+ - **逐规则 `override`**:`pointRules` / `lineRules` 的每一项新增 `override?: boolean`,只有严格 `true` 生效。override 规则只压过它实际写到的字段,其他字段继续交给要素自身、普通规则与外层样式;主图和鹰眼图共用同一优先级,小图颜色 / 线宽不会与主图分叉。
207
+ - **单节点 / 单线路样式**:手册 11 新增「改单个节点 / 线路的样式」示例,覆盖 `updatePoint` 改颜色、尺寸、`symbol` 图标,`updateLine` 改颜色、线宽、虚线,`patchPoints` / `patchLines` 批量改写,以及线路 `decorations` 替换装饰图标;把字段写回 `null` 可摘除逐要素覆盖并回落到规则 / 外层样式,无需整份 `updateData()`。
208
+ - **解析性能与鹰眼图**:`compileRules` 编译期预计算每条规则实际写到的字段,逐要素只遍历这些键;规则表无 override 时跳过第二份暂存清理。`point.js` / `line.js` 使用普通与 override 双 scratch,`engine.js` 的整批解析、状态刷新、定向更新、拖拽 / 复制预览和锚点尺寸读数全部接入,`create.js` 的鹰眼图同步同一口径。10 万要素 / 4 条规则 / 9 个字段的 Node 微基准:规则合并中位 **21.82 → 17.69 ms**(约 **1.23×**,校验和一致)。
209
+ - **核心文件**:`src/gis-view/rules.js`、`point.js`、`line.js`、`engine.js`、`create.js`、`types.d.ts`;手册 11 及 02 / 03 / 07 / 09 / 12 / 13 / 14 / 16 / 17 / 18 / 19 / 20 / 21、格式 02 / 03、internals 10 / 13 / 17 / 18 / 15.100、from0 06、教学页、`StyleDemo.vue`、`docs/demos/api-index.js`、本页与维护索引。
210
+ - **验证**:`npx tsc --noEmit`、`npm run check:docs`(276 个实例成员 / 102 个 options / 270 个数据字段)、API 索引生成、`npm run build`、`git diff --check` 通过;`selftest-features` 771/0,其余 actions / data / decoration / demo / demos / docs / effects / full / labels / select / selftest 页均 0 FAIL。`selftest-perf` 186/1(既有标签布局读数量测)、`selftest-scale` 120/2(既有筛选回调时序 `onFilter 0 条`),单页重跑仍复现,与本轮样式链无关。
211
+
212
+ ## 更早记录:updatePoint 快路径、id 索引拆分与插件生命周期(2026-10-29)
213
+
214
+ - **需求来源**:根目录 `修改.txt` 两条 —— ① 继续优化 `gis-view` 性能,包括交互、方法调用等,允许大改;② 提高组件可扩展性与后续可操作性。
215
+ - **定向更新快路径**:`updatePoint` 现在只在坐标或 id 变化时收集跟随线路,只有节点外框尺寸变化才重排锚定通道;只改名称 / 颜色 / 透明度等业务字段时,不再扫线路归属、重排通道或刷新拐点批次,直接走单点槽位补丁。修复 id 改名时用新对象查旧线路绑定的回归:先用更新前对象解析旧绑定,坐标仍用新值刷新。
216
+ - **id 索引拆分**:点 / 线各维护一份独立 id 表、版本、来源数组与条数;更新一个节点不再顺带重建十万条线路的索引,追加 / 整份换数据时按各自数组懒重建,单条改 id 只挪一个键。10 万点 / 10 万线下 `repeat:updatePoint500:4` 从改前 **62.3 / 6.8 / 4.7 / 4.3 ms** 降到三次复测的 **15.0 ~ 15.4 / 1.8 ~ 2.1 / 1.0 ~ 1.3 / 0.8 ~ 0.9 ms**(首段含首次建点 id 表),500 次批量改名稳态约 1 ms。
217
+ - **插件生命周期**:每个插件拿到独立冻结上下文 `{ apiVersion, view, signal, onCleanup, on, registerCommand }`。卸载 / 实例销毁时先 abort 自己的 signal,再跑旧写法的 `destroy`,最后按登记倒序跑自动清理;`on` / `registerCommand` 自动退订 / 注销,提前清理幂等。初始化成功即纳入视图生命周期,初始化后再登记的资源也不会漏;初始化抛错会先收回已登记资源。旧 `(view) => ({ destroy })` 写法继续兼容。
218
+ - **测试与文档**:`selftest-features` 补插件 signal、自动清理、初始化失败、实例销毁及初始化后登记资源共 8 条断言(752 → 760);手册 15 重写插件上下文与示例,03 / 16 / 17 / 18 同步 `use()` 清理口径,手册 20 记录本轮基准。
219
+ - **核心文件**:`src/gis-view/create.js`、`engine.js`、`types.d.ts`;`docs/manual/03` / `15` / `16` / `17` / `18` / `20`、`docs/demos/api-index.js`、`docs/steps/selftest-features.html`、本页与维护索引。
220
+ - **验证**:`npx tsc --noEmit`、`npm run check:docs`(276 个实例成员 / 102 个 options / 270 个数据字段全部命中)、`node docs/steps/gen-api-index.mjs --check`、`npm run build`、`git diff --check` 通过;`selftest-select` 102/0、`selftest-demos` 407/0、`selftest-features` 760/0、`selftest-docs` 138/0、`selftest-perf` 187/0。
221
+
222
+ ## 再早一轮:div 保留框跟随、通道单回线显隐与拾取优化(2026-10-29)
223
+
224
+ - **需求来源**:根目录 `修改.txt` 四条 —— ① 框选后保留选框,并可拖动整框平移选中节点、线路与通道;② 框选样式可配、支持 DOM 与自定义类名;③ 节点 / 线路 / 通道 / 分组支持单个与批量隐藏、恢复;④ 隐藏线路时可选择保留原回线位置或让剩余回线重新居中。
225
+ - **本轮续修来源**:根目录 `修改.txt` 三条 —— ① `selectionBoxStyle.render: 'div'` 的保留框在移动地图时应和 canvas 框一样跟随;② 通道 demo 补「隐藏某条通道内指定线路」的示例;③ 继续优化组件性能。
226
+ - **保留框与样式**:新增 `selectionBoxPersistent`、`clearSelectionBox()`、`getSelectionBox()`。非空框选后在框内拖动会按世界坐标增量平移全部选中节点,绑定线路、通道骨架与回线跟随;不参与节点合并,框内按下但未拖动也不会误清选中集。选中集变化、清空、关闭开关、销毁或手动调用时收起。`selectionBoxStyle` 增加 `render: 'div'`、`className`、`borderStyle`、`radius`,DOM 模式挂 `.gis-view__selection-box` 并追加自定义类;canvas 模式保持实线直角。
227
+ - **四类显隐**:`setFeatureVisible` 的 `kind` 扩到 `point` / `line` / `channel` / `group`,`refs` 支持 `'selection'`。分组可写 `{ channelId | channelIndex, groupId | groupIndex }`、`{ id }` 或唯一裸 id;`hideFeatures('group', ...)` 只收起该组,成员、骨架、拐点、`getChannelGroups()` 与 `getLineChannel()` 归属都保留,隐藏组不绘制 / 不拾取 / 不注册锚点。批量操作仍是一步历史、一条 `batch` 数据变更,结果新增 `groups` 快照;分组结果的 `indexes` 是通道下标、`ids` 是分组 id。
228
+ - **隐藏回线车道**:新增 `channelHiddenLineLayout: 'preserve' | 'center'`。`preserve`(缺省)保留原槽位;`center` 把当前可见回线按原顺序压成连续槽位并在通道宽度内重新居中,隐藏分组、逐条隐藏与筛选隐藏都参与判断。同时修复隐藏 / 恢复线路时半跳过状态未标脏、恢复后数据可见但不渲染的问题。
229
+ - **div 保留框跟随相机**:保留框新增世界坐标锚点 `selectionBoxWorld`;渲染帧从世界范围重投影,`getSelectionBox()` 与框内命中判断也先同步当前相机。div 框平移只写 `translate3d`,宽高只在缩放 / 拖动时更新,颜色、线型、圆角与类名按样式版本缓存;框内整组拖动与节点共用同一份世界增量,拖拽中相机变化也不会错位。
230
+ - **通道内单回线示例**:`ChannelDemo.vue` 新增「隐藏首通道末回线 / 显示」按钮,走 `hideFeatures('line', lineId)`,通道、分组与其它成员声明不变;`selftest-demos` 校验隐藏后成员 / 分组保留、其它回线不受影响,恢复后样式与数据回来。
231
+ - **性能收口**:`pick()` / `pickDraggablePoint()` 去掉逐候选 `projectPoint()` 数组和 `Math.hypot()`,相机中心 / 比例 / 半视口提到循环外,用平方距离比较;聚合拾取复用同一组常量。保留框的每帧投影也改为就地更新矩形,不再产生临时对象。10 万点 / 10 万线三次基准见 [手册 20](manual/20-性能与大数据.md#保留框-dom-跟随与拾取热路径):拾取仍稳定在亚毫秒级,平移 / 刷新差值受无头环境抖动影响,不作单独收益归因。
232
+ - **核心文件**:`src/gis-view/engine.js`、`create.js`、`types.d.ts`、`update-policy.js`、`gis-view.css`;`docs/manual/03` / `08` / `09` / `16` / `17` / `18` / `20`、`docs/internals/18`、`ChannelDemo.vue`、`demos.js`、`gis-view-demo` 面板、`selftest-select.html`、`selftest-demos.html`、`selftest-features.html`、`selftest-docs.html`、`selftest-perf.html`、`docs/demos/api-index.js`。
233
+ - **验证**:`npx tsc --noEmit`、`npm run build`(仅有既有大 chunk 提示)、`npm run check:docs`(276 个实例成员 / 102 个 options / 270 个数据字段全部命中)、`node docs/steps/gen-api-index.mjs --check`、`git diff --check` 通过;`selftest-select` 102/0、`selftest-demos` 407/0、`selftest-features` 752/0、`selftest-docs` 138/0、`selftest-perf` 187/0。
234
+
235
+ ## 更早一轮:README 精简与维护规则(2026-10-29)
88
236
 
89
237
  - **需求来源**:根目录 `修改.txt` —— 根 `README.md` 太长,不适合直接作为 npm 首页;并明确要求不要每轮都更新 README。
90
238
  - **README 定位**:把根 README 从 406 行的逐轮记录与性能长文收敛为 88 行、约 3 KB 的稳定首页,只保留产品简介、特性、安装、最小示例、文档入口、开发命令与运行说明;代码示例的包名统一为 `package.json` 里的 `gis-view-webgl2`。
@@ -92,7 +240,7 @@
92
240
  - **核心文件**:`README.md`、`AGENTS.md`、`docs/AI对话汇总.md`、`docs/ai/06-会话索引与复查方法.md`。
93
241
  - **验证**:`npx tsc --noEmit`、`npm run check:docs`(274 个实例成员 / 100 个 options / 266 个数据字段)、`node docs/steps/gen-api-index.mjs --check`、`npm run build` 与 `git diff --check` 通过;`selftest-docs` 138 条 0 失败。
94
242
 
95
- ## 上一轮:fitSpacing 距离模式互斥与屏幕距离读数(2026-10-29)
243
+ ## 更早记录:fitSpacing 距离模式互斥与屏幕距离读数(2026-10-29)
96
244
 
97
245
  - **需求来源**:根目录 `修改.txt` 两条 —— ① `fitSpacing` 的 `minDistance` / `maxDistance` 只能选一种,节点距离要么按最大、要么按最小;② `getPointSpacing()` 的最近 / 最远距离要和 `fitSpacing` 一样考虑地图缩放比例。
98
246
  - **fitSpacing 互斥**:`normalizeFitSpacing()` 把两个距离归一成单一模式;同时给出时只按 `maxDistance` 计算,`minDistance` 不参与。`fitSpacingAdjustment()` 改为明确分支,`maxDistance` 仍只压低比例,不会因上限过宽反而放大。`getOptions()` 保留原始入参,不回写内部归一化结果。
@@ -100,7 +248,7 @@
100
248
  - **核心文件**:`src/gis-view/engine.js`、`create.js`、`types.d.ts`;manual 03 / 14 / 16 / 17 / 18、demo 样式面板、`selftest-scale.html`、`docs/demos/api-index.js`。
101
249
  - **验证**:`npx tsc --noEmit`、`npm run check:docs`(274 个实例成员 / 100 个 options / 266 个数据字段)、`node docs/steps/gen-api-index.mjs --check`、`npm run build` 通过;`selftest-features` 740/0、`selftest-docs` 138/0、`selftest-demos` 395/0;`selftest-scale` 120/122,新增的互斥与屏幕距离断言通过,剩余两条仍是既有筛选回调断言(`onFilter 0 条`,与本轮改动无关)。
102
250
 
103
- ## 更早一轮:直接连接分列、节点距离与回显比例(2026-10-29)
251
+ ## 更早记录:直接连接分列、节点距离与回显比例(2026-10-29)
104
252
 
105
253
  - **需求来源**:根目录 `修改.txt` 三条 —— ① `getDirectConnections` 可按通道 / 线路筛选并按类外层分列;② 导出部分场站后回显比例被自动适应放大;③ 读取最近 / 最远节点距离,并给 `fitSpacing` 增加 `maxDistance`。
106
254
  - **直接连接查询**:`getDirectConnections(pointIds, options?)` 固定返回 `{ channels, lines }`;第二段支持 `'channel'` / `'line'` / `'both'` 或 `{ kind }`,只查一列时另一列为空数组,无效值按 `both`;通道与成员回线分别落列,仍只查集合内部的直接边。
@@ -109,7 +257,7 @@
109
257
  - **核心文件**:`src/gis-view/create.js`、`engine.js`、`utils.js`、`types.d.ts`;`docs/manual/03` / `09` / `14` / `16` / `17` / `18`、demo 样式面板、`selftest-features`、`selftest-scale`。
110
258
  - **验证**:`npx tsc --noEmit`、`npm run check:docs`(274 个实例成员 / 100 个 options / 266 个数据字段)、`node docs/steps/gen-api-index.mjs --check`、`npm run build`、`git diff --check` 通过;`selftest-features` 740 条 0 FAIL,`selftest-docs` 138 条 / `selftest-demos` 395 条均 0 FAIL;`selftest-scale` 120/122,本轮新增的距离与 `maxDistance` 断言通过,失败的两条是既有筛选回调断言(`onFilter 0 条`,与本轮改动无调用关系)。
111
259
 
112
- ## 再早一轮:AI 文档合并与阅读导航(2026-10-29)
260
+ ## 更早记录:AI 文档合并与阅读导航(2026-10-29)
113
261
 
114
262
  - **需求来源**:根目录 `修改.txt` 两条 —— ① 修改 AI 文档页,精简合并;② 继续优化文档页面的呈现效果。
115
263
  - **AI 文档合并**:把原先 `ai/01` ~ `ai/05` 的来源、主题分类、精选问答与旁支记录压缩进本页;保留 `ai/06` 作为会话文件、历史增量与复查方法的维护索引。AI 文档从 7 个入口收敛为 2 个入口,主页面不再重复堆叠逐轮细节。
package/docs/GisView.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # GisView
2
2
 
3
- `GisView` 是一套不依赖任何第三方图形库的 WebGL2 矢量视图:渲染层是原生 WebGL2(GLSL ES 3.00 + 实例化绘制),交互层只有指针与滚轮,界面只内置可选的小地图(配 `minimap` 才有,见「鹰眼图」),其余全靠使用方。它没有 Vue 组件形态,用 `createGisView(dom, options)` 把画布直接挂到传入的 DOM 上,宽高默认跟随容器。
4
-
5
- 控制面板、读数面板、图例这类视图工具都不内置:组件只提供画布与实例方法,样式和布局完全由使用方决定,后续改样式不需要等待组件升级。数据侧该有的都给了:按属性筛选(默认只隐藏,也可显式从数据删除;点被过滤时绑定线路与通道一起消失,大数据量走 Web Worker)、按属性批量配色换符号、节点标签与点 / 线 / 通道的悬浮提示,都可以通过 options 或实例方法配置。
3
+ `GisView` 是一套不依赖任何第三方图形库的 WebGL2 矢量视图:渲染层是原生 WebGL2(GLSL ES 3.00 + 实例化绘制),交互层只有指针与滚轮,界面只内置可选的小地图、热力图图例与背景编辑器(分别配 `minimap` / `visualMap` / 调 `beginBackgroundEdit()` 才有,见「鹰眼图」「图例(visualMap)」「背景层」),其余全靠使用方。它没有 Vue 组件形态,用 `createGisView(dom, options)` 把画布直接挂到传入的 DOM 上,宽高默认跟随容器。
4
+
5
+ 控制面板与读数面板不内置;需要热力图图例时也不必自建:`options.visualMap` 会画一条带刻度的连续色带(`ruler` / `continuous`)或一组分段色块(`piecewise`),默认跟随 `heatmap` 的字段、值域与颜色。显式写 `target` 时选区只门控这一类;不写时展示值域取第一类有数值的启用目标,选区却覆盖全部启用目标上同 `field` 的热力上色、光晕与密度。图例本身就能点选分段、拖动筛选区间;默认继承主图热力的鹰眼图同步门控,显式 `minimap.heatmap` 仍独立。落选值由 `outOfRange` 选择只回普通样式(`'heatmap'`,缺省)、把对应节点 / 独立线路 / 通道一起隐藏(`'network'`),或完全不做内置门控而只发 `onChange`(`'none'`);三种方式都不删除数据、不改筛选。额外业务联动仍可听 `onChange`。需要「再次点击已选中要素即取消」时打开 `toggleSelect`(缺省关),普通单击、双击与 Ctrl 选中后的普通单击都适用。需要完全换一套外观时用 `render(context)` 接管内容,不必再写插件。其余样式和布局由使用方决定,后续改样式不需要等待组件升级。数据侧该有的都给了:按属性筛选(默认只隐藏,也可显式从数据删除;点被过滤时绑定线路与通道一起消失,大数据量走 Web Worker)、按属性批量配色换符号、节点标签与点 / 线 / 通道的悬浮提示,都可以通过 options 或实例方法配置。
6
6
 
7
7
  **这份手册按主题拆成了 21 章,正文在 [`docs/manual/`](manual/) 下**:找方法先看 [16 实例方法总表](manual/16-实例方法总表.md),查参数跳 [17 参数速查](manual/17-参数速查.md),要能直接复制的调用看 [18 逐方法示例](manual/18-逐方法示例.md);只想先跑起来看 [01 快速开始](manual/01-快速开始.md)。
8
8
 
@@ -28,11 +28,11 @@
28
28
  | [10 通道编辑与新增](manual/10-通道编辑与新增.md) | 分组拐点的增删、右键交互框、新增通道的草稿流程、改名与增删回线 |
29
29
  | [11 样式与规则](manual/11-样式与规则.md) | 点配置、线配置、条件语言(筛选 / 规则 / 标签共用)与批量样式规则 |
30
30
  | [12 标签与装饰](manual/12-标签与装饰.md) | 节点 / 线路标签、标签拖动与编辑、节点与线路装饰、动态装饰器草稿、悬浮提示 |
31
- | [13 动效与图元](manual/13-动效与图元.md) | 热力图、动画效果、线路方向箭头、贴图预热与自定义图元 |
31
+ | [13 动效与图元](manual/13-动效与图元.md) | 热力图、图例(visualMap)、动画效果、线路方向箭头、贴图预热与自定义图元 |
32
32
  | [14 视图与筛选](manual/14-视图与筛选.md) | 筛选、搜索定位、初始视图与缩放范围、背景层、鹰眼图、近义入口 |
33
33
  | [15 导出与集成](manual/15-导出与集成.md) | 导出图片 / 选中节点 / 数据、自定义导出格式,插件、自建界面与键盘交互 |
34
34
  | [16 实例方法总表](manual/16-实例方法总表.md) | 按功能分组的实例方法主表(找方法从这一章开始) |
35
- | [17 参数速查(逐个方法)](manual/17-参数速查.md) | 274 个成员逐个列全:参数、默认值与返回 |
35
+ | [17 参数速查(逐个方法)](manual/17-参数速查.md) | 283 个成员逐个列全:参数、默认值与返回 |
36
36
  | [18 逐方法示例(复制就能跑)](manual/18-逐方法示例.md) | 每个成员一段可复制的调用示例(API 速查页读的就是这一章) |
37
37
  | [19 读数与拖拽预览](manual/19-读数与拖拽预览.md) | 自建界面常用的读数 / 定位方法;拖拽落点预览 |
38
38
  | [20 性能与大数据](manual/20-性能与大数据.md) | 十万级数据的开关与实测、WebGPU 取舍、渲染后端开关 |
@@ -44,7 +44,7 @@
44
44
  - **配置与回调**:[options 总表](manual/03-配置项.md#options) · [回调](manual/04-事件与回调.md#回调) · [功能开关](manual/04-事件与回调.md#功能开关)
45
45
  - **通道**:[通道与多回线](manual/09-通道与多回线.md) · [通道编辑与新增](manual/10-通道编辑与新增.md) · [分组拐点](manual/10-通道编辑与新增.md#分组拐点把某一组拉走)
46
46
  - **样式**:[点配置](manual/11-样式与规则.md#点配置) · [线配置](manual/11-样式与规则.md#线配置) · [条件语言](manual/11-样式与规则.md#条件语言) · [批量样式规则](manual/11-样式与规则.md#批量样式规则)
47
- - **标签与动效**:[节点标签](manual/12-标签与装饰.md#节点标签) · [线路标签](manual/12-标签与装饰.md#线路标签) · [标签优化](manual/12-标签与装饰.md#标签显示优化开关labeloptimize) · [扩展图形](manual/12-标签与装饰.md#扩展图形graphic) · [节点装饰](manual/12-标签与装饰.md#节点上的装饰图片--svg) · [线路装饰](manual/12-标签与装饰.md#线路上的装饰图片--svg) · [手动删除装饰](manual/12-标签与装饰.md#手动删除装饰) · [动态装饰器](manual/12-标签与装饰.md#动态装饰器草稿) · [动画效果](manual/13-动效与图元.md#动画效果effects) · [自定义图元](manual/13-动效与图元.md#自定义图元)
47
+ - **标签与动效**:[节点标签](manual/12-标签与装饰.md#节点标签) · [线路标签](manual/12-标签与装饰.md#线路标签) · [标签优化](manual/12-标签与装饰.md#标签显示优化开关labeloptimize) · [扩展图形](manual/12-标签与装饰.md#扩展图形graphic) · [节点装饰](manual/12-标签与装饰.md#节点上的装饰图片--svg) · [线路装饰](manual/12-标签与装饰.md#线路上的装饰图片--svg) · [手动删除装饰](manual/12-标签与装饰.md#手动删除装饰) · [动态装饰器](manual/12-标签与装饰.md#动态装饰器草稿) · [图例(visualMap)](manual/13-动效与图元.md#图例visualmap) · [动画效果](manual/13-动效与图元.md#动画效果effects) · [自定义图元](manual/13-动效与图元.md#自定义图元)
48
48
  - **视图**:[筛选](manual/14-视图与筛选.md#筛选) · [搜索与定位](manual/14-视图与筛选.md#搜索与定位) · [适应视图的节点间距](manual/14-视图与筛选.md#适应视图的节点间距fitspacing) · [背景层](manual/14-视图与筛选.md#背景层) · [鹰眼图](manual/14-视图与筛选.md#鹰眼图)
49
49
  - **导出与集成**:[导出数据](manual/15-导出与集成.md#导出数据) · [自定义导出格式](manual/15-导出与集成.md#自定义导出格式后端-dto) · [插件](manual/15-导出与集成.md#插件) · [实例命令](manual/15-导出与集成.md#实例命令) · [六类扩展点怎么选](manual/15-导出与集成.md#六类扩展点怎么选) · [自建界面](manual/15-导出与集成.md#自建界面)
50
50
  - **查方法**:[实例方法总表](manual/16-实例方法总表.md) · [参数速查](manual/17-参数速查.md) · [逐方法示例](manual/18-逐方法示例.md) · [读数与拖拽预览](manual/19-读数与拖拽预览.md)
@@ -55,6 +55,21 @@
55
55
 
56
56
  | 日期 | 这一轮 |
57
57
  | --- | --- |
58
+ | 2026-11-02 | 增量:(「修改.txt」两条:GisEdit toggleSelect 被 selectionKinds 拦截 / 取消选中同步收掉级联) |
59
+ | 2026-11-01 | 增量:(「修改.txt」三条:toggleSelect 再次选中取消 / visualMap outOfRange 落选门控 / 交互性能) |
60
+ | 2026-11-01 | 增量:(「修改.txt」三条:热力密度几何隔离 / 线路热力连续 / visualMap 运行时门控) |
61
+ | 2026-10-31 | 增量:(「修改.txt」三条:线路热力交互连续显示 / 热力性能 / visualMap 自定义交互) |
62
+ | 2026-10-31 | 增量:(「修改.txt」两条:visualMap 连续尺 / 分段图例 / 图例专用快路径 / 继续优化性能) |
63
+ | 2026-10-30 | 增量:(「修改.txt」三条:minDistance 精确落位 / 指定节点组间距 / 距离公式文档) |
64
+ | 2026-10-30 | 增量:(「问题.txt」两条:GeoJSON 背景拖动文字晃动 / `fitSpacing.minDistance` 被缺省 `maxScale` 截断) |
65
+ | 2026-10-30 | 增量:(「修改.txt」两条:旋转按钮失效修复 / 背景编辑器内置为方法模块) |
66
+ | 2026-10-30 | 增量:(「修改.txt」五条:旋转开关 / 解锁八点与旋转后九点 / 编辑框样式 / 移动晃动 / 全部在 demo 体现) |
67
+ | 2026-10-30 | 增量:(「修改.txt」:背景图片 / GeoJSON 添加与四角调大小、网架整体隐藏 / 透明度;新增「背景与网架」Demo) |
68
+ | 2026-10-30 | 增量:(「修改.txt」三条:交互颜色始终压过规则 / 单·多节点与线路样式 Demo / 节点·线路·通道详情查询;按补充要求不含分组详情) |
69
+ | 2026-10-30 | 增量:(「修改.txt」四条:规则优先级高于外层样式 / 单条规则 override / 单节点与单线路样式说明 / 规则解析性能) |
70
+ | 2026-10-29 | 增量:(「修改.txt」两条:继续优化交互 / 方法调用性能、提高可扩展性与可操作性;updatePoint 快路径、id 索引拆分、插件生命周期) |
71
+ | 2026-10-29 | 增量:(「修改.txt」三条:div 保留框跟随 / 通道单回线显隐示例 / 拾取优化) |
72
+ | 2026-10-29 | 增量:(「修改.txt」四条:保留框拖动 / 框选样式 DOM 化 / 四类显隐 / 隐藏回线车道) |
58
73
  | 2026-10-29 | 增量:(「修改.txt」:根 README 精简为 npm 首页并约定不逐轮更新) |
59
74
  | 2026-10-29 | 增量:(「修改.txt」两条:fitSpacing 距离模式互斥 / getPointSpacing 屏幕距离读数) |
60
75
  | 2026-10-29 | 增量:(「修改.txt」三条:直接连接筛选、回显比例与节点距离读数) |
@@ -119,14 +134,149 @@
119
134
  | 2026-10-19 | 增量:(「修改.txt」继续优化与排查) |
120
135
  | 2026-10-19 | 增量:(「修改.txt」五条) |
121
136
 
122
- ## 三、当前增量:根 README 精简为 npm 首页(2026-10-29)
137
+ ## 三、当前增量:toggleSelect 节点 / 线路 / 通道 / 分组核验与 visualMap 多目标门控(2026-11-02)
123
138
 
124
- - **需求来源**:根目录 `修改.txt`:根 `README.md` 太长,放到 npm 页面不合适,并明确要求不再每轮更新 README。
125
- - **改动主题**:根 README 从 406 行精简为 88 行(约 3 KB),只保留产品简介、核心能力、安装、最小示例、文档入口、开发命令与运行说明;示例包名改为 `gis-view-webgl2`。`AGENTS.md` 同步约定根 README 默认稳定、不逐轮追加,逐轮记录写回 aimd 或手册。
126
- - **核心文件**:`README.md`、`AGENTS.md`、`docs/AI对话汇总.md`、`docs/ai/06-会话索引与复查方法.md`。
127
- - **验证**:`npx tsc --noEmit`、`npm run check:docs`(274 个实例成员 / 269 个方法 / 5 个属性 / 100 个 options / 266 个数据字段)、`gen-api-index --check`、`npm run build` 与 `git diff --check` 通过;`selftest-docs` 138/0。
139
+ - **需求来源**:根目录 `修改.txt`:① 检查 `toggleSelect` 是否真的生效;② 续查对线路、通道和通道分组的取消是否生效;③ 反馈再次点击通道 / 线路 / 分组不会取消、只有节点能取消;④ 前一轮的 `visualMap` 交互没有效果、不会隐藏。
140
+ - **toggleSelect 根因与修复**:入口原先只判断命中的那一条线路 `result.selected`。通道分组 / 整条通道只选中一部分,或点到组内、通道内的另一条回线时,这个值可能为 false,点击会落到普通单选并重新选上,表现得像只有节点能取消。现在 `engine.js` 的 `selectionScopeKeysOf()` 统一按 `channelSelectMode` 求展开范围;`toggleSelect` 用范围 `anySelected` 判断,并以 `removeOnly` 整批取消,不再要求命中的恰好是那条已选回线;Ctrl / 多选路径仍保持原来的整批取反 / 补缺语义。新增独立线路、通道单条、完整 / 部分分组、完整 / 部分通道 6 条指针回归,两条选中回调都报 `toggleSelect`;`selftest-select` 107 → **113/0**。
141
+ - **toggleSelect 跨模式补充**:真实 `?demo=full` 再复核发现,默认 `channelSelectMode: 'line'` 时,用 `selectFeatures` / 右键菜单先完整选中整条通道或分组,再点回线只会移除命中那一条,剩余成员仍选中,视觉上仍像通道 / 分组没有取消。`engine.js` 新增 `selectionToggleScopeKeysOf()`:`line` 模式下,命中回线所属通道完整选中时优先整条取消,否则分组完整选中时整组取消;部分选中仍按当前模式摊开,Ctrl / 多选不变。`?demo=full` 用 3 回线通道和真实 `pointerdown` / `pointerup` 验证:完整通道选中后点击一条,选中集由 3 条变为空。`selftest-select` 再增 2 条,113 → **115/0**;手册 03 / 08、`types.d.ts`、组件 README 同步。
142
+ - **GisEdit 配置链路复核与取消级联**:`D:\work\gis-view\src\components\GIS\GisEdit.vue` 实际是 `selectionKinds: ['point', 'lines']`、`channelSelectMode: 'channel'`。`selection.js` 把 `'lines'` 归一成 `'line'`,所以 `channel` 不在允许集合里;但 `engine.js` 的 `toggleSelect` 取消分支仍检查 `selectionKinds`,通道回线(分组回线也归为 `channel`)根本没进入取消路径,普通点击又把它重新选上。线路大多属于通道,因此 GisEdit 里看到的是通道 / 线路 / 分组都不会取消。现在移除该门控,`selectionKinds` 继续只约束框选与 Ctrl / 多选,与 `types.d.ts`、手册 03 / 08 的既有口径一致;`selftest-select` 直接用 `['point', 'lines'] + channelSelectMode: 'channel'` 复现 GisEdit 配置,覆盖整条通道与完整分组取消,115 → **117/0**。
143
+ - **取消选中时级联收尾**:此前级联高亮在点击分流之前无条件提交,toggleSelect / Ctrl 取反等真正取消选中时可能先发一次非空再发 `null`,接口取消则完全不会收。`engine.js` 抽出 `updateCascadeForClick()`:会取消的点击只清旧级联;普通选择与新增选择仍按 `triggerOnClick` / `triggerOnMultiSelect` 更新。`setSelection` 发现本次移除了选中键时也调用 `clearCascadeHighlightState()`,因此 `deselect`、`selectFeatures(..., { mode: 'remove' })`、`selectFeatures(null)` 都会同步收掉级联并只发一条 `onCascadeHighlight(null)`。`selftest-features` 新增 toggleSelect、deselect、selectFeatures remove 三条回归,839 → **842/0**。
144
+ - **visualMap 根因**:内部状态此前只有单个 `target`,不写 `target` 时门控只取 `heatmap.target` 第一项 `point`;`new.json` 节点没有 `max_loading_rate`,图例展示值域退化为空;Demo 构建通道时也没写这一列,`channel` 分支没有可判定的值。因此图例看起来既不显示有效值域,也不会隐藏线路 / 通道。
145
+ - **多目标门控**:`visual-map.js` 内部快照 / 签名加入 `targets`,未显式写 `target` 时展示值域按 `point → line → channel` 选第一个真正有数值的目标,门控覆盖全部启用目标;`heatmap.js` 的 `visualStateAllows()` 按 `targets` 匹配;`engine.js` 的 `computeVisualHiddenIndexes()` 同时处理落选节点、独立线路与整条落选通道,`setVisualMapState()` 的 `affectsPoint` / `affectsLine` 也按目标组判断。公开面不增加 `targets` 字段,仍为 283 个实例成员(278 方法 + 5 属性)/ 107 options / 275 数据字段。
146
+ - **Demo 与回归**:`buildNewData` / `buildSampleData` 给通道补成员最大 `max_loading_rate`,Demo 默认 `visualMapOutOfRange` 改为 `network`,面板提示说明不写 `target` 时三类一起门控。`selftest-features` 新增 3 条:节点缺字段时图例展示值域切到 `line`、多目标 `network` 同时隐藏三类、恢复全选后全部回画布。真实 `?demo=full` 复核:7368 节点 / 12811 线路 / 9230 通道;重新随机后图例自动切到 `point`(0.401 ~ 1.5),取消首段后可见节点 / 线路由 2123 / 4058 降到 0 / 0。
147
+ - **核心文件**:`src/gis-view/visual-map.js`、`heatmap.js`、`engine.js`、`create.js`、`types.d.ts`、`src/gis-view/README.md`;`docs/manual/03` / `07` / `08` / `11` / `13`、`docs/GisView.md`、`docs/demos/gis-view-demo/useGisViewDemo.js`、`panels/StylePanels.vue`、`docs/steps/selftest-features.html`、`selftest-select.html`、本页与 `docs/AI对话汇总.md`。
148
+ - **验证**:`node --check src/gis-view/engine.js`、`npx tsc --noEmit`、`node docs/steps/gen-api-index.mjs`、`npm run check:docs`、`npm run build`、`git diff --check` 通过;串行自测 `selftest-select` **117/0**、`selftest-features` **842/0**、`selftest-actions` **96/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-perf` **197/0**。真实 `?demo=full` 以实际指针事件复核完整通道取消,选中集由 3 条变为空。性能页首次组合运行出现 **192/5**,5 条均为既有「线路标签候选复用」的标签排版时序,单独复跑全绿,与本轮改动没有调用关系。
128
149
 
129
- ## 四、怎么自己复查
150
+ ## 四、上一增量:再次选中取消、visualMap 落选门控与交互快路径(2026-11-01)
151
+
152
+ - **需求来源**:根目录 `修改.txt` 三条:① 新增取消选中开关,默认关闭,单击、双击、Ctrl 先选中的路径都能再次操作取消;② 继续优化交互性能;③ `visualMap` 落选后应与热力图 / 网架联动,可选择消失对应网架或对应热力。按用户补充「不考虑分组详情」,本轮不扩展分组详情查询。
153
+ - **toggleSelect**:顶层 `options.toggleSelect` 缺省 `false`,`create.js` 透传引擎,`updateOptions` 可运行时切换。单击模式下第二次普通单击已选要素取反;`selectTrigger: 'dblClick'` 下由第二下取反、再次双击取消;Ctrl / ⌘ 先选中后再普通单击也取消。双击每轮只取反一次,不改变普通 `onClick` / `onDblClick` 的派发顺序;取反时 `onClick.action.type` 与 `onSelectChange.action.type` 都是 `toggleSelect`。
154
+ - **outOfRange**:`visualMap.outOfRange` 缺省 `'heatmap'`,只退出同一 `target` / `field` 的热力、恢复普通样式;`'network'` 额外隐藏落选节点、独立线路或整条通道成员,并从拾取与包围盒消失;`'none'` 不参与内置门控,只保留 `onChange`。`network` 的 `channel` 按声明收集全部成员回线,`line` 不误伤通道回线;缺值与非数值不参与隐藏。三种模式都不改数据、筛选、选中集或分组声明。图例状态、读数与 `onChange` 载荷都带 `outOfRange`。
155
+ - **性能**:引擎把筛选基线隐藏与 visualMap 视觉隐藏分成两套集合,解析时取并集;`network` 隐藏集合不变时 `setVisualMapState()` 返回 `hiddenChanged: false`,不重建场景。点 / 线热力样式缓存键分开,图例只影响节点时不再重算线路那一半;通道成员收集按声明一次完成。鹰眼图在 `network` 下同步隐藏,即使显式配置 `minimap.heatmap` 也不遮挡该语义。
156
+ - **Demo、测试与文档**:Demo 增加 `toggleSelect` 开关与落选值下拉;`selftest-select` 新增 5 条覆盖普通、双击、Ctrl、事件动作与关闭态,`selftest-features` 新增 8 条覆盖三种 `outOfRange`、节点 / 独立线路 / 通道、数据与筛选不变、隐藏集合快路径与鹰眼图同步。性能页的标签稳态用例改用 `progressiveInit: false` + `labelOptimize: true` 并显式等待 `isLayoutReady()`,避免锚点视图因发散渲染未完成而把第七轮首次真实排版误记成整屏重量。手册 03 / 08 / 13 / 14、`docs/GisView.md`、组件 README、API 索引、本页与 15.111 同步。
157
+ - **核心文件**:`src/gis-view/engine.js`、`create.js`、`heatmap.js`、`visual-map.js`、`update-policy.js`、`types.d.ts`;`docs/manual/03` / `08` / `13` / `14`、`docs/GisView.md`、`src/gis-view/README.md`、Demo 组合式函数与面板、`selftest-select.html` / `selftest-features.html` / `selftest-perf.html`、`docs/AI对话汇总.md`、本页与 15.111。
158
+ - **验证**:`npx tsc --noEmit`、`npm run check:docs`、`npm run build`、`git diff --check` 通过;API 索引为 283 个实例成员(278 方法 + 5 属性)/ 107 options / 275 数据字段;串行自测 `selftest-select` **107/0**、`selftest-features` **836/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-perf` **197/0**。
159
+
160
+ ## 五、上两增量:热力密度几何隔离、线路热力连续与 visualMap 运行时门控(2026-11-01)
161
+
162
+ - **需求来源**:根目录 `修改.txt` 三条:① 开启热力图后平移 / 缩放时仍有部分线路热力先消失再出现;② 开启热力图后背景也跟着放大缩小;③ `visualMap` 交互没有效果,应参考 ECharts 的交互直接作用于热力表现。
163
+ - **背景缩放根因**:密度场有独立的 `heatDensityBuffer`,但 `drawImageQuad()` 仍默认绑定背景图片的 `imageVao`,密度四边形一变就按图片几何缩放。现在新增 `heatDensityVao`,密度场拥有自己的四边形与 VAO;背景图片仍用 `imageVao`,两者销毁时分别释放。
164
+ - **线路热力连续**:`engine.js` 不再按 `interacting || cameraMoving` 把线路热力切到无光晕 / 细线路径。普通或自动浅底配置固定走 `drawHeatLineBatch()` 一笔合并核与光晕;加法混合或实例属性槽位不匹配时固定走两遍 `drawLineHeatGlow()`。自动画质降档也不会关闭线路热力,节点光晕仍可在交互期让路。
165
+ - **visualMap 门控链路**:`visual-map.js` 的 `visualStateSnapshot()` 只输出 `type` / `target` / `field` / `selected` / `range` / 选中的 `pieces`,同一状态不重复通知;`create.js` 保存首帧状态并在引擎创建后以 `refresh: false` 灌入,之后调用引擎内部 `setVisualMapState()`。`heatmap.js` 的 `visualStateAllows()` 只在 `target` 与 `field` 都匹配时门控,避免误伤独立图例或另一类要素;落选值回到普通样式,不删除数据、不触发筛选。默认继承主图热力的鹰眼图使用同一状态并随选区刷新,显式 `minimap.heatmap` 不跟随。
166
+ - **交互边界**:分段空选择关闭对应热力,区间端点为闭区间,分段按归一化后的开闭端点判断;受控写回只更新选区、不发 `onChange`。选区变化只重算热力样式、光晕和密度权重,几何、背景与标签不重排;没有新增公开实例成员 / options / 数据字段。
167
+ - **回归与文档**:`selftest-features` 新增分段取消 / 受控选择、连续尺区间外的热力门控、密度场重采样、继承鹰眼图同选区与显式 `minimap.heatmap` 独立断言;`selftest-perf` 新增图片背景 + 密度场范围断言、逐条线路中点采样和加法混合管线断言,并把测试等待改成先兑现渲染帧再等图片解码,避免静止画面 `whenRendered()` 挂起。手册 03 / 11 / 13 / 14 / 15、`docs/GisView.md`、类型注释、组件 README、Demo 提示与 API 索引同步。
168
+ - **核心文件**:`src/gis-view/engine.js`、`heatmap.js`、`visual-map.js`、`create.js`、`types.d.ts`、`src/gis-view/README.md`;`docs/manual/03` / `11` / `13` / `15`、`docs/GisView.md`、`docs/demos/gis-view-demo/useGisViewDemo.js`、`panels/StylePanels.vue`、`docs/steps/selftest-features.html` / `selftest-perf.html`、本页与 15.110。
169
+ - **验证**:`npx tsc --noEmit`、`node --check`、`npm run check:docs`、`npm run build`、`git diff --check` 通过;串行自测 `selftest-features` **828/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-perf` **197/0**。性能页此前一次完整运行曾出现既有的标签布局读数断言失败(1313 次),最终复跑未再出现,与本轮改动没有调用关系。
170
+
171
+ ## 六、上三增量:线路热力交互连续显示与 visualMap 自定义交互(2026-10-31)
172
+
173
+ - **需求来源**:根目录 `修改.txt` 三条:① 开启热力图后平移 / 缩放时线路热力先消失再出现;② 继续优化开启热力图后的交互性能;③ 图例支持完全自定义与交互,参考 ECharts `visualMap`。
174
+ - **热力消失根因**:相机移动重铺线路实例时,`buildLineInstances()` 没有写回 `heat`,重铺后强度归零;`LINE_VERTEX_SHADER` 又把 `a_corner.y` 在顶点阶段取了绝对值,插值后整块四边形恒为 1,光晕衰减失效。修复为补 `heat: line.heat ?? 0`,顶点保留带符号 `v_edge`,片元再取 `abs()`。
175
+ - **合并线与性能**:交互 / 相机运动帧由 `HEAT_LINE_FRAGMENT_SHADER` + `heatLineProgram` 一笔同时画本色核与外侧光晕,不增加 draw call;预乘普通混合避免重叠线推白,停稳后仍按配置的 `glow.blend` 两遍绘制。密度场四边形改静态 `heatDensityBuffer`,运动期跳过重烤、停稳补烤;节点光晕交互期让路,线路热力保持连续。
176
+ - **visualMap 交互与自定义**:新增 `interactive`、`selectedMode`、`selected`、`range`、`calculable`、`onChange`、`render(context)`。分段支持点击 / Enter / Space 单选与多选,连续尺支持区间遮罩、双滑块、拖动与键盘;`onChange` 走 rAF 合帧并带 `source` / `reason` / `originalEvent` / `rangeRatios` 等载荷,受控更新不回声。`render(context)` 可返回 DOM / DocumentFragment / HTML 或直接写 `context.body`,复用 `setSelection` / `setRange` / `clearSelection` / `emitChange`;`getVisualMap()` 返回交互状态、选择、区间与比例。
177
+ - **公开面与核心文件**:没有新增实例成员 / options / 数据字段,保持 283 个实例成员(278 方法 + 5 属性)/ 106 options / 274 数据字段。核心文件为 `src/gis-view/shaders.js`、`engine.js`、`heatmap.js`、`visual-map.js`、`create.js`、`types.d.ts`、`gis-view.css`、Demo 组合式函数与样式面板、手册 03 / 11 / 13 / 15 / 16 / 17 / 18、`docs/GisView.md`、`src/gis-view/README.md`、四个自测页、本页与 15.109。
178
+ - **验证**:`node --check` 覆盖着色器 / 引擎 / 热力图 / 图例 / 组件入口 / Demo;`npx tsc --noEmit` 0 错;`node docs/steps/gen-api-index.mjs` 与 `--check`、`npm run check:docs`(283 / 278 / 5 / 106 / 274)、`npm run build`、`git diff --check` 通过;串行自测 `selftest-features` **823/0**、`selftest-perf` **195/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**。
179
+
180
+ ## 七、上四增量:visualMap 图例与图例专用快路径(2026-10-31)
181
+
182
+ - **需求来源**:根目录 `修改.txt` 两条:① 参考 ECharts `visualMap`,增加类似图例并结合 ruler 样式;② 继续优化组件性能。
183
+ - **图例模型**:新增 `src/gis-view/visual-map.js` 与 `options.visualMap`。`ruler` / `continuous` 为连续渐变尺 + 刻度,`piecewise` 为分段色块;支持 `pieces` 的 `gte` / `gt` / `lte` / `lt` / `min` / `max`,以及显式 `domain` / 单端 `min` / `max`、`colors` / `stops` / `opacity`、标题 / 单位 / formatter、方向 / 定位 / 尺寸 / 外部容器 / class / 内联样式。默认继承 `heatmap` 的 target / field / domain / colors / stops / opacity,没有热力图时按自己的 `field` 扫独立值域。
184
+ - **零挂载与读数**:不配 / `null` / `enabled: false` 不挂节点;`getVisualMapElement()` 返回根节点,`getVisualMap()` 返回类型、目标、字段、值域、色带与刻度 / 分段。图例默认 `pointer-events: none`,不参与拾取。
185
+ - **性能快路径**:`heatmap.js` 导出 `createHeatmapRamp()`,图例与画布共用同一套色带插值;更新走 rAF 合帧与渲染签名缓存,同签名零 DOM 写入。数据变化由 `markDataDirty()` 合并到下一帧,图例侧自动值域在本次配置生命周期内复用自身解析缓存;显式 `domain` 或两端都写死的 `min` / `max` 跳过数据扫描。`updateOptions({ visualMap })` 单独走覆盖层快路径,绕过引擎场景、鹰眼图与标签重排;性能页先等待字体队列稳定再计量稳态重排,不放宽已有断言。
186
+ - **Demo 与文档**:热力图面板增加图例开关与连续尺 / 分段选择,Demo 默认跟随热力图字段与色带。手册 03 / 11 / 13 / 15 / 16 / 17 / 18、组件 README、文档中心与自测页同步;实例成员 281 → **283**(方法 276 → **278**,属性仍 5),options 105 → **106**,数据字段 273 → **274**,分组仍 16。
187
+ - **核心文件**:`src/gis-view/visual-map.js`、`heatmap.js`、`create.js`、`gis-view.css`、`types.d.ts`、`src/gis-view/README.md`;`docs/manual/03` / `11` / `13` / `15` / `16` / `17` / `18`、`docs/index.html`、`docs/demos/gis-view-demo/useGisViewDemo.js`、`panels/StylePanels.vue`、`docs/steps/selftest-features.html` / `selftest-perf.html` / `selftest-demos.html` / `selftest-docs.html`、API 索引、本页与 15.108。
188
+ - **验证**:`npx tsc --noEmit`、`node --check`、`node docs/steps/gen-api-index.mjs`、`gen-api-index.mjs --check`、`npm run check:docs`(283 / 278 / 5 / 106 / 274)、`npm run build`、`git diff --check` 通过;浏览器自测 `selftest-features` **808/0**、`selftest-perf` **190/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-demo` **133/0**。
189
+
190
+ ## 八、上五增量:fitSpacing.minDistance 精确落位与指定节点组间距(2026-10-30)
191
+
192
+ - **需求来源**:根目录 `修改.txt` 三条:① `minDistance` 一旦设置就必须精确显示为该屏幕距离,不能因为初始值或内部限制只能变大;② 新增方法,传一组节点返回整组的 `minDistance` / `maxDistance`;③ 文档写明距离如何由坐标与相机比例换算。
193
+ - **根因与修复**:`engine.js` 的 `fitSpacingAdjustment()` 原先把 `minDistance / 最近世界距离` 与普通适应比例取 `Math.max`,再用 `maxZoom` 截断,所以目标比例更小时不生效。现在 `minDistance` 直接作为精确目标比例,可放大也可缩小;`maxZoom` 仅兼容保留,最终只由 `minScale` / `maxScale` 夹取,相机中心仍沿用普通包围盒中心。
194
+ - **指定节点组读数**:新增 `getPointsSpacing(refs)`,refs 支持单个 / 数组、id / 下标 / `{ id }` / `{ index }`;复用引用解析去重,并按传入节点的世界坐标测最近正距离与凸包直径最远距离,再乘当前 `camera.scale` 返回 CSS 像素。与 `getPointSpacing()` 不同,它只统计显式节点,筛选 / 隐藏不影响。
195
+ - **测试与文档**:`selftest-scale` 新增普通适应屏距更大时缩到 `minDistance`、继续改小、`maxZoom` 不截断、指定组去重 / 空输入 / 单节点 / 隐藏节点共 5 条断言。手册 03 / 14 / 16 / 17 / 18 补 `d_world`、`d_screen` 与两种模式的目标比例公式;Demo 移除失效的“最大放大”控件。
196
+ - **公开面与核心文件**:实例成员 280 → **281**(方法 275 → **276**),options 105、数据字段 273、分组 16 不变。核心文件为 `src/gis-view/engine.js`、`create.js`、`types.d.ts`、`src/gis-view/README.md`,以及手册 03 / 14 / 16 / 17 / 18、Demo 面板、`selftest-scale.html`、`selftest-docs.html`、`selftest-demos.html`、API 索引、本页与 15.107。
197
+ - **验证**:`npx tsc --noEmit`、`node docs/steps/gen-api-index.mjs`、`npm run check:docs`(281 / 276 / 105 / 273)、`npm run build`、`git diff --check` 通过;浏览器串行自测 `selftest-features` **794/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-demo` **133/0**;`selftest-scale` **126/2**,新增断言全过,两条失败仍是既有筛选回调时序(`onFilter 0 条`)。
198
+
199
+ ## 九、上六增量:背景文字同帧刷新与 fitSpacing.minDistance 上限修复(2026-10-30)
200
+
201
+ - **需求来源**:根目录 `问题.txt` 两条:① 拖动 GeoJSON 背景仍有晃动,文字尤其明显;② `fitSpacing.minDistance` 有时怎么设置都不生效,`maxDistance` 正常,像是有内部强制限制。
202
+ - **背景文字晃动**:`overlay.setBackgroundLabels()` 会把新的区域文字排到下一帧,而内置背景编辑器的 `applyBackground()` 已经同步重画了 WebGL 底图和编辑框,两者相差一帧。`refreshBackgroundLabels()` 现在立即排版并取消待执行的 rAF;编辑器的 `applyBackground()` 在 `updateBackground()` + `refresh({ reflow: false })` 后同步调用它,底图、编辑框、区域文字同任务提交。
203
+ - **minDistance 根因**:缺省 `maxScale` 是 `20000`,会先把相机比例截住;距离公式本身只按可见节点最近正中心距反推。实测小量纲数据最近世界距离约 `0.00536`,`20000 × 0.00536 ≈ 107.2px`,所以把 `minDistance` 调到 200 / 1000 / 5000 都停在同一屏距。`engine.js` 新增 `DEFAULT_MAX_SCALE = 1000000000`,未配置时使用;显式 `maxScale` 仍优先。
204
+ - **测试与文档**:`selftest-features` 用标准 `FeatureCollection` 生成区域文字,断言 `updateBackgroundEdit({ center })` 返回前 transform 已更新;`selftest-scale` 新增世界距离 `0.01`、目标 `minDistance: 1000` 的用例;`selftest-demo` 与 Demo 面板同步缺省值。手册 03 / 14、`docs/from0/15` 写明缺省上限与「显式 `maxScale` / `maxZoom` 仍会截断」的排查方法,API 索引重生成。
205
+ - **核心文件**:`src/gis-view/engine.js`、`overlay.js`、`create.js`、`types.d.ts`、`README.md`;`docs/manual/03` / `14`、`docs/from0/15`、`docs/demos/api-index.js`、`docs/demos/gis-view-demo/useGisViewDemo.js`、`docs/steps/selftest-features.html`、`selftest-scale.html`、`selftest-demo.html`、`docs/AI对话汇总.md`、本章节、15.106。
206
+ - **验证**:`npx tsc --noEmit` 0 错;`node docs/steps/gen-api-index.mjs` 更新索引;`npm run check:docs` 全绿(280 个实例成员 / 105 个 options / 273 个数据字段);`npm run build` 通过;`git diff --check` 通过。浏览器串行自测:`selftest-features` **794/0**、`selftest-demos` **441/0**、`selftest-docs` **139/0**、`selftest-demo` **133/0**;`selftest-scale` **121 通过 / 2 失败**,新增的默认上限断言通过,剩余两条仍是既有筛选回调时序(`onFilter 0 条`)。
207
+
208
+ ## 十、上七增量:内置背景编辑器与旋转按钮命中修复(2026-10-30)
209
+
210
+ - **需求来源**:根目录 `修改.txt` 两条:① 旋转按钮始终不旋转;② 将整块背景编辑模式内置,通过方法开启与配置,不再由 Demo 纯手写。
211
+ - **旋转按钮根因**:旧编辑层 `.bg-edit-layer` 为 `pointer-events: none`,缩放手柄和轮廓单独恢复 `auto`,但旋转按钮漏了;内置编辑器的旋转按钮显式 `pointer-events: auto`,`selftest-demos` 通过 `document.elementFromPoint()` 验证真实命中后再拖动旋转。
212
+ - **内置编辑器**:新增 `src/gis-view/background-editor.js`;`create.js` 公开 `beginBackgroundEdit(options)` / `updateBackgroundEdit(patch)` / `endBackgroundEdit()` / `getBackgroundEdit()`。支持移动、四角等比 / 八向缩放、可选旋转点、Shift 吸附、`fitView`、编辑框样式与 `onChange` / `onEnd`;图片写回 `image.corners`,GeoJSON 写回 `geoJsonStyle.bounds + rotation`,其它背景字段保留。
213
+ - **生命周期与刷新**:编辑器懒初始化,进入自动打开 `backgroundEditing`、退出恢复进入前的值,实例销毁时清理;无背景时只报 warning。拖动合并到 RAF,帧内 `updateBackground()` + `refresh({ reflow: false })`,底图与编辑层同帧刷新。
214
+ - **Demo 与测试**:`BackgroundDemo.vue` 删除手写拖动、缩放、旋转、投影与 CSS 编辑框,只调用内置 API。新增回归覆盖 4 / 8 / 9 点、旋转真实命中、角度写回、样式实时更新、退出恢复与销毁清理。
215
+ - **公开面**:实例成员 276 → **280**;options 105、数据字段 273、Demo 23 不变。
216
+ - **核心文件**:`src/gis-view/background-editor.js`(新增)、`gis-view.css`、`create.js`、`types.d.ts`;`docs/demos/BackgroundDemo.vue`、`demos.js`、`docs/manual/03` / `14` / `16` / `17` / `18` / `21`、`docs/internals/14`、`docs/steps/selftest-demos.html`、`selftest-features.html`、`selftest-docs.html`、`docs/AI对话汇总.md`、本章节、15.105。
217
+ - **验证**:`npx tsc --noEmit` 0 错;`node docs/steps/gen-api-index.mjs` 更新索引;`npm run check:docs` 全绿(280 个实例成员 / 105 个 options / 273 个数据字段);`npm run build` 通过;`git diff --check` 通过。浏览器串行自测:`selftest-features.html` **793/0**、`selftest-demos.html` **441/0**、`selftest-docs.html` **139/0**。
218
+
219
+ ## 十一、上八增量:背景编辑 4 / 8 / 9 点、旋转开关与可定制编辑框(2026-10-30)
220
+
221
+ - **需求来源**:根目录 `修改.txt` 五条:① 只有开启旋转时才出现旋转按钮;② 取消宽高锁定后从四角编辑改成常见八点,开启旋转后变成九点,并考虑背景旋转角;③ 背景编辑框样式支持自定义;④ 修复移动背景图的轻微晃动;⑤ 全部在 demo 中体现。
222
+ - **编辑点与旋转**:`BackgroundDemo.vue` 锁定比例时显示四角等比缩放;解锁后增加四边中点,共八个缩放手柄;旋转开关独立控制顶部旋转点与连线,只有开启时才从八点变成九点。关闭旋转仍保留当前角度和八个缩放手柄。
223
+ - **旋转后的缩放方向**:缩放手柄均先把指针换算到背景未旋转的局部坐标。角手柄负责局部宽高,锁比例时按相对位移更大的轴推导另一边;四边手柄只改所在边的一个局部轴并固定对边中点。手柄光标方向和边手柄朝向都随背景角度换算。
224
+ - **样式与晃动**:demo 用 CSS 变量控制编辑框颜色、填充、线宽、虚线、手柄尺寸和圆形 / 方形外观;不新增组件 options。指针移动不再同步改输入框和手柄,而是合并到动画帧;帧内先更新背景并立即 `refresh({ reflow: false })`,再同步读数和手柄,避免 WebGL 底图与 DOM 编辑层错开一帧造成晃动。
225
+ - **Demo 与测试**:添加背景后仍自动进入编辑并放回视野;面板新增旋转开关、编辑点计数、颜色 / 线宽 / 虚线 / 手柄尺寸 / 形状控件。`selftest-demos` 覆盖默认 4 点、开旋转 5 点、解锁 8 点、解锁并旋转 9 点、旋转 30° 后的边缩放锚点、样式变量、关闭旋转收起按钮,以及拖动时手柄不抢先和与底图同帧落位。
226
+ - **公开面**:未新增或删除实例成员、options、数据字段与 Demo;保持 276 / 105 / 273 / 23。
227
+ - **核心文件**:`docs/demos/BackgroundDemo.vue`、`docs/demos/demos.js`、`docs/manual/03-配置项.md`、`docs/manual/14-视图与筛选.md`、`docs/manual/21-说明与常见问题.md`、`docs/steps/selftest-demos.html`、`docs/AI对话汇总.md`、本章节、15.104。
228
+ - **验证**:`npx tsc --noEmit` 0 错;`npm run check:docs` 全绿(276 个实例成员 / 105 个 options / 273 个数据字段);`npm run build` 通过(仅既有大 chunk 提示);`git diff --check` 通过。浏览器串行自测:`selftest-features.html` **786/0**、`selftest-demos.html` **440/0**、`selftest-docs.html` **139/0**。
229
+
230
+ ## 十二、上九增量:背景移动 / 旋转、背景编辑模式与网架整体显隐(2026-10-30)
231
+
232
+ - **需求来源**:根目录 `修改.txt` 两条:背景可移动、可旋转;调整背景时网架不能拖拽 / 点击等操作,但可与背景整体缩放,相当于背景编辑模式;Demo 明显有问题。同日上一增量(15.102)已补背景添加、四角调整与网架显隐 / 透明度,本轮补齐移动、旋转、编辑模式并修正 Demo。
233
+ - **背景能力**:`geoJsonStyle.bounds` 负责独立缩放 / 平移到目标世界矩形,新增 `geoJsonStyle.rotation` 绕目标矩形中心顺时针旋转;所有解析几何、区域范围、重心与区域文字一起变换,`rawBounds` 保持原始坐标,`bounds` 为旋转后的轴对齐外框。图片用旋转后的 `image.corners` 表达,不改原始数据。
234
+ - **背景编辑模式**:新增顶层 `backgroundEditing`,走表现型快路。打开后屏蔽画布上的网架悬停、点击、选中、拖拽、平移、框选、右键、数据快捷键与 DOM 标签编辑入口,仅保留滚轮缩放和 `fitView`;网架和背景作为一个整体缩放,数据、选中、历史与相机均不丢。
235
+ - **Demo 修复**:背景添加后自动进入编辑模式并放回视野;支持拖内部移动、四角缩放、顶部圆点旋转、Shift 15° 吸附、±15° 按钮、精确角度输入、适应背景与退出 / 重新进入。编辑层滚轮转发到画布,图片与 GeoJSON 分别写 `corners` 与 `bounds + rotation`;demo 简介和面板文案同步。
236
+ - **文档与计数**:手册 03 / 14 / 16 / 18 / 21、类型声明、API 索引与三页自测同步;options 104 → 105,数据字段 272 → 273,实例成员仍 276,Demo 仍 23。
237
+ - **核心文件**:`src/gis-view/engine.js`、`background.js`、`create.js`、`overlay.js`、`update-policy.js`、`types.d.ts`;`docs/demos/BackgroundDemo.vue`、`demos.js`、`docs/demos/api-index.js`、`docs/manual/03` / `14` / `16` / `18` / `21`、`docs/steps/selftest-features.html`、`selftest-demos.html`、`selftest-docs.html`、`docs/AI对话汇总.md`、本章节、15.102 / 15.103。
238
+ - **验证**:`npx tsc --noEmit` 0 错;`node docs/steps/gen-api-index.mjs` 更新索引;`npm run check:docs` 全绿(276 个实例成员 / 105 个 options / 273 个数据字段);`npm run build` 通过(仅既有大 chunk 提示);`git diff --check` 通过。浏览器串行自测:`selftest-features.html` **786/0**、`selftest-demos.html` **433/0**、`selftest-docs.html` **139/0**。
239
+
240
+ ## 十三、上十增量:交互样式优先级回归、单 / 多要素样式 Demo 与详情查询(2026-10-30)
241
+
242
+ - **需求来源**:根目录 `修改.txt` 三条:① 选中 / 框选 / 多选 / 级联等交互颜色始终最高,不受规则束缚;② 增加修改单个或多个节点 / 线路样式的 demo;③ 查询单个或多个节点、线路、通道详情的写法。用户补充「不考虑分组详情」,因此本轮不扩展分组查询。
243
+ - **交互优先级审计**:核对 `point.js` / `line.js` 的状态样式取值顺序,并确认 `applyPointNarrowFast` / `applyLineNarrowFast` 只在无规则、无热力图且规则输入未变时启用,不会绕过交互层。`selftest-features` 新增单选、动态 override 规则、多选节点 / 线路、框选节点 / 线路与级联共 7 条断言;线路框选仍走 `lineSelectStyle`,没有新增公开选项。
244
+ - **Demo**:`StyleDemo.vue` 增加单条 `updatePoint` / `updateLine`、批量 `patchPoints` / `patchLines`、原始数据恢复、单选 / 多选 / 框选按钮和五种状态色(悬停、单选、多选、框选、级联);详情读数同时展示 `getPoint` / `getLine` / `getChannel` 与 `listPoints` / `listLines` / `getChannels`。`demos.js` 简介同步。
245
+ - **文档**:手册 11 把「改单个节点 / 线路的样式」扩成「改单个或多个节点 / 线路的样式」,补 `patchPoints` / `patchLines` 返回值和交互颜色优先级;手册 18 新增「单条 / 多条要素详情」,覆盖引用写法、`null` / 空数组、批量选项与节点 / 线路 / 通道读数字段,明确分组详情不在本轮范围。
246
+ - **核心文件**:`docs/demos/StyleDemo.vue`、`docs/demos/demos.js`、`docs/manual/11-样式与规则.md`、`docs/manual/18-逐方法示例.md`、`docs/steps/selftest-features.html`、`docs/steps/selftest-demos.html`、`docs/AI对话汇总.md`、本章节、15.101。
247
+ - **验证**:`npx tsc --noEmit`、`npm run check:docs`(276 个实例成员 / 102 个 options / 270 个数据字段)、`npm run build`、`git diff --check` 通过;`selftest-features` **778/0**、`selftest-demos` **415/0**、`selftest-docs` **138/0**。未新增公开 API / options / 数据字段。
248
+
249
+ ## 十四、上十一增量:规则优先级分层、单要素样式说明与解析性能(2026-10-30)
250
+
251
+ - **需求来源**:根目录 `修改.txt` 四条 —— ① 规则样式始终高于外层 `pointStyle` / `lineStyle`,但默认低于要素自身样式;② 单条规则可设置 `override: true`,压过要素自身样式;③ 说明如何修改单个节点 / 单条线路的颜色、尺寸、图标等样式;④ 继续优化组件性能。
252
+ - **优先级口径**:状态样式 / 热力图 > override 规则 > 要素自身样式 > 普通规则 > 外层 `pointStyle` / `lineStyle` > 默认值。普通规则只补要素自身没写的字段,但始终高于外层样式;override 规则写了的字段压过要素自身,未写字段继续回落;同一层后命中的规则覆盖先命中的规则。状态样式与热力图保持最高。
253
+ - **实现方式**:`rules.js` 的 `compileRules(rules, keys)` 编译期预计算每条规则实际写到的 `fields`,新增私有 `RULE_HAS_OVERRIDE` 跳过无 override 时的第二份暂存清理;`point.js` / `line.js` 使用 `ruleScratch` 与 `ruleOverrideScratch` 双暂存逐字段合并。`engine.js` 的整批解析、状态刷新、定向更新、拖拽 / 复制预览、锚点尺寸读数全部接入,`create.js` 的鹰眼图同步同一优先级。`types.d.ts` 的主图与鹰眼图规则类型均增加 `override?: boolean`。
254
+ - **单要素样式文档**:手册 11 新增「改单个节点 / 线路的样式」,覆盖 `updatePoint` 改颜色、尺寸与 `symbol` 图标,`updateLine` 改颜色、线宽与虚线,`patchPoints` / `patchLines` 批量改写,以及线路 `decorations` 逐条替换装饰图标;字段写回 `null` 可摘除覆盖并回落到规则 / 外层样式,无需整份 `updateData()`。
255
+ - **性能与示例**:10 万要素 / 4 条规则 / 9 个样式字段的 Node 微基准,规则合并中位 **21.82 → 17.69 ms**(节省 **4.13 ms**,约 **1.23×**),校验和一致。`StyleDemo.vue` 增加「规则强制覆盖」开关,可把当前预设所有规则临时改为 `override: true`。
256
+ - **核心文件**:`src/gis-view/rules.js`、`point.js`、`line.js`、`engine.js`、`create.js`、`types.d.ts`;手册 11 及 02 / 03 / 07 / 09 / 12 / 13 / 14 / 16 / 17 / 18 / 19 / 20 / 21、格式 02 / 03、internals 10 / 13 / 17 / 18 / 15.100、from0 06、教学页、`src/gis-view/README.md`、`StyleDemo.vue`、`docs/demos/api-index.js`、`docs/AI对话汇总.md`、本章节。
257
+ - **验证**:`npx tsc --noEmit`、`npm run check:docs`(276 / 102 / 270)、`node docs/steps/gen-api-index.mjs`、`npm run build`、`git diff --check` 通过;`selftest-features` 771/0(新增 11 条优先级、override、状态样式、`updatePoint` / `updateLine` 断言),actions 96/0、data 103/0、decoration 75/0、demo 133/0、demos 407/0、docs 138/0、effects 96/0、full 94/0、labels 178/0、select 102/0、selftest 19/0。`selftest-perf` 186/1(既有标签布局读数量测)、`selftest-scale` 120/2(既有筛选回调时序 `onFilter 0 条`),单页重跑仍复现,与本轮样式链无关。
258
+
259
+ ## 十五、上十二增量:updatePoint 快路径、id 索引拆分与插件生命周期(2026-10-29)
260
+
261
+ - **需求来源**:根目录 `修改.txt` 两条:① 继续优化组件性能,包括交互、方法调用等,允许大改;② 提高组件可扩展性和后续可操作性。
262
+ - **updatePoint 快路径**:只有坐标 / id 变化才收集跟随线路,只有节点外框尺寸变化才重排锚定通道;改名称、颜色等业务字段直接补单点槽位,不再扫线路、重排通道或刷新拐点批次。id 改名时先用旧对象解析旧线路绑定,再用新坐标补几何。
263
+ - **id 索引拆分**:点与线路各维护独立 id 索引的版本、来源数组、条数与扫描账本;点更新不重建线路表,单条改 id 只挪一个键。10 万点 / 10 万线 `repeat:updatePoint500:4` 从改前 62.3 / 6.8 / 4.7 / 4.3 ms 降到三次复测的 15.0 ~ 15.4 / 1.8 ~ 2.1 / 1.0 ~ 1.3 / 0.8 ~ 0.9 ms(首段含建点 id 表)。
264
+ - **插件生命周期**:每个插件上下文新增独立 `AbortSignal`、`onCleanup`、`on`、`registerCommand`;卸载顺序为 abort → 旧 `destroy` → 自动清理倒序执行。初始化成功即纳入实例生命周期,初始化后再登记的资源仍会随 `destroy()` 清理;初始化失败也会先 abort 并收起已登记资源。
265
+ - **测试与文档**:`selftest-features` 752 → 760(插件上下文、自动清理、初始化失败、实例销毁、初始化后登记资源);手册 15 的插件示例改为 signal / context 自动清理,并同步 03 / 16 / 17 / 18 与 API 索引;手册 20 记录本轮基准。
266
+ - **核心文件**:`src/gis-view/create.js`、`engine.js`、`types.d.ts`;`docs/manual/03` / `15` / `16` / `17` / `18` / `20`、`docs/demos/api-index.js`、`docs/steps/selftest-features.html`、`docs/AI对话汇总.md`、本章节。
267
+ - **验证**:`npx tsc --noEmit`、`npm run check:docs`(276 / 102 / 270)、`node docs/steps/gen-api-index.mjs --check`、`npm run build`、`git diff --check` 通过;`selftest-select` 102/0、`selftest-demos` 407/0、`selftest-features` 760/0、`selftest-docs` 138/0、`selftest-perf` 187/0。
268
+
269
+ ## 十六、上十三增量:div 保留框跟随、通道单回线显隐与拾取优化(2026-10-29)
270
+
271
+ - **需求来源**:根目录 `修改.txt` 四条:① 框选后保留选框,并支持拖动整框平移选中节点及关联线路 / 通道;② 框选框支持自定义边框、DOM 渲染与类名;③ 节点、线路、通道、分组支持单个 / 批量隐藏与恢复;④ 隐藏线路时可保留原回线位置或让剩余回线重新居中。
272
+ - **本轮续修来源**:根目录 `修改.txt` 三条:① div 保留框移动地图时跟随;② 通道 demo 展示隐藏通道内指定线路;③ 继续优化性能。
273
+ - **改动主题**:新增 `selectionBoxPersistent`、`clearSelectionBox()`、`getSelectionBox()`,保留框拖动按世界坐标增量移动选中节点,选中集变化 / 清空 / 关闭开关 / 手动调用时收起;`selectionBoxStyle` 增加 `render: 'div'`、`className`、`borderStyle`、`radius`。`setFeatureVisible` 的 `kind` 扩到 `group`,分组引用支持通道 + 分组 id / 序号、唯一 id 与 `'selection'`,批量调用保持一条历史、一条 `batch` 变更,结果补 `groups` 快照;隐藏组保留成员、骨架、拐点与归属查询,但不绘制 / 拾取 / 注册锚点。新增 `channelHiddenLineLayout: 'preserve' | 'center'`,并修复隐藏线路恢复后的半跳过渲染状态。
274
+ - **div 保留框与性能**:保留框锚定 `selectionBoxWorld`,渲染帧重新投影,读数和框内命中同步当前相机;DOM 平移只写 `translate3d`,宽高、颜色 / 线型 / 类名分别按尺寸与 `selectionBoxStyleVersion` 缓存。`pick()` / `pickDraggablePoint()` 改为循环外取相机常量、内联投影 + 平方距离比较,去掉逐候选数组与 `hypot`;保留框投影也不再每帧造中间对象。
275
+ - **demo 与测试**:`ChannelDemo.vue` 增加隐藏 / 显示首通道末回线按钮,走 `hideFeatures('line', lineId)`;`selftest-demos` 校验通道分组和成员声明保留、其它回线不受影响;`selftest-select` 新增 div 框随平移 / 缩放重投影的 DOM 与 `getSelectionBox()` 断言。
276
+ - **核心文件**:`src/gis-view/engine.js`、`create.js`、`types.d.ts`、`update-policy.js`、`gis-view.css`;`docs/manual/03` / `08` / `09` / `16` / `17` / `18` / `20`、`docs/internals/18`、`ChannelDemo.vue`、`demos.js`、`gis-view-demo` 面板、`docs/steps/selftest-select.html`、`selftest-demos.html`、`selftest-features.html`、`selftest-docs.html`、`selftest-perf.html`、`docs/demos/api-index.js`、`docs/AI对话汇总.md`、本章节。
277
+ - **验证**:`npx tsc --noEmit`、`npm run check:docs`(276 个实例成员 / 102 个 options / 270 个数据字段)、`node docs/steps/gen-api-index.mjs --check`、`npm run build`(仅有既有大 chunk 提示)与 `git diff --check` 通过;`selftest-select` 102/0、`selftest-demos` 407/0、`selftest-features` 752/0、`selftest-docs` 138/0、`selftest-perf` 187/0。10 万点 / 10 万线基准连续 3 次已记录在手册 20 与 internals 18,拾取保持亚毫秒级,平移 / 刷新受无头环境抖动影响。
278
+
279
+ ## 十七、怎么自己复查
130
280
 
131
281
  ### 1. 先看本次工作区改了什么
132
282
 
@@ -173,4 +323,4 @@ node scripts/run-selftests.mjs selftest-select.html
173
323
  - 组件本体:34 个会话
174
324
  - 选型与立项:2 个会话
175
325
  - 宿主旁支:3 个会话
176
- - 时间跨度:2026-09-15 ~ 2026-10-29
326
+ - 时间跨度:2026-09-15 ~ 2026-10-31