gis-view-webgl2 0.1.7 → 0.1.8
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.
- package/README.md +9 -8
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +232 -228
- package/dist/index.js +1 -1
- package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +49 -0
- package/docs/GisView.md +1 -1
- 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 +48 -0
- package/docs/demos/BasicDemo.vue +2 -2
- package/docs/demos/BatchAddDemo.vue +6 -6
- package/docs/demos/ConnectDemo.vue +164 -33
- package/docs/demos/CopyMergeDemo.vue +27 -14
- package/docs/demos/EventDemo.vue +17 -20
- package/docs/demos/LabelDemo.vue +5 -5
- package/docs/demos/api-index.js +31 -29
- package/docs/demos/gis-view-demo/GisViewDemoCardHeader.vue +1 -1
- package/docs/demos/gis-view-demo/GisViewDemoStage.vue +1 -1
- package/docs/demos/gis-view-demo/panels/DataPanels.vue +1 -1
- package/docs/demos/gis-view-demo/useGisViewDemo.js +31 -33
- package/docs/format/07-/344/272/213/344/273/266/350/275/275/350/215/267/344/270/216/347/244/272/344/276/213/346/225/260/346/215/256.md +8 -7
- package/docs/from0/05-/347/233/270/346/234/272/344/270/216/344/272/244/344/272/222.md +1 -1
- package/docs/from0/07-/351/200/232/351/201/223/345/210/206/347/273/204/344/270/216/345/244/232/345/233/236/347/272/277.md +26 -10
- package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +1 -1
- package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +21 -16
- package/docs/manual/06-/346/225/260/346/215/256/344/270/216/345/234/272/346/231/257/346/233/264/346/226/260.md +9 -10
- 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 +54 -31
- package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +3 -3
- package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +9 -6
- package/docs/manual/10-/351/200/232/351/201/223/347/274/226/350/276/221/344/270/216/346/226/260/345/242/236.md +226 -493
- package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +2 -2
- package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +12 -13
- package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +23 -21
- package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +19 -17
- package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +125 -78
- 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 +1 -1
- package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +2 -2
- 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 -4
- package/docs/steps/README.md +9 -7
- package/docs/steps/bench-scale.html +1 -1
- package/docs/steps/index.html +6 -6
- package/docs/steps/selftest-actions.html +26 -25
- package/docs/steps/selftest-data.html +1 -1
- package/docs/steps/selftest-demos.html +102 -6
- package/docs/steps/selftest-docs.html +3 -3
- package/docs/steps/selftest-features.html +283 -51
- package/docs/steps/selftest-full.html +3 -3
- package/docs/steps/selftest-labels.html +1 -1
- package/docs/steps/selftest-perf.html +31 -4
- package/docs/steps/selftest-select.html +20 -5
- package/docs/steps/step-05-pick.js +4 -8
- package/docs/steps/step-07-channels.js +3 -5
- package/docs/steps/step-08-labels.js +3 -3
- package/docs/steps/step-10-full.js +3 -3
- package/docs/steps/step-12-events.js +41 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
不依赖任何图形库的 WebGL2 矢量视图:点、线、背景层(图片 / GeoJSON)与首屏落位(`initialView`)都通过 `createGisView(dom, options)` 创建,宽高默认跟随传入的 DOM 容器;跨项目复用的视图级逻辑用 `plugins` 挂载。
|
|
4
4
|
|
|
5
|
-
本轮按
|
|
5
|
+
本轮按 `修改.txt` 收紧新增接口:`addChannel` / `addChannelGroupLines` / `joinChannelGroupLines` / `addChannelGroups` / `addChannels` / `addLine` / `addPoint` / `addPoints` / `addLines` 都通过 `options.select` 决定落地后是否选中新要素,缺省不选中;草稿的 `select` 仍只控制点中的节点。程序化线路数据统一走第二段 `lineData`(`lineItems` 已移除),交互入口固定为 `beginAddChannel()` / `beginAddLine()`,`addChannel` 只负责新建通道,`addLine` 走追加式引擎增量路径。旧的 `circuits` / `kind` / `resolution` / `channelId` / `lineItems` 等入参已删除,命中时明确失败且不写数据。公开实例成员保持 **267**(**262** 个方法 + **5** 个属性),options / 数据字段 / 事件 / 功能开关保持 **96 / 250 / 43 / 17**。
|
|
6
6
|
|
|
7
7
|
- 渲染层:原生 WebGL2(GLSL ES 3.00 + 实例化绘制),没有任何运行时依赖,也不需要 Vue。
|
|
8
8
|
- 交互层:拖拽平移、滚轮缩放、按关键字搜索并定位(节点 / 线路 / 通道)、点击 / 双击拾取、点拖拽(相连线路同步移动)、Shift 拖动框选与 Ctrl 点击累加多选(多选后整组同步移动;`selectionKinds` 可限定只选节点 / 线路 / 通道或任意组合)、复制只带选中要素、节点合并可指定保留端并改写最终信息与样式、线路拐点编辑与通道多回线,全部走配置与回调 —— **这些能力缺省全关**,要哪一项显式打开(`features` 预设 / 开关表,或 `interactive: true` / `clickable: true` / `draggable: true` 这类详细配置,见 `docs/GisView.md` 的「功能开关」)。
|
|
@@ -31,7 +31,7 @@ npm run dev
|
|
|
31
31
|
|
|
32
32
|
源码本身就是 JS:`src/gis-view/*.js` 逐文件带中文注释,对外类型集中在 `src/gis-view/types.d.ts`(构建时复制成 `dist/index.d.ts`),不用先编译就能直接读。想照着从零写一遍看 [从 0 到完整的实现](docs/从0到完整的实现.md),里面有一份可以照抄的 mini 实现与验收清单。
|
|
33
33
|
|
|
34
|
-
想知道组件到底有哪些属性和方法:[GisView 文档](docs/GisView.md) 的「实例方法」一节把
|
|
34
|
+
想知道组件到底有哪些属性和方法:[GisView 文档](docs/GisView.md) 的「实例方法」一节把 267 个实例成员(方法 + `el` / `canvas` / `gl` / `cameraAnimating` 这类属性)与 96 个 `options` 键逐个列全;demo 的「视图 · 交互」页签里有同一份清单(`?demo=full`,可搜索、点一条就对当前视图求值);`node docs/steps/check-doc-coverage.mjs` 负责 10 项双向对账,改完源码或文档先跑 `node docs/steps/gen-api-index.mjs` 重生成 demo 读的那一份(三类查询的口径见 [docs/steps/README.md](docs/steps/README.md) 的「怎么查全部属性与方法」)。
|
|
35
35
|
|
|
36
36
|
## 构建 npm 包
|
|
37
37
|
|
|
@@ -126,9 +126,10 @@ const view = createGisView('#map', {
|
|
|
126
126
|
// view.addChannelGroupWaypoint('corridor-1', 'corridor-1::2')
|
|
127
127
|
// view.removeChannelGroupWaypoint('corridor-1', 'corridor-1::2')
|
|
128
128
|
// 右键通道回线:onContextMenu 在 payload.channelContext 里给出「几组 / 当前哪组 / 每组几条回线与可用交互」,点空白 / 节点时没有这份上下文,用它收框
|
|
129
|
-
// onContextMenu:
|
|
129
|
+
// onContextMenu: payload => { const context = payload.channelContext; if (context) view.setCurrentChannelGroup(context.channelId, context.groups[1].id) }
|
|
130
130
|
// view.runChannelAction('add-waypoint', { channelId: 'corridor-1', groupId: 'corridor-1::2' })
|
|
131
131
|
// 新增通道:点两个节点出草稿(onChannelDraft 给两个节点的信息与可选方案),或绕开交互直接加一条
|
|
132
|
+
// 新增通道 / 线路默认不选中;需要时传 options.select: true
|
|
132
133
|
// view.beginAddChannel({ autoCommit: true }); view.addChannel({ from: 'station-a', to: 'station-b' })
|
|
133
134
|
// 定向更新:改一个节点 / 线路 / 通道并重渲染,只重排受影响的那一小片
|
|
134
135
|
// view.updatePoint('station-a', { x: 116.42 }).updateLine('line-a-b', { width: 6 }).updateChannel('corridor-1', { width: 0.2 })
|
|
@@ -261,23 +262,23 @@ view.zoomTo(12).zoomToBounds({ minX: 116, minY: 39, maxX: 117, maxY: 40 }, 60)
|
|
|
261
262
|
- 这一轮(鹰眼图与缩放联动):小图开了「可缩放」之后,空白处拖动可以直接平移小图内容、或拉出矩形框选让主图显示过去(`dragAction` 与 Ctrl / ⌘ 各管一个动作,平移过内容就不再被自动拽回视口框),每一格放大 / 缩小的倍率由 `zoomStep` 单独配(`zoomInStep` / `zoomOutStep` 还能分别覆盖),`channelCircuits: false` 时每个分组按可见成员逐顶点平均出一根居中代表线(多回线挤在小图上只会糊成一片);缩放联动的两组系数分工写明:`pointSizeScale` / `lineWidthScale` 是与地图无关的常数倍数,`pointZoomScale` / `lineZoomScale` 是跟随地图缩放的指数(0 不跟随、1 同倍率),节点尺寸一变,按节点尺寸取宽的通道回线位置跟着走;只有一条回线的通道不再计算回线偏移(回线就是骨架),缩放时的宽度重算与实例重传整块跳过,真实数据里这类通道占大多数。
|
|
262
263
|
- 这一轮(通道分组、鹰眼图规则与定向更新):一条通道不再只能是「一整组」——`splitChannelGroups` 把它拆成多个分组、`mergeChannelGroups` 再并回来,每组回线数自己定、最少一条,拆分出来的新分组不带走拐点、合并进来的线路跟随目标分组的拐点(目标没有拐点就一条都不带),加点 / 拖点只作用于同一分组,分组结果写回 `channels[].groups` 并参与 `getParallelGroups` 的组号;再细到单条回线的 `moveChannelLine` 把某一条回线单独拆成新分组或并进别的分组(两回线拆成两个分组各一条,demo 的右键框里每条回线都有一个「拆成新分组 / 并入第 n 组」的下拉 + 分配按钮,组数 / 回线数到上限时拒绝并给出原因);鹰眼图补上了规则(`pointRules` / `lineRules` 的颜色、半径 / 线宽、形状与层级,不配自己的规则时沿用主图规则的颜色 / 层级,并取主图最终解析出的尺寸与图标,避免小图节点和主图对不上),配合 `levels` 只看某几层、`layered` 控制分层叠画、`pointZoomScale` / `lineZoomScale` 让节点与线路跟着小图倍数放大,底图按层级分箱、按「层级 + 颜色 + 线宽 + 透明度」分桶,绘制次数不随规则数量膨胀;定向更新补上 `updatePoint` / `updateLine` / `updateChannel`:只重解析受影响的那一小片(节点带着绑在它身上的线与锚定通道、线路只重排自己、通道按成员表比对后决定补槽位还是整份重解析),其余要素与缓存一个字节都不动,鹰眼图与标签覆盖层跟着重画。
|
|
263
264
|
- 发散渲染与导出:2 万点以上默认从视图中心向外分帧铺开(`progressiveInit`,铺完前 `isLayoutReady()` 返回 `false`,标签与拾取只看已经画出去的那部分),首屏一帧内先出中心附近的一片;`exportImage({ scale, background, download })` 把画布内容与标签合成一张图导出(返回 data URL,`download: true` 直接下载)。
|
|
264
|
-
- 这一轮(指针事件、连续新增与移除新增):鼠标的每个动作都有自己的回调 —— 悬停 `onHover`、左键单击 `onClick`、双击 `onDblClick`,外加通用的 `onPointerDown` / `onPointerUp`(左 / 中 / 右键按下与抬起)与 `onContextMenu`(每一次右键),后三者发同一种 `GisViewPointerPayload`:命中的要素(`type` / `index` / `item`,通道回线还带 `channelId` / `groupId` / `channelIndex
|
|
265
|
+
- 这一轮(指针事件、连续新增与移除新增):鼠标的每个动作都有自己的回调 —— 悬停 `onHover`、左键单击 `onClick`、双击 `onDblClick`,外加通用的 `onPointerDown` / `onPointerUp`(左 / 中 / 右键按下与抬起)与 `onContextMenu`(每一次右键),后三者发同一种 `GisViewPointerPayload`:命中的要素(`type` / `index` / `item`,通道回线还带 `channelId` / `groupId` / `channelIndex`)与光标位置(`world` / `x` / `y`);按键与修饰键读 `originalEvent`(`button` / `buttons` / `ctrlKey` / `metaKey` / `shiftKey` / `altKey`),空白处 `hit` 为 false,要自己弹菜单就在回调里 `payload.originalEvent.preventDefault()`;新增通道补上「每点一次都回调」的 `onChannelDraftClick`(`step` 为 1 是拿到起点、2 是拿到终点,载荷与 `onChannelDraft` 一致)与连续新增:`beginAddChannel({ continuous: true })` 落地之后草稿原地重开(发 `phase: 'restart'`),接着点下一对节点就能一直加,`continuous: 'chain'` 再以上一段的终点当下一段起点,`continueAddChannel()` 手动开下一段、`cancelAddChannel()` 退出草稿;新增错了用 `removeLine(lineId)` 把刚落地的那条回线摘掉(通道声明一起改,通道空了整条删掉),整条通道走 `removeChannel(channelId)`,两者都会把选中下标跟着往前挪。
|
|
265
266
|
- 性能实测与 WebGPU 的结论见 [GisView 实现原理](docs/GisView实现原理.md) 第 18 章:10 万点 / 10 万线的连续平移,标签全开最初只有 0.8 FPS、关掉标签 10.3 FPS;加上标签候选上限(`label.scanLimit`)回到 36.5 / 48.9 FPS,再把标签图层做成「交互期整体变换 + 停手后重排」,平移 / 缩放 / 拖点分别到 57.9 / 57.9 / 55.0 FPS(与关掉标签同档),整屏框选约 9.9 万个节点从 97 ms 降到 52 ms;整组拖动的增量补丁与圆头欠账见效之后,10 万选中连续拖动每帧 1391 ms → 339 ms;引擎每帧渲染函数耗时一直只有 0.05 ~ 0.2 ms。瓶颈在 DOM 覆盖层与 JS 侧,换 WebGPU 省不到这笔开销,本轮不迁移;这一轮把它收成了 `renderer` 开关(`auto` / `webgl2` / `webgpu`)与 `getRendererInfo()` 读数,真要迁移的路线写在文档里。
|
|
266
|
-
- 搜索与定位和筛选分开:`search()` 只找不藏(可限定 `points` / `lines` / `channels` / `groups`,也认与 `focusOn` 一致的单数别名;通道连回线一起搜并给出 `memberIndex` / `memberLineIndex`,分组命中给 `channelIndex` / `groupId` / `groupIndex`,见 `docs/GisView.md`),**但不再自己动视角** —— 搜到之后要不要聚焦、要不要选中由使用方决定(`GisViewDemo` 的搜索面板就是一个「搜到就聚焦 + 选中」的勾选框);`focusOn(target, options)` 缺省只把中心移到目标上、比例一点不动,`{ zoom: true }` 才按目标范围走 `zoomToBounds` 适配,`
|
|
267
|
+
- 搜索与定位和筛选分开:`search()` 只找不藏(可限定 `points` / `lines` / `channels` / `groups`,也认与 `focusOn` 一致的单数别名;通道连回线一起搜并给出 `memberIndex` / `memberLineIndex`,分组命中给 `channelIndex` / `groupId` / `groupIndex`,见 `docs/GisView.md`),**但不再自己动视角** —— 搜到之后要不要聚焦、要不要选中由使用方决定(`GisViewDemo` 的搜索面板就是一个「搜到就聚焦 + 选中」的勾选框);`focusOn(target, options)` 缺省只把中心移到目标上、比例一点不动,`{ zoom: true }` 才按目标范围走 `zoomToBounds` 适配,`select: true` 顺带选中;节点 / 线路 / 通道 / 分组共用这条适配路径、没有额外放大倍率。`setFilter` 默认只隐藏显示,不删数据、也不清空选中集;显式写 `mode: 'remove'` 才从数据里删除,搜索随后也搜不到被删项。相机另有 `zoomTo(scale, origin?)` 与 `zoomToBounds(bounds, padding?)`。
|
|
267
268
|
- 预览能力:鹰眼图是唯一内置的界面(配 `minimap` 才有,见 `docs/GisView.md` 的「鹰眼图」;底图先铺线、再把节点整层盖上去,节点层级高于线路;小图自己也能套规则:`pointRules` / `lineRules` 给每个节点 / 每条线定颜色、大小与层级,`levels` 只画某几层、`layered` 分层叠画、`pointZoomScale` / `lineZoomScale` 跟着小图倍数放大,没配自己的规则就用主图的颜色与层级),要更自由的实现仍然交给使用方——`getBounds()` 给全量范围、`getViewRect()` 给当前视口矩形,在小画布上按比例画出来并回写 `setCamera()`,需要缩放与框选放大时用 `project` / `unproject` 在两端换算即可。
|
|
268
269
|
- 这一轮(demo 整理、标签显隐规则、全屏与规则更新):demo 页面重新排成「左边画布、右边配置」两列,说明段落默认收起、配置按组折进可折叠面板,画布右上角的「全屏」按钮走 `requestFullscreen()`(进出都等布局稳定后 `view.resize()`,按 Esc 退出也认);节点标签默认只给电压最高的那一档打(阈值取当前数据里最高的 `vn_kv`,new.json / test.json 都是 1050kV),面板上的「显示范围」还能切 ≥525kV 与全部;线路标签默认整个不显示,勾上「显示」之后再按同一套范围展开,打开 demo 不再满屏标签。新增「规则更新」面板:`pointRules` / `lineRules` 可以在文本框里直接改 JSON(或选面板配置 / 单色 / 高电压突出三份预设),点「更新规则并重渲染」把新规则表交给 `updateOptions`,读数里给出规则条数与整份重排耗时 —— 自定义规则生效期间面板上的样式开关不再抢着下发规则。
|
|
269
270
|
- 这一轮(demo 分页与底图、初始视图、插件与三处性能优化):`initialView` 决定首次加载的相机落位(`{ mode, center, scale, zoom, bounds, padding }`,不配仍是适应数据范围),实例方法 `applyInitialView()` 在换数据 / 改配置之后重新套用同一份落位,见 `docs/GisView.md` 的「初始视图」;`plugins: [view => hook]` 是插件挂载点 —— 初始化按数组顺序执行,返回的 `destroy` 在视图销毁时倒序回调,单个插件抛错只走 `onError`,demo 里的 F 键聚焦就是一份完整示例;性能上 `drawGrid` 复用顶点缓冲(范围 / 步长 / 颜色不变就跳过重建)、`onStats` 按新增的 `statsInterval`(默认 250 ms)节流、悬停拾取合并到一帧一次。`docs/steps` 新增第 11 步 `step-11-background.js` 演示背景层 + 初始视图,步骤页工具条上多了「切换底图 / 切换初始视图」两个按钮。
|
|
270
271
|
- 这一轮(背景图与鹰眼图背景):背景层的图片来源扩到「URL / dataURL / `<img>` / `<canvas>` / `<svg>` 元素 / 只给 SVG 路径的 `d` 字符串」(路径会先量外框再包成 SVG,可用 `pathStyle` 上色),摆放除了 `bounds` + `fit`(`contain` / `cover` / `stretch` / `center`,`size` 给原尺寸)之外还能给 `corners` 四个角的世界坐标,按任意四边形做仿射 + 裁剪贴图;GeoJSON 补上 ECharts 风格的 `aspectScale`(默认 0.75,只压经度方向,相机与 `fitView` 仍用缩放前的 `rawBounds` 真实经纬度)、`nameProperty`、`label` 区域文字(开关 / 模板 / 字号 / 字重 / 颜色 / 偏移 / 透明度,位置取区域重心)与 `regions` / `itemStyle(params)` 逐区域配色,填充与描边的颜色、宽度都能逐区域覆盖,`getResolvedBackground()` / `getBackgroundLabels()` 把解析结果暴露出来给自建缩略图或图例用。鹰眼图背景默认继承主视图(`minimap.background: 'inherit'`:底色 / 图片 / GeoJSON 与区域文字一起缩着画,文字字号按比例缩放后夹在 5 ~ 12px),也可以给 `minimap.background` 单独配一份、用 `minimap.backgroundStyle` 显式接管画布底色,或在主视图换背景时自动跟着重画;demo 的「背景来源」下拉把现生成 GeoJSON / 全省 GeoJSON(真实经纬度,`public/全省.geojson`)/ dataURL 图片 / 运行时 canvas / SVG 路径五种来源摆在一起对比,`docs/steps/step-11-background.js` 与三个自测页同步补了断言。
|
|
271
272
|
- 发布前请在 `package.json` 中更新包名、版本号和仓库信息。如果包名已被占用,可以使用 npm 作用域,例如 `@your-scope/gis-view`。
|
|
272
273
|
- 这一轮(坐标转换与鹰眼图范围):新增 `projection.js` 的坐标层 —— `createGeoProjection` 给出「经纬度 ↔ 画出来的世界坐标」(含 `aspectScale`:只压经度、绕整体 bbox 中心,`rawBounds` 给相机、`bounds` 给绘制),`createGeoMapper` 把数据搬到 GeoJSON 上(`mode: 'lngLat'` 完全贴合 / `'fit'` 等比铺进底图 / `'scale'` 按比例,`scale` / `scaleX` / `scaleY` 就是「节点与 geojson 的大小比例」,`mapPoint` / `mapLine` / `mapChannel` / `mapData` 都是复制一份再换坐标);实例方法补上 `getGeoProjection` / `lngLatToWorld` / `worldToLngLat` / `lngLatToScreen` / `screenToLngLat` / `getPointer` / `createGeoMapper` / `mapDataToGeoJson`,`onPointer` 与各类拾取载荷在配了 GeoJSON 底图时给出 `lngLat`。鹰眼图新增 `minimap.extent`(默认 `auto` = 可见数据范围 ∪ 底图范围,GeoJSON 取画出来的 `bounds`、图片取四角 quad):数据与底图不在一个坐标系时小图不再把底图缩成一个点,`data` 是旧行为、`background` 只看底图。demo 的「数据映射」下拉 + 「节点 / geojson 比例」滑块 + 「坐标换算」输入框把这几项摆在一起,`docs/steps/selftest-*.html` 同步补了断言。
|
|
273
|
-
- 这一轮(事件里的选中态、选中集读数与要素、导出数据分四份):`onClick` / `onContextMenu` / `onPointerDown` / `onPointerUp` 的载荷里直接带 `selected`(这一刻在不在选中集里)、`wasSelected`(`onClick` 给「点之前」的那一份,右键与按下 /
|
|
274
|
+
- 这一轮(事件里的选中态、选中集读数与要素、导出数据分四份):`onClick` / `onContextMenu` / `onPointerDown` / `onPointerUp` 的载荷里直接带 `selected`(这一刻在不在选中集里)、`wasSelected`(`onClick` 给「点之前」的那一份,右键与按下 / 松开是「当下」);需要选中集读数时调实例方法 `getSelectionInfo()`(`{ ids, count, points, lines, channels }`,通道回线按通道算一个,按选中集引用缓存),左键分支与右键自建面板也不必再比对 `getSelections()`;`getSelectionData()` 一份读数全给(`ids` / `count` / `pointCount` / `lineCount` / `channelCount`,要素本身 `points` / `lines` / `channels`(数据里的对象引用,通道是选中回线所属通道去重),加上 `items` / `pointIndexes` / `lineIndexes` 与 `bounds`),`onSelectChange` 顶层与 `getSelectionInfo()` 共用同一份口径;导出数据按概念分四份 —— `exportStationData` / `exportPointData`(`new.json` 的 `station_data` 与 `test.json` 的 `point_data`)、`exportLineData`(`test.json` 的 `line_data`,通道回线带 `channel_id` / `channel_name` / `parallel_group_id` 与第几回)、`exportChannelData`(`new.json` 的 `channel_data`,回线折在 `line_data` 列里、路由在 `coords` 列里)、`exportParallelGroups`(`test.json` 的 `parallel_groups`,与通道数据分开取),另有 `exportData({ format: 'view' | 'new' | 'test' })` 一次按口径给整份,见 `docs/GisView.md` 的「导出数据」。
|
|
274
275
|
- 这一轮(标签拖动与编辑、导出分项多选):节点标签与线路标签各多了一对开关 —— `draggable` 让标签自己接住指针(按住挪到别处记成 `offset`,移动节点时偏移照旧叠在节点位移上,位移小于 3 px 算点选),`editable` 时点一下发一条 `labelClick` 把这一条交给使用方;改内容 / 字号 / 颜色走 `updateLabel(kind, ref, patch)`(`style` 是内联样式的增量合并,某项写 `null` 只摘掉这一项覆盖),恢复默认走 `resetLabel` / `resetLabels`,当前记着的逐条状态用 `getLabelStates()` 读出来(按 id 记,换数据不丢),改动都发 `labelChange` 给面板回显,见「标签的拖动与编辑」。导出多了**分项多选**:`exportData({ parts: ['station', 'channel'] })` 选什么导什么(没要的那几份连记录都不生成),选了通道 / 线路会自动带上拐点 —— 通道的路由与线路的折线都靠拐点说话;`exportSelectionData()` 把同一套分项接到「选中的这一撮」上(选中口径与 `exportSelection` 完全一致,出的却是业务表记录),见「导出数据」。
|
|
275
276
|
- 这一轮(大数据交互的性能、bug 排查与 demo 压测):三处「按总量付费」改成「按改动量付费」—— `batch()` 收口筛选(批处理里只记账,收尾统一跑一次 `applyFilter`,标签整层重排 / 提示框 / 鹰眼图也只在收尾各补一次)、筛选投影带缓存(`filter.js` 的 `createFilterProjectionCache`:数据与条件字段没变就复用,单条改动只补那一条的字段 / 坐标 / 两端绑定,点挪了位置还会把绑在它身上的线端点一起重解析,id 变了或数组换了一份才整份重建)、线段网格(`utils.js` 的 `createSegmentGrid`)改成按格线步进登记「真正穿过的格子」(长线只记一条包围盒,查询时先按盒子筛一遍)。实测:20000 点 / 20000 线的筛选开着改 500 个节点(基准页 `docs/steps/bench-filter.html`)从 4687 ~ 6382 ms 降到 152 ms(同一份数据不开筛选是 142 ms),10 万点 / 10 万线 500 次 `pick` 从 3530 ms 降到 164 ms(0.3 ms / 次),10 万级默认全字段 `search` 从每次 30 ms 上下降到首次 80 ms(建缓存)、之后 15 ms 上下。顺带修掉一处真 bug:节点更新时如果它绑着被筛选隐藏的线,补槽位必然失败,于是每次 `updatePoint` 都退化成整份重排 —— 现在只把真的画在场景里的线交给补丁路径。demo 的「开关 · 历史」页多一块**性能压测**(一个按钮量出「500 次逐条 `updatePoint` / 500 次 `batch()` / 500 次 `pick` / 5 次 `search`」,附 `getStats()` 读数,跑完数据回到原处),「数据 · 通道」页的导出样例改成一有数据变更就自动刷新。新增自测页 `docs/steps/selftest-scale.html`(26 条断言 + 4 条耗时 DIAG)与基准页 `docs/steps/bench-filter.html`(上面那些数字就是它量出来的),详见 `docs/GisView.md` 的「批量更新」与「大数据量」、`docs/GisView实现原理.md` 的 16.6 / 16.7。
|
|
276
277
|
- 这一轮(线路标签拖动飞走 / 鹰眼图之后标签消失 / 热力图观感 / 配置更新的快速通道):修掉两处真 bug —— 线路标签拖动时每一步都把「落点 + 本次偏移」的结果写回排版基准,分 5 步拖 50px 会被算成 10+20+30+40+50 = 150px(看着就是标签自己飞走),现在拖动期间只刷新文本,落点始终从锚点重算;两层标签同时被 `hideOnInteract` 收着时,停手的收尾计时器挂不上、图层再也回不来(「移动一次鹰眼图,线路标签全消失」就是这条),现在收尾无条件挂上,180 ms 内恢复。热力图:光晕的渐隐改成按符号自己的距离场走(圆符号与过去逐像素等价,方 / 圆角方形不再一律套一个圆点 —— 这是「有的圆有的棱形」那一半观感的来源),密度场的透明曲线指数 0.45 → 0.8(核外更透、热核更实、外缘不再发灰)。性能:`updateOptions` 的快速通道扩到纯标签 / 提示 / 根样式(这类补丁引擎一个字节都收不到,只刷覆盖层;小图配置变更顺带作废组件这一层的小图数据缓存)与状态样式 / `defaultHighlight`(只重解析在悬停 / 选中里的那几个要素)—— 10 万点 / 10 万线的合成数据里,`updateOptions({ label })` / `{ tooltip }` / `{ ariaLabel }` / `{ statsInterval }` / `{ initialView }` / `{ pointSelectStyle }` / `{ defaultHighlight }` / `{ selectionBoxStyle }` 从 82 ~ 120 ms 降到 0 ms(改 `pointStyle` 这种真重排仍是 116 ms 上下),8 个用例在「快速通道」与「强制整份重排」两条路上的截图逐像素相同;`selftest-labels.html` 新增「拖动逐步核对」段(分 5 步拖、合计 -50px,每一步的漂移必须为 0)。见 `docs/GisView.md` 的「标签的拖动与编辑」「线路标签」「鹰眼图」「热力图」「大数据量」与 `docs/GisView实现原理.md` 的 15.34。
|
|
277
278
|
- 这一轮(样式更新的快路径 / 面板收进弹层 / 常用读数与定位的实例方法):`updateOptions` 又多了一条快路 —— `pointStyle` / `lineStyle` / `pointRules` / `lineRules` 这些「只换外观、不动几何」的补丁由引擎里的 `isStyleOnlyPatch` 认出来,逐要素按新配置重解析后覆盖到实例槽位上(数据包围盒、背景、通道骨架与装饰锚点都不重算,只有贴图换批次 / 阴影条数 / 绘制层级 / 虚线图案变了才回退整份重排),10 万点 / 10 万线下一次 `pointStyle` 从 109 ~ 116 ms 降到 40 ~ 55 ms,两条路画出来的截图逐像素相同。上手成本这一轮主要花在「少写循环」上:实例上新增 `getPoint` / `getLine` / `getChannel`(按 id / 下标取一个要素)、`listPoints` / `listLines`(按 `indexes` / `inView` / `limit` / `withScreen` / `visibleOnly` 列快照)、`getElementBounds` 与 `focusOn`(一批要素的包围盒 + 把视角挪过去,`{ center: true }` 只居中、`select: true` 顺带选中)、`getViewState` / `getContextAt`(一次取全读数,自建状态栏与右键菜单各调一个就够),见 docs/GisView.md 的「实例方法」与「常用读数与定位」。demo 也从「一长串折叠面板」改成「一排按钮 + 弹层」:点按钮或右键按钮弹面板,Esc / 点别处 / 点画布都能收(点画布那一下不吞事件),切页签时按钮跟着换,画布上右键空白处弹出「画布菜单」(定位到选中 / 聚焦命中的那一个 / 适应视图 / 读一下选中集 / 导出选中的图 / 导出选中的数据 / 清空选中 / 切底图,每一行都是一个公开方法),并新增「实例方法速查」面板当场调一次新方法看返回值;`docs/steps/selftest-demo.html` 补了一批断言覆盖弹层开关与画布菜单。
|
|
278
279
|
- 这一轮(新加标签的交互 / 标签事件的所属父级 / 右键默认收系统菜单 / 数据格式里的标签):`addLabel` 加的标签与配置、数据里声明的走同一条路 —— `label` / `lineLabel` 上打开 `draggable` / `editable` 之后它照样能拖能点(逐条没写就跟着这一类的缺省走,写 `false` 单独关掉这一条),位置现给就行(节点标签是八向 `top` / `bottom` / `left` / `right` 与四个斜角加 `center`,线路标签是沿线 0 ~ 1 / 百分比 / 距离);「一开始就显示几条」把数组写进 `label` / `lineLabel`,或者把 `labels` 写进数据都行,两种写法都跟着数据走。`labelClick` / `labelDrag` 的载荷新增两份现成读数:`label`(这一条标签的 `id` / 当下文本 / 合并后的 `position` 与 `style` / `source` 是配置、数据还是运行时加的 / 运行时那一份的 `definition`)与 `parent`(`type` / `index` / `id`,线路在通道里时 `channel` 给 `{ id, groupId, index, slot, item }` —— 点的是哪条通道的哪一回线直接读);引擎为此补了 O(1) 的 `getLineChannel(index)`。右键默认把浏览器的系统菜单收掉(`preventContextMenu` 缺省 `true`:接住右键时一律 `preventDefault()`,点 / 线 / 空白 / 通道都一样),想留系统菜单写 `false`,关掉 `contextMenu` 开关也等于组件不接右键。demo 的「数据 · 通道」页新增两块标签格式样例(节点上的 `point_data[].labels` 与通道里的 `channel_data[].line_data[].labels`,`printDataShape()` 的完整结构也带上 `getLabels()` / `getLabelStates()`),「样式 · 标签」页的「加一条标签」多了位置下拉与「初始标签」(给前 3 个节点各写 4 条上下左右的 `labels`,一条 `label` 配置不写也画得出来)。点选 / 拖动的读数(这一条标签的 id / 内容 / 来源,挂在哪条要素 —— 线路在通道里时连通道 / 分组 / 第几回)在 demo 面板点一下就直接排出来,`getLabels()` 的每一条也补了同一口径的 `source`。
|
|
279
|
-
- 这一轮(指针事件的动作判读 / 只读查询与数据增补的实例方法 / 滚轮缩放的连续手感):画布上的每一条指针事件都多了一份 `action` 读数 —— `type` 说「这一次是什么操作」(按下时是意图 `dragPoint` / `dragWaypoint` / `boxSelect` / `pan` / `copy` / `channelDraft` / `contextMenu` / `click`,松开时是刚做完的那件事,点击与右键是真正发生的那一件:`select` / `clearSelection` / `toggleSelect` / `addWaypoint` / `removeWaypoint` / `selectWaypoint` / `contextMenu` / `dblClick` / `click`),`target` 说点在什么上面(`point` / `line` / `channel` / `empty`,通道回线单独给 `channel` 而不是混在 `line` 里),`moved` 说明按下之后有没有真的拖动、`double`
|
|
280
|
-
- 这一轮(左右键事件的参数与判读 / 程序化悬停 /
|
|
280
|
+
- 这一轮(指针事件的动作判读 / 只读查询与数据增补的实例方法 / 滚轮缩放的连续手感):画布上的每一条指针事件都多了一份 `action` 读数 —— `type` 说「这一次是什么操作」(按下时是意图 `dragPoint` / `dragWaypoint` / `boxSelect` / `pan` / `copy` / `channelDraft` / `contextMenu` / `click`,松开时是刚做完的那件事,点击与右键是真正发生的那一件:`select` / `clearSelection` / `toggleSelect` / `addWaypoint` / `removeWaypoint` / `selectWaypoint` / `contextMenu` / `dblClick` / `click`),`target` 说点在什么上面(`point` / `line` / `channel` / `empty`,通道回线单独给 `channel` 而不是混在 `line` 里),`moved` 说明按下之后有没有真的拖动、`double` 说明是不是双击里的第二下;原始输入不重复打包 —— 鼠标键 / 修饰键 / 浏览器坐标都读 `originalEvent`(`button` / `buttons` / `ctrlKey` / `metaKey` / `shiftKey` / `altKey` / `clientX` / `clientY`),命中的数据直接放载荷顶层:节点 / 线路读 `item`、通道回线读 `channel` / `channelContext`、空白是 `null`;不再有 `action.button` / `action.modifiers` / `action.data`—— 「右键点空白才弹菜单」「拖完的是节点还是拐点」「点的是通道的第几回」因此都是一次 `switch (payload.action.type)` 的事。标签事件同一套写法(`target: 'label'`,标签与父级读顶层的 `label` / `parent`);选中集变更也带 `action`(`select` / `toggleSelect` / `boxSelect` / `clearSelection`),引擎的 `onSelect` 多给一个 `detail` 参数(载荷为 `null` 时靠它分辨这一下是框选还是 Ctrl 取反,`originalEvent` 与修饰键都在里面)。查询与增补补了一批实例方法:`pickAt(clientX, clientY)` 按鼠标事件坐标问「这儿是什么」(与指针载荷同一份结果再加 `target` / `lngLat`,只读、不改选中不动光标)、`getFeaturesInRect(rect)` 按画布矩形列出框里的节点与线路(与框选同一套判定,另给这块像素对应的 `worldRect`)、`getChannelsInView()` 数当前视口里的通道(同一通道的多回线只算一条,带 `lineIndexes` / `groupIds`),`addPoint` / `addPoints` / `addLines` 把现成对象追加到数据末尾(老数据下标一个都不动,返回 `{ ok, count, indexes, items }` 并发一条 `addPoints` / `addLines` 数据变更),`removeLines` 一次删多条线路(通道声明与分组跟着收拾、删空的通道整条走)。性能做在「每次按下少跑一趟」上:拖拽起手直接复用按下那一次的拾取结果(`resolveDragIndex`),省掉一次点网格查询与一次拐点扫描;滚轮缩放从「一格一档」改成按 `deltaY` 的量连续缩放(100 像素 ↔ 1.12 倍,触控板的小步进因此是一路平滑的),`deltaMode` 为行 / 页的设备先折算成像素、单次再夹在 240 像素以内。可上手性:`docs/steps/` 新增第 12 步 `step-12-events.js`(一边点一边把 `action` 逐字段打在页面上,工具栏的「框内有什么」调 `getFeaturesInRect`),新增自测页 `docs/steps/selftest-actions.html`(67 条断言逐条覆盖上面这些读数),事件演示页(`?demo=events`)也补了一栏「动作判读」与 `pickAt` / `getFeaturesInRect` 两个方法按钮,`docs/GisView.md` 新增「action:一次操作的判读」一节与五个实例方法的说明。
|
|
281
|
+
- 这一轮(左右键事件的参数与判读 / 程序化悬停 / 批量打补丁与删除选中):指针回调统一为一个参数 `payload`;`action` 只保留操作判读(`type` / `target` / `moved` / `double` / `press` / `duration` / `longPress`)。松开与点击载荷里的 `press` 仍是**按下时的意图**(与那一刻 `onPointerDown` 的 `action.type` 同一份)、`duration` 是按了多久(毫秒)、`longPress` 是超过 500ms 且中间没拖动过(触摸 / 触控笔按它出菜单)。鼠标键名 / 数字、修饰键与 `clientX` / `clientY` 一律读 `payload.originalEvent`(`button` / `buttons` / `ctrlKey` / `metaKey` / `shiftKey` / `altKey` / `clientX` / `clientY`),不再有 `action.button` / `action.modifiers` / `left` / `right` 与载荷顶层坐标。**中键按住就是临时平移**(`payload.originalEvent.button === 1`、`action.type` 是 `pan`,按住拖动平移、松开结束,不经过 `onClick`、也不改选中);悬停载荷(`GisViewHoverPayload`)带 `action.type: 'hover'` / `target` 与光标位置(`x` / `y` / `world`),只有光标停在最近一次真实指针事件的位置上时才带 `originalEvent`,程序化悬停没有这一份。方法侧补四条路:`hoverAt(clientX, clientY)` / `clearHover()` / `getHover()`(程序化悬停:让指针「停」到某个位置,高亮、光标与 `onHover` 一起更新、读数与 `onHover` 同一份 —— 外部列表 / 表格 hover 到某一行时联动高亮图上的要素用它,`docs/steps/` 第 12 步工具栏的「程序化悬停」按钮就是这么接的),`getSelectionData().bounds`(选中集的世界包围盒,没选中或数据换过是 `null`),`patchPoints(entries, patch?)` / `patchLines(entries, patch?)`(批量打补丁:`[{ id: 'a', name: 'A' }, { index: 3, x: 10 }]` 一次改几条,或 `['a', 'b']` 配一份公共补丁盖一批,认不出来的进 `skipped`,只记一条历史、只发一条 `updatePoints` / `updateLines`),与 `removeSelected(options?)`(删掉当前选中的那一批:节点连同绑在它们身上的线路、剩下的选中回线一起删,删完清空选中,返回点 / 线的 ids 与下标、连带删掉的通道数 —— 工具栏「删除选中」就是它,一次调用只落一条历史、只发一条 `removeSelected` 数据变更)。性能与交互:`getSelectionInfo()` 按选中集引用缓存(右键菜单 / 状态栏按需读;指针与悬停载荷不再挂这份读数)、`onSelectChange` 的去重从拼字符串签名换成 Set 比对、批量补丁与删除选中各只落一条历史与一条数据变更。**`updatePoints(points)` / `updateLines(lines)` 的整份替换语义保持原样** —— 批量补丁因此另起名 `patchPoints` / `patchLines`,两套各管一件事(老接口换整份数据、新接口只动点到的这几条)。
|
|
281
282
|
- 这一轮(数据格式成文、筛选简写与 `optionChange`、几个 demo 的交互修正):新增 [数据格式](docs/数据格式.md) —— 节点 / 线路 / 通道 / 标签 / 拐点分组逐字段一张表(`x` / `y` 必填、`id` 是引用键、图上回线也是普通线路)、条件语法与运算符表、四套导出格式(`view` / `new` / `test` / 新增的 `input` 回灌口径:`exportData({ format: 'input' })` 给当前数据副本,`updateData` + `updateOptions` 直接喂回去就回显)、事件载荷速查(指针 / 命中、选中集、标签、读数)与示例数据说明。筛选补上简写:`setFilter({ vn_kv: { gte: 525 } })` 等价于 `{ points: { vn_kv: { gte: 525 } } }`(顶层出现 `points` / `lines` / `cascade` / `worker` 任一键才按完整格式解释),完整格式里多写的顶层键走 `onWarning` 点名提醒、不再静默失效;`normalizeFilter` / `FILTER_FORM_KEYS` 一并导出,交给组件之前可以先自查同一套口径。配置变更多了一条统一出口 `onOptionChange`(`updateOptions()` 每改一次发一条:`keys` / `replace` / `changed`(含 `style` / `presentation` 两个快路径归类)/ 合并后的 `options`),外部面板跟组件状态同步不必自己再包一层 `updateOptions`。实例方法补 `isSelected(ref)`(id / 下标 / `{ type, index }` 问「这个要素在不在选中集里」)与 `getLineChannel(ref)`(这条回线属于哪条通道、哪一组:`{ lineIndex, channelId, channelIndex, channel, groupId, group }`)。读数侧:`getStats()` 新增 `idle`,静止画面按需渲染时报「空闲 + 最近一帧耗时」而不是 0.3 fps 这种假帧率,帧率窗口空闲超过 200ms 后断开重算;`emitStats` 的节流初值改成 `-Infinity`,首帧一定报一次(页面打开 200ms 内画完的那一帧原来会被节流掉,静止之后又不再画帧,面板读数就一直空着)。demo:`PerfDemo` 的电压筛选原来传的是扁平条件(库只认 `points` / `lines`,条件被静默忽略,看着就是筛选不生效),改用 `points` 完整格式并抽出 `voltageFilterInput()`;`EventDemo` 的总线订阅补拆 `{ payload, event }`(右键动作读数不再是「—」)、标签载荷认 `{ label, parent }`、方法栏补选中集 / 可见数据 / 导出读数;`LabelDemo` 不再让「点选标签」改写批量操作的目标 labelId(批量改 / 删原来会落到 `default` 上)、三个「加一条」按钮各自记住新建的 labelId、`cyclePosition` / `toggleHidden` 回写命中读数并新增 `labelStatesText` 汇总;`ChannelDemo` 的分组操作一律按 `channelId`(拆分后 `getChannels()[0].id` 是分组 id,第二次「每回线拆一组」原来会空转)、导出读数区分输入侧通道分组与视图侧拐点分组;`StyleDemo` / `BasicDemo` 的读数行与 `GisViewDemo` 的初始读数修正(`onReady` 在 `createGisView` 返回之前触发,依赖实例的读数必须放到创建之后)。回归:仓库 9 个自测页全部通过、7 个 demo 的点击 / 滚轮 / 框选 / 读数 / 控制台逐页跑通(`PerfDemo` 2000 点筛 `≥1050 kV` 得 500 点 / 99 线)。另外把内置鹰眼图的容器改成按需挂载:没配 `minimap`(或 `enabled: false`,以及功能开关把 `minimap` 关掉)时一个节点都不进 DOM,运行时再配上会当场补挂上,`destroy()` 之后宿主里不留东西 —— 与文档里「不配则不产生任何 DOM」的承诺一致(此前无论配不配都会先挂一层隐藏容器)。
|
|
282
283
|
- 这一轮(数据格式补全拐点 / 标记 / 偏移与颜色样式、`input` 口径带 `labelStates`、拖拽落点新演示、逐要素细粒度方法与选中高亮的修正):[数据格式](docs/数据格式.md) 补上缺的几节 —— 「拐点」把三处写法(线路 `path` 的中间顶点、通道 `channels[].path` 骨架、分组的 `groups[].path`)与读写接口(`getWaypoints` / `addWaypoint` / `removeWaypoint` / `setLineWaypoints` / `setChannelPath` / `addChannelGroupWaypoint`)以及导出形状(`parallel_groups` 的 `group_route` 含两端、`input` 折在 `path` 里)摆进一张表,「标记 / 装饰」把 `lines[].decorations` 逐字段写清(`position` 的四种写法、`anchor` 的 auto / follow / fixed、`at` 优先、`parallel`、`size` / `color` / `strokeColor` / `strokeWidth` / `opacity` / `shadow`),再补一节「偏移与颜色样式」说明「标签 `offset` 是像素、标记 `position` 是沿线、`at` 是世界坐标」与「全局 → 规则 → 要素自身 → 状态 → 热力图」的覆盖顺序;标签一节补上「编辑结果不在数据对象里」这件事:新增 `options.labelStates` 与 `updateOptions({ labelStates })` 回灌,`exportData({ format: 'input' })` 的结果多一列 `labelStates`(与 `getLabelStates()` / `setLabelStates()` 同一份形状,`labels: false` 时不带,`counts.labelStates` 报条数)—— 数据支持的格式与导出的格式因此对上,「存档 → 回灌」两步就能完整回显。逐要素改法补一批实例方法(19 个):`setPointSize` / `setPointSymbol` / `setPointColor` / `movePoint` / `setLineWidth` / `setLineColor` / `setLineWaypoints` / `getLineDecorations` / `setLineDecorations` / `addLineDecoration` / `updateLineDecoration` / `removeLineDecoration` / `setChannelWidth` / `setChannelNodeWidth` / `setChannelInset` / `setChannelTangentInset` / `setChannelLineWidth` / `setChannelColors` / `setChannelPath` —— 一个方法只改一样东西(大小 / 图标 / 颜色 / 拐点 / 标记 / 通道宽度与配色),走的还是定向更新那条路:只重排受影响的一小片、只发一条数据变更、只落一步历史,要素没找到只记一条 warning 不抛错;通道那两个「成员回线 + 通道声明」一起改的(线宽 / 配色)包在一个 `batch` 里,只发一条数据变更。新增演示「拖拽落点」(`docs/demos/DragDropDemo.vue`,页签 `?demo=drag`):左侧看板 7 个图标直接拖到画布上 —— `dragstart` 写自定义 MIME + `text/plain` 兜底,`drop` 用 `getContextAt` 一次取全(世界坐标 / 命中要素 / 选中集)先出草稿(这一步数据一个字节不动),「确认添加」才按类型调 `addPoint` / `addLines` / `createChannels + addLines + updateOptions` / `addWaypoint` / `addLineDecoration` / `addLabel`,「取消添加」或 Esc 丢掉草稿,两条路都进事件日志(`dataChange` / `waypointChange` / `labelChange` / `selectChange` 都订阅了);落点正好压在节点上会拉出两端重合的退化线,这里按 6px / 相机比例拦一条提示;面板上的「微调最后一条」把上面那批细粒度方法摆成按钮,「存档 → 重建」用 `exportData({ format: 'input' })` + `labelStates` 走完整回灌。修正 `StyleDemo` 的「选中高亮」完全没效果:它把样式对象传给了布尔开关 `defaultHighlight`(`=== true` 才算开),现在按「有样式对象就用它、没有才退回内置强调」,`create.js` 的 `warnOptionValues` 也会对这类值提醒一句。类型侧 `types.d.ts` 补 `GisViewOptions.labelStates`、`GisViewExportDataResult.labelStates` 与这 19 个方法的签名;自测页 `selftest-demos.html` 的页签断言改成 8 个并新增两条拖放断言(拖进去先出草稿、确认才落地)。回归:`npx tsc --noEmit`、9 个自测页 720 条断言、`t35` / `t50` / `t54` / `t55` / `t58` 全部通过。
|
|
283
284
|
- 这一轮(三份完整样本数据、演示页「完整样本」与数据格式的一处澄清):仓库根目录新增 `sample-labels.json` / `sample-waypoints.json` / `sample-channels.json` —— 三份都是与 `exportData({ format: 'input' })` 同构的完整样本(`points` + `lines` + `channels` + `labelStates` 四列,拿来就能当 `createGisView` 的入参),把标签(八向位置、沿线的比例 / 百分比 / 距离、旧式 `lineLabel*` 写法、`field` / `html` / `className` / 内联样式与像素偏移)、拐点(`lines[].path` 的中间顶点与通道 / 分组骨架各一份)、分组(`channels[].groups` 各带自己的骨架拐点)、标记(`decorations` 的比例 / 百分比 / 距离 / 世界坐标四种定位与圆 / 方 / SVG / 图片四种符号,外加 `parallel` / `opacity` / `shadow`)、偏移(标签 `offset`、标记 `position` / `at`)与颜色样式(逐点 `symbol` / `strokeColor`、逐线 `color` / `width` / `lineType`、通道的逐回配色与线宽 / `nodeWidth` / `offsetMode` / `inset` / `tangentInset`)摆齐,`labelStates` 里还带着拖过的偏移、改过的内容与样式、运行时加的标签。新增演示页「完整样本」(`docs/demos/SampleDemo.vue`,页签 `?demo=samples`):三份切着看,「与文件对一遍」用 `exportData({ format: 'input' })` 与文件逐字节对账,「按导出重建」演示完整的存档 → 重建回显,读数把拐点 / 标记 / 标签状态 / 画布上的标签数量摊开。文档侧 [数据格式](docs/数据格式.md) 的「拐点」一节补上最容易踩的一条:**线路的 `path` 是整条折线,首尾两个顶点是端点**(绑了 `from` / `to` 时被节点坐标替换),只写中间那几个点会被首尾替换掉、直接退化成两端直连 —— 通道 / 分组骨架反过来只写中间拐点,两种写法各配一段可以直接抄的 JSON;「示例数据」一节列出三份样本与各自包含的字段。回归:`npx tsc --noEmit`、`npm run build`、`npm run build:lib` 通过,9 个自测页 725 条断言全绿(`selftest-demos.html` 的页签断言改成 9 个并新增 3 条样本断言),9 个演示页逐页点按 0 warning / 0 error(`full` 那条「未知配置项 qualty」是它故意留的配置提醒),新增的样本校验脚本对三份 JSON 断言 25 条(条数 / 拐点 / 标记 / 标签状态 / `parallel_groups` 含两端 / 导出回灌逐字节一致)全过。
|