gis-view-webgl2 0.1.4 → 0.1.6
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 +10 -7
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +225 -20
- package/dist/index.js +1 -1
- package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +109 -0
- package/docs/GisView.md +53 -53
- 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 +91 -0
- package/docs/demos/ConnectDemo.vue +114 -3
- package/docs/demos/MinimapDemo.vue +216 -17
- package/docs/demos/SearchFilterDemo.vue +113 -1
- package/docs/demos/api-index.js +28 -20
- package/docs/demos/demos.js +1 -1
- package/docs/demos/gis-view-demo/GisViewDemoStage.vue +25 -16
- package/docs/demos/gis-view-demo/useGisViewDemo.js +27 -16
- package/docs/index.html +3 -3
- package/docs/internals/13-/351/271/260/347/234/274/345/233/276.md +8 -5
- package/docs/internals/16-01-/344/274/230/345/214/226/344/270/216/345/217/226/350/210/215-/344/270/212.md +18 -5
- package/docs/internals/16-03-/344/274/230/345/214/226/344/270/216/345/217/226/350/210/215-/344/270/213.md +11 -1
- 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 +73 -1
- package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +14 -5
- package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +2 -2
- package/docs/manual/05-/347/224/273/350/264/250/344/270/216/346/211/271/351/207/217/346/233/264/346/226/260.md +1 -1
- package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +1 -1
- 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 +423 -3
- package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +99 -30
- package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +12 -7
- package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +14 -6
- package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +137 -6
- 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 +4 -0
- package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +8 -3
- 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 +6 -3
- package/docs/steps/README.md +6 -6
- package/docs/steps/selftest-demos.html +252 -9
- package/docs/steps/selftest-docs.html +3 -3
- package/docs/steps/selftest-full.html +357 -13
- package/docs/steps/selftest-perf.html +599 -382
- package/package.json +1 -1
|
@@ -4,8 +4,8 @@ const {
|
|
|
4
4
|
containerRef, stageRef, isFullscreen, fullscreenSupported, toggleFullscreen, viewRef, selectionCount, stats,
|
|
5
5
|
qualityBadge, cursorText, hostZoom, zoomText, pointerText, screenText, lngLatText, canvasMenu, closeCanvasMenu,
|
|
6
6
|
canvasMenuStyle, canvasMenuRows, runCanvasMenuAction, pointSizeScale, lineWidthScale, minimapSize,
|
|
7
|
-
minimapEnabled, minimapShowLines, minimapExtent,
|
|
8
|
-
minimapZoomStep, zoomMinimap, minimapRuleMode, minimapLayered, minimapLevels, minimapCascade, minimapPointSize,
|
|
7
|
+
minimapEnabled, minimapShowLines, minimapExtent, minimapExtentFollowCamera, minimapZoomMode, minimapFollowZoomScale,
|
|
8
|
+
minimapDragAction, minimapChannelCircuits, minimapZoomStep, zoomMinimap, minimapRuleMode, minimapLayered, minimapLevels, minimapCascade, minimapPointSize,
|
|
9
9
|
minimapLineWidth, minimapPointZoom, minimapLineZoom, minimapPointMapZoom, minimapLineMapZoom, minimapBoxFill,
|
|
10
10
|
minimapBoxFillOpacity, minimapBoxStroke, minimapBoxStrokeWidth, minimapBoxStrokeStyle, minimapBoxRadius,
|
|
11
11
|
minimapDrawLayer, minimapSummary, minimapLayerOptions, heatDensityText, channelMenu, closeChannelMenu,
|
|
@@ -105,6 +105,10 @@ const {
|
|
|
105
105
|
<option value="data">范围:只看数据</option>
|
|
106
106
|
<option value="background">范围:只看底图</option>
|
|
107
107
|
</select>
|
|
108
|
+
<label class="demo-minimap-switch" title="extent=auto 时是否允许范围随相机收窄;默认关,避免包围盒与视口框自己跳">
|
|
109
|
+
<input v-model="minimapExtentFollowCamera" type="checkbox" :disabled="!minimapEnabled || minimapExtent !== 'auto'" />
|
|
110
|
+
范围跟相机
|
|
111
|
+
</label>
|
|
108
112
|
<label class="demo-minimap-switch">
|
|
109
113
|
<input v-model="minimapEnabled" type="checkbox" />
|
|
110
114
|
鹰眼
|
|
@@ -117,22 +121,27 @@ const {
|
|
|
117
121
|
<input v-model="minimapChannelCircuits" type="checkbox" />
|
|
118
122
|
回线
|
|
119
123
|
</label>
|
|
120
|
-
<
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
<select v-model="minimapZoomMode" :disabled="!minimapEnabled" title="缩放模式:关闭 / 手动缩放小图 / 整体范围跟随主图;手动与跟随互斥">
|
|
125
|
+
<option value="off">缩放:关闭</option>
|
|
126
|
+
<option value="manual">缩放:手动</option>
|
|
127
|
+
<option value="follow">缩放:跟随主图</option>
|
|
128
|
+
</select>
|
|
129
|
+
<select v-model="minimapDragAction" :disabled="!minimapEnabled" title="小图空白处拖动的动作:pan 平移小图内容(需手动缩放),box 直接框选(不依赖缩放开关);只有手动缩放时 Ctrl / ⌘ 才切换另一个动作">
|
|
125
130
|
<option value="pan">拖动=平移小图</option>
|
|
126
131
|
<option value="box">拖动=框选</option>
|
|
127
132
|
</select>
|
|
128
|
-
<
|
|
133
|
+
<label class="demo-minimap-switch" title="zoomable=follow 时主图相对基准倍数的指数:1 同倍率、0.5 为主图放大 4 倍时小图放大 2 倍、0 不随主图变化">
|
|
134
|
+
跟随指数
|
|
135
|
+
<input v-model.number="minimapFollowZoomScale" type="number" min="0" max="2" step="0.1" :disabled="!minimapEnabled || minimapZoomMode !== 'follow'" />
|
|
136
|
+
</label>
|
|
137
|
+
<select v-model.number="minimapZoomStep" :disabled="!minimapEnabled || minimapZoomMode !== 'manual'" title="每一次放大 / 缩小的倍率(滚轮一格与 - / + 按钮;只用于手动缩放)">
|
|
129
138
|
<option :value="1.2">步进 1.2</option>
|
|
130
139
|
<option :value="1.4">步进 1.4</option>
|
|
131
140
|
<option :value="1.8">步进 1.8</option>
|
|
132
141
|
<option :value="2">步进 2</option>
|
|
133
142
|
</select>
|
|
134
|
-
<button type="button" :disabled="!minimapEnabled ||
|
|
135
|
-
<button type="button" :disabled="!minimapEnabled ||
|
|
143
|
+
<button type="button" :disabled="!minimapEnabled || minimapZoomMode !== 'manual'" @click="zoomMinimap(1 / minimapZoomStep)">-</button>
|
|
144
|
+
<button type="button" :disabled="!minimapEnabled || minimapZoomMode !== 'manual'" @click="zoomMinimap(minimapZoomStep)">+</button>
|
|
136
145
|
</div>
|
|
137
146
|
<div class="demo-minimap-toolbar demo-minimap-toolbar--rules">
|
|
138
147
|
<select v-model="minimapRuleMode" :disabled="!minimapEnabled" title="小图的规则:沿用主图(只取颜色与层级)/ 按电压单独配一份(半径、形状、层级都在内)/ 完全不用规则">
|
|
@@ -163,7 +172,7 @@ const {
|
|
|
163
172
|
放大线路
|
|
164
173
|
<input v-model.number="minimapLineZoom" type="number" min="0" max="1" step="0.1" :disabled="!minimapEnabled" />
|
|
165
174
|
</label>
|
|
166
|
-
<span class="demo-control-hint">「放大节点 / 放大线路」跟的是<strong>小图自身</strong>的倍数:要勾上「可缩放」再滚轮 / +-
|
|
175
|
+
<span class="demo-control-hint">「放大节点 / 放大线路」跟的是<strong>小图自身</strong>的倍数:要勾上「可缩放」再滚轮 / +- 放大鹰眼图才看得到效果(改这两个值时这里会自动打开)。沿用主图规则时,节点 / 线路先按两边视口比例缩放,<strong>主视图缩放不会改变它们的大小</strong>;下面的「节点跟主图 / 线路跟主图」只作用于小图自有规则 / 样式。</span>
|
|
167
176
|
<label class="demo-minimap-switch" title="节点半径的整体倍数:与主视图的 pointSizeScale 同名同义(常数倍数,与小图倍数无关)">
|
|
168
177
|
整体节点
|
|
169
178
|
<input v-model.number="minimapPointSize" type="number" min="0" max="4" step="0.2" :disabled="!minimapEnabled" />
|
|
@@ -172,13 +181,13 @@ const {
|
|
|
172
181
|
整体线路
|
|
173
182
|
<input v-model.number="minimapLineWidth" type="number" min="0" max="4" step="0.2" :disabled="!minimapEnabled" />
|
|
174
183
|
</label>
|
|
175
|
-
<label class="demo-minimap-switch" title="
|
|
184
|
+
<label class="demo-minimap-switch" title="小图自有规则 / 样式的节点半径跟着主视图的地图倍数放大:0 不跟随、1 同倍率;沿用主图规则的节点不吃这一份">
|
|
176
185
|
节点跟主图
|
|
177
|
-
<input v-model.number="minimapPointMapZoom" type="number" min="0" max="1" step="0.1" :disabled="!minimapEnabled" />
|
|
186
|
+
<input v-model.number="minimapPointMapZoom" type="number" min="0" max="1" step="0.1" :disabled="!minimapEnabled || minimapRuleMode === 'inherit'" />
|
|
178
187
|
</label>
|
|
179
|
-
<label class="demo-minimap-switch" title="
|
|
188
|
+
<label class="demo-minimap-switch" title="小图自有规则 / 样式的线路宽度跟着主视图的地图倍数放大:0 不跟随、1 同倍率;沿用主图线宽不吃这一份">
|
|
180
189
|
线路跟主图
|
|
181
|
-
<input v-model.number="minimapLineMapZoom" type="number" min="0" max="1" step="0.1" :disabled="!minimapEnabled" />
|
|
190
|
+
<input v-model.number="minimapLineMapZoom" type="number" min="0" max="1" step="0.1" :disabled="!minimapEnabled || minimapRuleMode === 'inherit'" />
|
|
182
191
|
</label>
|
|
183
192
|
</div>
|
|
184
193
|
<div class="demo-minimap-toolbar demo-minimap-toolbar--box">
|
|
@@ -212,7 +221,7 @@ const {
|
|
|
212
221
|
自定义层
|
|
213
222
|
</label>
|
|
214
223
|
</div>
|
|
215
|
-
<span class="demo-minimap-hint">内置鹰眼图 · 拖框移视图 ·
|
|
224
|
+
<span class="demo-minimap-hint">内置鹰眼图 · 拖框移视图 · 缩放模式:关闭 / 手动缩放小图 / 跟随主图,手动与跟随互斥 · 手动模式滚轮按步进缩放小图(Ctrl / ⌘ + 滚轮留给主图),跟随模式按指数随主图倍数整体变化;「拖动=框选」不依赖缩放开关 · 空白处长按后跟随只在未手动缩放时走 · 范围三档:自动(数据 ∪ 底图)/ 只看数据 / 只看底图,「范围跟相机」默认关 · 规则:沿用主图 / 按电压单独配 / 不用;分层、层级、三组尺寸系数都能调 · 视口框与框选矩形的底色、不透明度、边框与圆角都能调 · 「自定义层」是 draw 钩子的示例</span>
|
|
216
225
|
</details>
|
|
217
226
|
</div>
|
|
218
227
|
</div>
|
|
@@ -3443,7 +3443,8 @@ export const useGisViewDemo = () => {
|
|
|
3443
3443
|
/**
|
|
3444
3444
|
* 鹰眼图:改成组件自带的能力,这里只留开关与样式配置。
|
|
3445
3445
|
* 节点与线路各自一份样式,框可以直接拖,空白处长按之后视角跟过去;
|
|
3446
|
-
*
|
|
3446
|
+
* 缩放模式三选一:关闭 / 手动缩放小图(zoomable: true)/ 跟随主图(zoomable: 'follow');
|
|
3447
|
+
* 手动模式走滚轮与 setMinimapZoom 那一组,跟随模式只由主图倍数带动。
|
|
3447
3448
|
*/
|
|
3448
3449
|
const MINIMAP_SIZES = {
|
|
3449
3450
|
small: [132, 99],
|
|
@@ -3456,9 +3457,13 @@ export const useGisViewDemo = () => {
|
|
|
3456
3457
|
const minimapShowLines = ref(true)
|
|
3457
3458
|
/** 小图范围:auto 数据 ∪ 底图(GeoJSON 底图不会缩成一个点)、data 只看数据(老行为)、background 只看底图 */
|
|
3458
3459
|
const minimapExtent = ref('auto')
|
|
3459
|
-
/**
|
|
3460
|
-
const
|
|
3461
|
-
/**
|
|
3460
|
+
/** auto 范围是否随相机收窄:默认关,始终按数据 ∪ 底图铺 */
|
|
3461
|
+
const minimapExtentFollowCamera = ref(false)
|
|
3462
|
+
/** 缩放模式:off 关闭、manual 手动缩放小图、follow 整体范围跟随主图;后两者互斥 */
|
|
3463
|
+
const minimapZoomMode = ref('off')
|
|
3464
|
+
/** 跟随主图时主图倍数的指数:1 同倍率、0.5 是主图放大 4 倍小图放大 2 倍 */
|
|
3465
|
+
const minimapFollowZoomScale = ref(1)
|
|
3466
|
+
/** 小图空白处拖动做哪个动作:平移小图内容 / 直接框选;box 不依赖手动缩放 */
|
|
3462
3467
|
const minimapDragAction = ref('pan')
|
|
3463
3468
|
/** 通道在小图上画几根:true 画全部回线,false 一个通道只画偏移最靠中间的那一根 */
|
|
3464
3469
|
const minimapChannelCircuits = ref(true)
|
|
@@ -3523,7 +3528,8 @@ export const useGisViewDemo = () => {
|
|
|
3523
3528
|
/** 鹰眼图折叠条上的摘要:不展开设置也能看到当前档位 */
|
|
3524
3529
|
const minimapSummary = computed(() => {
|
|
3525
3530
|
const size = MINIMAP_SIZES[minimapSize.value] ?? []
|
|
3526
|
-
|
|
3531
|
+
const zoom = minimapZoomMode.value === 'manual' ? '手动缩放' : minimapZoomMode.value === 'follow' ? '跟随主图' : '不缩放'
|
|
3532
|
+
return `${size[0] ?? 0}×${size[1] ?? 0} · ${minimapEnabled.value ? '开' : '关'} · ${zoom} · ${minimapShowLines.value ? '线路' : '无线'} · ${minimapChannelCircuits.value ? '全部回线' : '一根回线'}`
|
|
3527
3533
|
})
|
|
3528
3534
|
/** 主图节点规则里出现过的层号:按电压分层关掉时全是 0,就没有可选的层 */
|
|
3529
3535
|
const minimapLayerOptions = computed(() => {
|
|
@@ -3579,6 +3585,8 @@ export const useGisViewDemo = () => {
|
|
|
3579
3585
|
height: MINIMAP_SIZES[minimapSize.value][1],
|
|
3580
3586
|
// 范围:默认数据与底图合起来,GeoJSON 底图不会因为与数据范围不重合而缩成一个点
|
|
3581
3587
|
extent: minimapExtent.value,
|
|
3588
|
+
// auto 默认不跟相机收窄;打开后相机进出数据 / 底图范围时才会重新算包围盒
|
|
3589
|
+
extentFollowCamera: minimapExtentFollowCamera.value,
|
|
3582
3590
|
position: 'bottom-right',
|
|
3583
3591
|
margin: 12,
|
|
3584
3592
|
pointStyle: { color: '#4b8dff', size: 1.4 },
|
|
@@ -3592,7 +3600,8 @@ export const useGisViewDemo = () => {
|
|
|
3592
3600
|
// 被 levels 挡掉的节点,连在它们身上的线路按同一套 cascade 一起隐藏('false' 表示不连锁)
|
|
3593
3601
|
cascade: minimapCascade.value,
|
|
3594
3602
|
layered: minimapLayered.value,
|
|
3595
|
-
// 节点 /
|
|
3603
|
+
// 节点 / 线路的尺寸系数:整体倍数对自有与沿用主图的要素都生效;小图自身倍数也两边都算;
|
|
3604
|
+
// 跟随主视图地图倍数只作用于小图自有规则 / 样式(沿用主图时尺寸按视口比例,不受主图缩放影响)
|
|
3596
3605
|
pointSizeScale: minimapPointSize.value,
|
|
3597
3606
|
lineWidthScale: minimapLineWidth.value,
|
|
3598
3607
|
// 节点与线路跟着小图自身的倍数放大:滚轮 / - + 放大鹰眼图时它们一起变大
|
|
@@ -3616,9 +3625,11 @@ export const useGisViewDemo = () => {
|
|
|
3616
3625
|
draw: minimapDrawLayer.value ? drawMinimapOverlay : undefined,
|
|
3617
3626
|
interactive: true,
|
|
3618
3627
|
longPressDelay: 180,
|
|
3619
|
-
//
|
|
3620
|
-
zoomable:
|
|
3621
|
-
//
|
|
3628
|
+
// 三档互斥:true 手动缩放小图,'follow' 整体范围跟随主图,false 关闭;minZoom / maxZoom 是倍数范围
|
|
3629
|
+
zoomable: minimapZoomMode.value === 'manual' ? true : minimapZoomMode.value === 'follow' ? 'follow' : false,
|
|
3630
|
+
// 跟随主图时主图相对基准倍数的指数;手动缩放模式下不参与
|
|
3631
|
+
followZoomScale: minimapFollowZoomScale.value,
|
|
3632
|
+
// 每一次放大 / 缩小的倍率、空白处拖动的动作(box 不依赖手动缩放)、通道画全部回线还是一根
|
|
3622
3633
|
zoomStep: minimapZoomStep.value,
|
|
3623
3634
|
dragAction: minimapDragAction.value,
|
|
3624
3635
|
channelCircuits: minimapChannelCircuits.value,
|
|
@@ -4774,24 +4785,24 @@ export const useGisViewDemo = () => {
|
|
|
4774
4785
|
}
|
|
4775
4786
|
/**
|
|
4776
4787
|
* 小图倍数的两个系数(pointZoomScale / lineZoomScale)只在小图自身被放大时起作用 ——
|
|
4777
|
-
*
|
|
4778
|
-
*
|
|
4788
|
+
* 缩放模式是关的时候,改这两个值看不出变化,容易被当成没生效。这里在用户真的填了正数时
|
|
4789
|
+
* 顺手切到「手动缩放小图」,并在读数里说一句怎么看到效果;跟随主图的模式不被覆盖。
|
|
4779
4790
|
*/
|
|
4780
4791
|
watch([minimapPointZoom, minimapLineZoom], ([point, line]) => {
|
|
4781
|
-
if (!minimapEnabled.value ||
|
|
4792
|
+
if (!minimapEnabled.value || minimapZoomMode.value !== 'off') {
|
|
4782
4793
|
return
|
|
4783
4794
|
}
|
|
4784
4795
|
if (!(Number(point) > 0) && !(Number(line) > 0)) {
|
|
4785
4796
|
return
|
|
4786
4797
|
}
|
|
4787
|
-
|
|
4788
|
-
writeLastEvent('「放大节点 /
|
|
4798
|
+
minimapZoomMode.value = 'manual'
|
|
4799
|
+
writeLastEvent('「放大节点 / 放大线路」跟的是小图自身的倍数:已自动切到「手动缩放」,滚轮或 + / - 放大鹰眼图就能看到节点 / 线路一起变大')
|
|
4789
4800
|
})
|
|
4790
4801
|
watch([showTooltip, tooltipHtml, tooltipChannelScope], () => viewRef.value?.updateOptions({ tooltip: buildTooltipOptions() }))
|
|
4791
4802
|
watch([filterVoltage, filterType, filterKeyword, filterLines, filterCascade], () => applyFilterFromControls())
|
|
4792
4803
|
// 数据映射:换模式 / 换比例就把当前数据按新映射重画一遍(数据不动,只换画出来的坐标)
|
|
4793
4804
|
watch([datasetProjection, datasetProjectionScale], () => applyDatasetMapping())
|
|
4794
|
-
watch([minimapSize, minimapEnabled, minimapShowLines, minimapExtent,
|
|
4805
|
+
watch([minimapSize, minimapEnabled, minimapShowLines, minimapExtent, minimapExtentFollowCamera, minimapZoomMode, minimapFollowZoomScale, minimapDragAction, minimapChannelCircuits, minimapZoomStep, minimapRuleMode, minimapLayered, minimapLevels, minimapCascade, minimapPointSize, minimapLineWidth, minimapPointZoom, minimapLineZoom, minimapPointMapZoom, minimapLineMapZoom, minimapBoxFill, minimapBoxFillOpacity, minimapBoxStroke, minimapBoxStrokeWidth, minimapBoxStrokeStyle, minimapBoxRadius, minimapDrawLayer], () => viewRef.value?.updateOptions({ minimap: buildMinimapOptions() }))
|
|
4795
4806
|
// 两种画法「好看」的门槛不一样:smooth 靠 alpha 往外淡,3% 就够;band 是硬边色块,抬到 15% 才留得住「大片浅色 + 环环相扣的热点」。
|
|
4796
4807
|
// 换画法时把这两个跟着画法走的滑杆带回它自己的缺省,免得拿 smooth 的 3% 去看 band(整张图糊成一片橙)
|
|
4797
4808
|
watch(heatmapDensityStyle, value => {
|
|
@@ -6142,7 +6153,7 @@ export const useGisViewDemo = () => {
|
|
|
6142
6153
|
exportPartToFile, refreshExportSample, slimSample, sampleJson, refreshDataShape, scheduleDataShape,
|
|
6143
6154
|
printDataShape, exportWholeImage, startCopyPick, copyPointByApi, copyThenPaste, waypointPhaseText,
|
|
6144
6155
|
syncParallelGroups, copyParallelGroupRecords, handleWaypoint, MINIMAP_SIZES, minimapSize, minimapEnabled,
|
|
6145
|
-
minimapShowLines, minimapExtent,
|
|
6156
|
+
minimapShowLines, minimapExtent, minimapExtentFollowCamera, minimapZoomMode, minimapFollowZoomScale, minimapDragAction, minimapChannelCircuits, minimapZoomStep,
|
|
6146
6157
|
zoomMinimap, minimapRuleMode, minimapLayered, minimapLevels, minimapCascade, minimapPointSize,
|
|
6147
6158
|
minimapLineWidth, minimapPointZoom, minimapLineZoom, minimapPointMapZoom, minimapLineMapZoom, minimapBoxFill,
|
|
6148
6159
|
minimapBoxFillOpacity, minimapBoxStroke, minimapBoxStrokeWidth, minimapBoxStrokeStyle, minimapBoxRadius,
|
package/docs/index.html
CHANGED
|
@@ -1323,7 +1323,7 @@
|
|
|
1323
1323
|
{ file: 'manual/14-视图与筛选.md', title: '手册 14 · 视图与筛选', blurb: '筛选 / 搜索 / 视图与背景', parent: 'GisView.md' },
|
|
1324
1324
|
{ file: 'manual/15-导出与集成.md', title: '手册 15 · 导出与集成', blurb: '导出 / 插件 / 自建界面', parent: 'GisView.md' },
|
|
1325
1325
|
{ file: 'manual/16-实例方法总表.md', title: '手册 16 · 实例方法总表', blurb: '实例方法主表', parent: 'GisView.md' },
|
|
1326
|
-
{ file: 'manual/17-参数速查.md', title: '手册 17 · 参数速查', blurb: '
|
|
1326
|
+
{ file: 'manual/17-参数速查.md', title: '手册 17 · 参数速查', blurb: '257 个成员逐个列全', parent: 'GisView.md' },
|
|
1327
1327
|
{ file: 'manual/18-逐方法示例.md', title: '手册 18 · 逐方法示例', blurb: '每个成员一段示例', parent: 'GisView.md' },
|
|
1328
1328
|
{ file: 'manual/19-读数与拖拽预览.md', title: '手册 19 · 读数与拖拽预览', blurb: '读数 / 定位 / 落点预览', parent: 'GisView.md' },
|
|
1329
1329
|
{ file: 'manual/20-性能与大数据.md', title: '手册 20 · 性能与大数据', blurb: '大数据开关与实测', parent: 'GisView.md' },
|
|
@@ -1399,7 +1399,7 @@
|
|
|
1399
1399
|
{ file: '../src/gis-view/README.md', title: 'src/gis-view/README.md', blurb: '源码导读与逐轮实现记录' }
|
|
1400
1400
|
]
|
|
1401
1401
|
const PAGES = [
|
|
1402
|
-
{ href: 'api/index.html', title: 'API 速查(方法 + 示例)', blurb: '
|
|
1402
|
+
{ href: 'api/index.html', title: 'API 速查(方法 + 示例)', blurb: '257 个实例成员 / 96 个 options,逐个带示例与复制' },
|
|
1403
1403
|
{ href: 'playground/index.html', title: '调试演示页(粘代码就跑)', blurb: '左侧编辑、右侧真实实例 + GeoJSON 底图:内置示例与「这一份文档」的示例同在一个下拉,粘代码直接跑' },
|
|
1404
1404
|
{ href: 'guide/sample-document.html', title: 'sample-document.json 图解', blurb: '点数据看端点 / 拐点 / 分组骨架' },
|
|
1405
1405
|
{ href: 'steps/index.html', title: '从 0 手写分步 demo', blurb: '13 步,每步一个文件' },
|
|
@@ -1956,7 +1956,7 @@
|
|
|
1956
1956
|
{ badge: 'START', title: '第一次使用', desc: '引入、最小数据与首屏配置,先把图画出来。', meta: '01 快速开始 · 约 10 分钟', file: 'manual/01-快速开始.md' },
|
|
1957
1957
|
{ badge: 'BACKEND', title: '接后端与导出', desc: '编辑接口、导出回灌、插件与自建界面。', meta: '15 导出与集成', file: 'manual/15-导出与集成.md' },
|
|
1958
1958
|
{ badge: 'PERF', title: '十万级性能', desc: 'Worker 筛选 / 异步搜索、批量更新与质量档。', meta: '20 性能与大数据', file: 'manual/20-性能与大数据.md' },
|
|
1959
|
-
{ badge: 'API', title: '查方法与参数', desc: '实例方法、options 与可复制示例集中检索。', meta: 'API 速查 ·
|
|
1959
|
+
{ badge: 'API', title: '查方法与参数', desc: '实例方法、options 与可复制示例集中检索。', meta: 'API 速查 · 257 个成员', href: 'api/index.html', external: true }
|
|
1960
1960
|
]
|
|
1961
1961
|
const renderReadingPaths = () => `<section class='doc-paths' aria-label='推荐阅读路径'>` +
|
|
1962
1962
|
`<div class='doc-paths__head'><strong>按任务选一条阅读路径</strong><span>第一次进来先看快速开始;带着明确目标时直接跳到对应章节。</span></div>` +
|
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
- **底图**:`minimap.js` 把节点与线条直接写进一块离屏像素缓冲(`ImageData`),按「层级 + 颜色 + 线宽 + 透明度」分桶后再画 —— 绘制次数随分桶数走,不随数据量走;底图只在数据或筛选结果变化时重画;节点像素结果按「数据引用 + 尺寸 + 范围 + 变换 + 样式」缓存,同一份数据前后两次重画直接复用(十万点重铺 20ms → 0.3ms),数据范围也按数据对象进 `WeakMap`。
|
|
6
6
|
- **视口框**:单独一个 DOM 元素,相机变化只改 `transform`(不重画底图),所以拖动小图不掉帧。
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
7
|
+
- **挂载与位置**:`minimap.container` 接受 `HTMLElement` 或选择器,把 `.gis-view__minimap` 根节点挂到外部宿主;换容器只 `append` 同一根节点,画布、缓存与事件监听都不重建,`destroy()` 从当前宿主摘掉。`offset` 是相对 `position` 角落的 `[x, y]` 位移(正数向右 / 向下),`updateOptions` 只改 `left` / `right` / `top` / `bottom`,因此整图拖动不需要重画小图;根节点通过 `getMinimapElement()` 暴露给外部手势。
|
|
8
|
+
- **整图拖动示例**:`docs/demos/MinimapDemo.vue` 在根节点顶部追加一个独立手柄,手柄的 `pointerdown` 直接 `stopPropagation`,窗口级 `pointermove` / `pointerup` 累计位移并写回 `minimap.offset`;小图内部的框选、平移与视口框拖动都不受影响。方向键按 2px(Shift 10px)微调,复位按钮把 `offset` 写回 `[0, 0]`。
|
|
9
|
+
- **规则**:小图可以有自己的 `pointRules` / `lineRules`(颜色、半径 / 线宽、形状、层级),不配时沿用主图样式链:颜色 / 描边色 / 层级取规则,节点尺寸与符号取引擎最终解析结果(点自身 > 主图规则 > `pointStyle`),线路线宽取样式链的原始线宽(不含主图整体倍数 / 缩放联动 / 热力倍数)。`inheritSize` / `inheritWidth` 标记的节点 / 线路再乘一次「小图 CSS 视口宽高 ÷ 主图 CSS 视口宽高」的较小比例(`inheritedSizeFactor()`),这一份只跟两边视口尺寸有关,主图相机缩放不会改继承要素的大小;小图自身放大时仍可按 `pointZoomScale` / `lineZoomScale` 叠加,`pointSizeScale` / `lineWidthScale` 对自有与继承要素统一生效,`pointMapZoomScale` / `lineMapZoomScale` 只作用于小图自有规则 / 样式。小图自己的尺寸不受视口比例这一步影响。圆形按主图的面积对齐系数还原真实直径;图片 / SVG 图标与自定义图元异步解码后单独盖在点层上,解码前先用小图基准尺寸的圆 / 方回落,完成后只失效点层并补一帧。
|
|
10
|
+
- **交互**:视口框上按下 = 拖框;空白处长按(`longPressDelay`)= 视角跟随;`zoomable` 三态互斥:`true` 手动缩放小图自身(滚轮按 `zoomStep`、锚点落光标处,Ctrl / ⌘ + 滚轮留给主图),`'follow'` 让整体范围跟随主图(`followZoomScale` 是主图倍数的指数,`setMinimapZoom` / `zoomMinimapBy` 不抢控制权),`false` 只缩放主图。`dragAction` 决定空白处拖动是平移小图还是框选,`box` 不依赖 `zoomable`;只有手动模式按住 Ctrl / ⌘ 才自动切到另一个动作。拖框与视角跟随带来的相机变化是「程序化」的:标签层不进交互态(`hideOnInteract` 不会把主视图的标签收起来),拖动结束补一次真实排版。每次真正有位移的手势结束时通过 `onInteraction` 发一条 `{ type, originalEvent, local, world, zoom, extent, camera, viewport }`(`type` 为 `box-drag` / `select` / `pan` / `zoom` / `wheel-main` / `long-press`);无位移的点击不发,`pointermove` 不逐帧回调,长按在触发跟随时发。
|
|
11
|
+
- **范围**:`extent` 决定小图按哪段世界范围铺 —— `measure(data)` 量出可见数据的范围,`backgroundBoundsOf(background)` 量出底图范围(GeoJSON 用画出来的 `bounds`,图片用四角 quad 的包围盒),`auto`(默认)取两者的并集,`data` 只看数据(旧行为),`background` 只看底图。数据为空时 `measure()` 返回 `null`、不会当成「范围是正负一」;修掉的问题见 15.12。`extentFollowCamera` 默认 `false`,`auto` 始终用并集,外围内容消失不会让包围盒与视口框跳动;打开后才有例外:相机正落在其中一份范围里、而那一份在并集里连 6 个像素都占不到时(数据还没映射到底图坐标系就是这样)只画正在看的那一份;`followFocusedExtent()` 在相机挪进 / 挪出这份小范围时补一次重画 —— 判断只用上一次重画缓存的两份范围,每帧几次比较。
|
|
12
|
+
- **内容范围锁定**:`extentFollowContent` 默认 `false`。`resolveExtent()` 首次拿到当前模式需要的数据 / 底图范围后把它放进 `pinnedExtent`,之后筛选、删除、隐藏或新增内容只重画可见要素,不再改 `bounds` / `scale` / 中心,视口框也就不会跟着外围内容消失而漂移;打开开关后每次重画都用当前可见内容重算。显式修改 `extent`(模式或固定范围对象按值比较)会清掉锁定,立刻按新配置铺;切换 `extentFollowContent` 会重新锁定当前内容。`extentFollowCamera` 的相机取舍也使用锁定后的两份范围。
|
|
13
|
+
- **通道**:`channelCircuits: false` 时每个分组按当前可见成员逐顶点平均成一根代表线,双回线因此落在两根正中间,三回线落在中间那条;只剩一条可见成员时就是它自己,顶点数对不上时退回第一条可见成员(底图分辨率本来就在一像素上下,多回线只会糊成一片)。
|
|
14
|
+
- **背景**:默认 `background: 'inherit'`,直接拿引擎解析好的那份背景在 Canvas2D 上重画:底色铺满,图片按 quad 拆成两组三角形做仿射 + 裁剪(任意四边形都不会画歪),GeoJSON 面用奇偶规则填充(洞自动镂空)、纯线几何的区域再描一遍、点要素画成固定 1.2px 半径的小圆;底图的线宽(取配置值、最低 0.4px 保可见)与区域文字字号(固定档,夹在 5 ~ 12px)都是小图上的固定像素,不乘「小图视口 ÷ 主图视口」的比例 —— 缩放主视图时底图不会单独放大 / 缩小(本轮删掉了 `mapRatio`,见 15.17)。也可以给 `minimap.background` 单独配一份(结构与主视图的 `background` 完全一致,只是换 Canvas2D 画)。`backgroundStyle` 显式设置时由容器 CSS 接管底色:继承或独立的底图仍画图片与 GeoJSON,但画布底色改成透明,不再用主图的不透明底色盖住容器;不写时仍按主图底色铺满。区域文字先量「区域在小图上的屏幕矩形 ≥ 文字尺寸 × 0.85」再画,放不下就整条跳过(缩略图上那些小块本来也读不出来);能画的按区域从大到小排,和已经放下的标签重叠就跳过 —— 小图上几十个区域各画一行字只会叠成一团。
|
|
12
15
|
- **扩展层**:`layers` 接收一组 `{ id?, order?, placement?, enabled?, draw }`。`placement: 'below-data'` 在内置线路 / 节点之前执行,适合网格、分区底色;`'above-data'`(缺省)在数据之后执行,适合指北针、业务标记。两段内部各按 `order` 从小到大,相同或缺省 `order` 按数组顺序。`setOptions` 时把过滤、排序与分段结果缓存成两条数组,绘制帧只遍历当前段,不再每帧 `map` / `filter` / `sort`。每个回调独立 `save` / `restore`,一层改过的画布状态不会漏进下一层;`enabled: false` 可临时关掉一层,旧的单层 `draw` 保持兼容并固定最后执行,回调里的 `stage` 为 `'overlay'`。这样网格、指北针、业务标记可以各自维护,不必把所有内容堆进一个钩子。
|
|
13
16
|
- **清晰度与开销**:小图画布用自己的一份倍率(`clamp(devicePixelRatio × 宿主显示比例, 1, maxPixelRatio)`,`maxPixelRatio` 默认 4、夹在 1 ~ 4),主视图为全屏帧率按像素预算压低渲染倍率时,小图不受影响;小图尺寸大或高分屏填充压力高时可以把上限降到 1 ~ 2。容器另有 `contain: layout paint` 与 `isolation: isolate`,把布局与重绘影响收在自身。
|
|
14
17
|
|
|
@@ -266,9 +266,20 @@
|
|
|
266
266
|
|
|
267
267
|
② 也在本轮落了地(见 15.55):写实例的那几个口子(`writeCircle` / `writeLine` / `writeSpriteInstance`、追加点的那一段循环、`patchPointSlots` 的贴图分支)就地记光晕账本(`heat > 0 && opacity > 0`,与解析那一趟同一份口径),补丁路径不再置 `heatGlowDirty`,`refreshHeatGlow` 只剩「补丁改过解析结果」(换热力图配置)这一条兜底;顺手把样式快路径漏写回的 `point.heat` 补上(线路那侧的 `refreshLine` 一直有)。
|
|
268
268
|
|
|
269
|
-
### 16.34 线路侧的「只换线色 /
|
|
269
|
+
### 16.34 线路侧的「只换线色 / 线宽」窄路(已完成,本轮)
|
|
270
270
|
|
|
271
|
-
|
|
271
|
+
点侧在 15.53 / 15.54 已有尺寸链 / 配色链两条窄路,线侧原先仍是整份重解析:`updateOptions({ lineStyle })` 只动线色 / 线宽时,规则、热力、虚线、阴影、动点与方向箭头都要重新归一化,`resolveLineStyleInto` 还会再走一遍完整对象写入。上一轮量过 20 万线,重解析约占三成、槽位补丁与实例上传占大头,因此把它留成候选;这一轮先把最常走的基准样式补丁收掉,同时让窄路与整份解析共用同一份取值链,避免两套实现以后漂开。
|
|
272
|
+
|
|
273
|
+
**改法**:从 `line.js` 抽出 `resolveLinePaintInto(target, line, style, defaults, state, heat, rule)`,只负责「基准宽 / 实际半宽 / 颜色 / 透明度」;`resolveLineStyleInto` 继续在它之上补 `zIndex` / 拐角 / 虚线 / 阴影 / 效果 / 方向。`engine.js` 新增 `NARROW_LINE_STYLE_BUCKETS` 与 `lineStyleNarrowChange()`:只在补丁确实动到 `width` / `color` / `opacity`、且没有线路规则 / 热力图、`effects` 与 `lineDirection` 引用未变时命中;`applyLineNarrowFast()` 逐条重算 paint,结果与上一轮相同就不进补丁列表,最后仍走 `patchLineSlots(changedLines, true)`。逐线自己写死的字段和状态样式继续优先;线宽变化会让交互期细线的账本作废,但不再重跑线型、阴影、动点等结构输入。`getLineStyle(index)` 读到的也是这条链落下来的最新快照。
|
|
274
|
+
|
|
275
|
+
1000 点 + 50000 线连续 5 次换色 / 换宽(无头 Chrome + SwiftShader,`scripts/bench-scale.mjs`):
|
|
276
|
+
|
|
277
|
+
| 操作 | 改前(稳态) | 改后(稳态) |
|
|
278
|
+
| --- | --- | --- |
|
|
279
|
+
| `lineStyle.color` 换色 | 10.1 ~ 11.7 ms | **6.1 ~ 7.4 ms** |
|
|
280
|
+
| `lineStyle.width` 换宽 | 9.2 ~ 10.4 ms | **5.8 ~ 6.4 ms** |
|
|
281
|
+
|
|
282
|
+
改后 profile 顶部是 `patchLineSlotsInner` 30.8% / `patchLineSlots` 17.3% / `applyLineNarrowFast` 13.0%,`resolveLinePaintInto` 3.8%;原先整份路里占大头的 `applyResolvedStyles` 与 `refreshLine` 不再出现。首轮仍有 18.9 / 17.3 ms(槽位表与交互期细线账本首次重建),稳态收益约 40%。正确性侧:`selftest-perf.html` 核对窄路后的 `getLineStyle`、逐线自身线宽 / 颜色优先、虚线不被覆盖,以及存在线路规则时回退整份解析;`selftest-demos.html` 核对 demo 的换色 / 加宽与 `dataVersion` 不递增。
|
|
272
283
|
|
|
273
284
|
### 16.35 通道回线拖动剩下的账(已完成,见 15.61)
|
|
274
285
|
|
|
@@ -284,11 +295,13 @@
|
|
|
284
295
|
|
|
285
296
|
10 万点 / 6 万线里删掉一条线,`removeLine` 实测 61 ms(最快一次):`removeLines` 收尾走 `applyOptions()` → 引擎 `setOptions({ points, lines, channels, hiddenPoints, hiddenLines })`,补丁里带了 `points`,于是整份 `buildScene()` —— 十万个节点重解析一遍、圆点与贴图批次整份重铺,纯粹陪跑(删一条线一个节点都没动)。收益是把点那一半摘掉(约 30 ms;其余是线路侧的重编号:删掉中间一条线,后面每条线的下标都往前挪一格,`lineSegmentSlots` / `decorationRanges` / 选中镜像 / 通道成员表全都要跟着重排)。要做的话得让 `setOptions` 认得「节点这一半逐元素还是上一轮那批对象」(`patch.points` 与内部副本逐元素比身份,十万次比较约 0.3 ms),再让 `resolveFeatures` 支持只跑线路那一半(符号预热账本 / 热力值域 / 点层序这些与点绑定的账要原样留着)。这一条按「值不值得做」排在建增量通道(16.35 末尾那条)之后:删一条线的场景不多,而它牵扯的是数据更新的主路径 —— **本轮(15.65)把它做掉了:判定改成「逐元素同引用 + 解析输入快照」两步,只跳过点那一半;`removeLine` 10 万点 / 6 万线 50.7 → 41.3 ms。** 剩下那 ~40 ms 是线路侧的整份重编号,见 16.37。
|
|
286
297
|
|
|
287
|
-
### 16.37
|
|
298
|
+
### 16.37 线路那一半也整半跳过(已在当前轮落地)
|
|
299
|
+
|
|
300
|
+
与 15.65 做掉的「点那一半」同构。判定分两层:先在 `applyOptions` 收配置前确认 `patch.lines` 与内部那一份**逐元素同引用**、`patch.hiddenLines` 内容没变、`patch.channels` 也逐条同引用、通道宽度 / 节点尺寸 / 整体倍率 / `lineFollowsNode` 这些会改车道与回线折线的输入没变,并且没有 `appendedPoints` / `appendedLines`;收完配置后再用快照确认线基准样式 / 规则 / 效果 / 线方向 / 热力图、节点基准样式与线路悬停 / 选中 / 多选状态样式都没变。`forceResolve`、交互中、销毁后以及增量删除路都直接回退整份重解析。
|
|
288
301
|
|
|
289
|
-
|
|
302
|
+
命中时 `resolveFeatures` 跳过 `resolveLines`、`lineByIndex` / 最大半线宽 / 虚线图案槽位 / 线路装饰与效果标记 / 布局层序 / 线路包围盒这几趟,直接沿用上一轮线路那一半的读数;排线路批次那一趟仍然照常跑。线路半包围盒不是只在整份解析时记账:追加补线会把新路径并进来,拖点 / 拐点 / 通道骨架这类增量改线也会在 `applyResolvedLinePath` 里把新路径并进来;还没有可信读数时记 `lineHalfOutOfSync`,下一轮放弃跳过,避免沿用旧范围。
|
|
290
303
|
|
|
291
|
-
|
|
304
|
+
收益只在「同一批线路对象原样再交一遍」的补丁上兑现(内容真的换了、`removeLine` 这种下标平移的路都不算)。`selftest-perf.html` 的 20000 点 / 8000 线回灌基准(同一批对象连交 5 次取中位)由 **14.3 ms** 降到 **6.3 ms**;同页新增三条断言,锁定条数与线路实例数不变、通道声明没换时派生折线原样保留、换通道骨架时线路几何必须重推。性能页当前为 **167 passed / 0 failed**。
|
|
292
305
|
|
|
293
306
|
|
|
294
307
|
### 16.38 `removePoints` 的反向增量(候选 → 已在 15.66 落地)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 16-03 优化与取舍(下)
|
|
2
2
|
|
|
3
|
-
> 16.57 ~ 16.
|
|
3
|
+
> 16.57 ~ 16.75:坐标、通道、筛选、相机快路径与文档口径的取舍。
|
|
4
4
|
|
|
5
5
|
## 16 还能怎么优化(续)
|
|
6
6
|
|
|
@@ -140,6 +140,16 @@
|
|
|
140
140
|
- **为什么 `exportViewportData` 的结果要展开补元数据**:自定义适配器只负责业务结构,不知道视口范围;`viewRect` / `margin` 是这次查询的上下文,必须由 `exportViewportData` 统一补上,且不能覆盖适配器同名字段之外的内容。对象结果才展开、非对象原样返回,避免适配器返回 `null` 时凭空造一个对象。
|
|
141
141
|
- **为什么严格契约放在 demos 自测里**:这两个接口是「演示即文档」的一部分,后端同学拿到的第一个可执行样例就是假后端。把 400 / 409 断言放在 `selftest-demos.html`,每次演示页回归都会重新验证契约,不需要另起一套测试设施。
|
|
142
142
|
|
|
143
|
+
### 16.75 程序化相机运动为什么也走交互快路径、聚合关闭为什么不能再整份重排(本轮已做 / 留档)
|
|
144
|
+
|
|
145
|
+
- **根因不在绘制,而在「谁算运动帧」**:`zoomBy` / `setCamera` / `centerOn` / `flyToCamera` 都只改相机再 `notifyCameraChange()`,并不经过 `beginInteraction()`。轻量画法的判定只看 `interacting` 或动画,于是同一份十万级场景,用户拖一下能走细线与非 MSAA 后备缓冲,外部控件调一次缩放却仍按全质量画。这一轮把「程序化相机运动」记成一个 160 ms 的短窗口,`offscreenFrame` 与 `thinLinesDrawn` 共用同一套判定;每次真实位置变化重新计时,停稳后补一张全质量帧,并刷新通道宽度、恢复符号预烤。
|
|
146
|
+
- **为什么要比较相机位置,而不是每次 `setCamera` 都续期**:业务侧常把 `setCamera` 放在定时器或响应式同步里,即使视角没变也会反复调用。若无条件续期,画面会永久停在轻量档,线宽、圆头与 MSAA 都回不来。现在的 `cameraMotionLast` 只认真实变化的中心 / 比例;同一位置重复调用既不进入快路径,也不会重置停稳计时。
|
|
147
|
+
- **为什么关闭聚合也要单独处理**:旧代码只要 `camera.scale !== clusterScale` 就标 `clusterDirty`,而 `flushPointClusterLayout()` 无条件调用 `layoutScene()`。聚合没开时,这一趟没有任何成员可算,却会把十万级点的实例缓冲整份重写上传 —— 缩放看起来慢,慢在这里而不是 WebGL 绘制。现在只在聚合启用且当前档可能聚合、或上一帧确实有聚合圆 / 隐藏点时才标脏;关闭聚合且没有旧画面时只清标记。跨出 `maxZoom`、改配置、数据 / 选中 / 拖动变化仍立即重排,避免为了省一次计算让状态延迟生效。
|
|
148
|
+
- **为什么相机引起的聚合变化可以晚一帧**:聚合半径是屏幕像素,运动过程中每帧都重算成员只会把主线程占满,而圆本身的成员变化在快速缩放里很难看清。于是只把「纯相机缩放导致的成员变化」推迟到停稳后,拖动期间沿用上一组成员是同一口径;平移不改比例,一次都不标脏。
|
|
149
|
+
- **为什么停稳条件不能只看「画过轻量帧」**:聚合成员被推迟时,如果场景没有线、又显式 `interactionNoMsaa: false`,这一轮可能没有任何轻量几何,但 `clusterDirty` 仍在。停稳计时器现在同时检查 `cameraMotionFastDrawn` 与「被相机推迟的聚合脏」,后者也补一帧,否则聚合会停在旧缩放档。`selftest-perf.html` 用 12000 点、无边、关后备缓冲的场景专门钉住这一条。
|
|
150
|
+
- **为什么不改公开接口**:快路径只改「什么时候画成哪一档」,相机、聚合、选项与返回结构都没变,不使用这条路的调用方行为不变;`getStats().thinLines` / `noMsaa` 仍是最近一帧的真实读数,静态画面照旧回到全质量。
|
|
151
|
+
- **验证**:`node --check`、`npx tsc --noEmit`、`node docs/steps/gen-api-index.mjs --check`、`npm run check:docs`(264 个实例成员 / 96 个 options / 250 个数据字段 / 43 个事件 / 17 个功能开关)、四页自测 `full 94` / `demos 365` / `docs 134` / `perf 181` 共 **774** 条通过 / 0 失败、`npm run build` 与 `git diff --check` 全部通过。10 万点 / 5 万线实测连续缩放 p50 **67.9 → 22.5 ms**、p95 **76.2 → 25.1 ms**、avg **60.77 → 20.57 ms**;平移 p50 17.1 → 17.2 ms(帧节拍波动),`refresh()` 56.2 → 53.7 ms。profile 显示剩余成本主要是 GPU 光栅化 / 帧节拍,`render` 自身约 0.1%,因此本轮收益应表述为「省掉整份重排与上传、运动期省掉 MSAA 细线光栅化」,不是「单帧渲染降到 1 ms」。
|
|
152
|
+
|
|
143
153
|
---
|
|
144
154
|
|
|
145
155
|
[← 16-02 优化与取舍(中)](16-02-%E4%BC%98%E5%8C%96%E4%B8%8E%E5%8F%96%E8%88%8D-%E4%B8%AD.md) · [实现原理目录](../GisView实现原理.md) · [17 调试与扩展建议 →](17-%E8%B0%83%E8%AF%95%E4%B8%8E%E6%89%A9%E5%B1%95%E5%BB%BA%E8%AE%AE.md)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 十五轮实测数据、瓶颈定位与 WebGPU 值不值得上。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
结论先说:**绘制提交与 JS 不是当前瓶颈;十万级长线的主要剩余成本是 GPU 填充率,换 WebGPU(或把渲染挪进 Worker)不会减少相同像素量的填充,因此仍不会带来明显收益**。
|
|
6
6
|
十万级数据下真正的开销在 JS / DOM 侧,几轮优化都落在这里:先是标签覆盖层的候选上限(`label.scanLimit`,0.8 → 36.5 FPS),
|
|
7
7
|
再是把标签图层做成「交互期整体变换 + 停手后重排」,平移 / 缩放 / 拖点从此与「关掉标签」同档(17.9 / 13.5 / 20.1 → 55 ~ 58 FPS),
|
|
8
8
|
整屏框选也从 97 ms 降到 52 ms;随后一轮把「整组拖动」的增量补丁补齐到每个实例批次(点线按槽位合并上传、圆头批次欠账到松手后分摊补齐),
|
|
@@ -251,6 +251,78 @@
|
|
|
251
251
|
- **编辑类开关缺省关闭**(详见 15.39 与 15.25):`features` 与详细配置都没写时,框选 / 拖拽 / 拐点 / 复制 / 合并 / 新增通道 / 通道右键菜单一律关着 —— 缺省口径=只读浏览;`features: 'edit'` 一次全开,单开写 `draggable: true` / `boxSelect: true` / `waypointEditable: true` / `copy: {…}` / `merge: {…}` 或 `features: { drag: true }`。自测页与 demo 里要用这些交互的地方都显式打开了开关,因此断言与画面语义不变(变的只是「什么都不写」时的行为,这正是需求本身)。
|
|
252
252
|
- **验证**:十个自测页在真时间下逐页跑完全绿(`selftest` 26 / `selftest-actions` 96 / `selftest-effects` 85 / `selftest-labels` 90 / `selftest-demo` 112 / `selftest-demos` 61 / `selftest-scale` 42 / `selftest-perf` 72 / `selftest-full` 68 / `selftest-features` 264),`npx tsc --noEmit` 0 错,`node docs/steps/check-doc-coverage.mjs` 无缺口,`npm run build` 通过。
|
|
253
253
|
|
|
254
|
+
#### 第十六轮:同一批点线原样回灌,线路那一半整半复用
|
|
255
|
+
|
|
256
|
+
上一轮把节点那一半在「逐元素同引用」时整半跳过;这一轮把同一套判据补到线路侧,并额外核对隐藏集合、通道声明、通道车道输入与线路样式快照。命中后不再重跑 `resolveLines` 与其索引 / 虚线槽位 / 层序 / 包围盒,追加补线和增量改线则把新路径并进线路半包围盒,防止下一次回灌沿用旧范围。
|
|
257
|
+
|
|
258
|
+
`selftest-perf.html` 用 20000 点 / 8000 线、同一批对象连续回灌 5 次,取中位:
|
|
259
|
+
|
|
260
|
+
| 场景 | 优化前 | 优化后 |
|
|
261
|
+
| --- | --- | --- |
|
|
262
|
+
| 同一批点线原样回灌(20000 点 / 8000 线) | 14.3 ms | **6.3 ms** |
|
|
263
|
+
|
|
264
|
+
优化后的 5 次读数依次是 5.6 / 6.3 / 6.3 / 6.4 / 10.7 ms;同页新增三条断言分别核对条数与线路实例数不变、通道声明未变时派生折线原样保留、换通道骨架时线路几何必须重推。该快路只对原样回灌生效,内容真的换了或删除导致下标平移时仍走原来的整份 / 增量路径。
|
|
265
|
+
|
|
266
|
+
#### 第十七轮:线路样式窄路 —— 只换线宽 / 颜色不再重跑整份解析
|
|
267
|
+
|
|
268
|
+
上一轮把「同一批点线原样回灌」收掉,这一轮继续看样式面板上最常发生的补丁:只拖线宽、只换线色。点侧已有尺寸 / 配色两条窄路,线侧仍会在 `resolveLineStyleInto` 里重跑规则、热力、虚线、阴影与效果归一化。现在把「基准宽 / 实际半宽 / 颜色 / 透明度」抽成 `resolveLinePaintInto`(整份解析与窄路共用),命中窄路时逐条只重算这四项并补实例槽位;规则、热力图、虚线、方向箭头等结构输入存在时仍回退整份解析。`getLineStyle(index)` 读的是同一条链的最新结果。
|
|
269
|
+
|
|
270
|
+
1000 点 + 50000 线,连续 5 次交替(`node scripts/bench-scale.mjs --points=1000 --lines=50000 --gpu=true`;profile 时另用临时表达式文件挂 `--profileFile`,跑完即删):
|
|
271
|
+
|
|
272
|
+
| 操作 | 改前 | 改后 | 稳态收益 |
|
|
273
|
+
| --- | --- | --- | --- |
|
|
274
|
+
| 只换 `lineStyle.color` | 27 / 11.7 / 10.1 / 10.1 / 10.5 ms | 18.9 / 10.8 / 7.4 / 6.1 / 6.6 ms | 约 40% |
|
|
275
|
+
| 只换 `lineStyle.width` | 20.4 / 10.4 / 9.2 / 10.2 / 10.4 ms | 17.3 / 7.8 / 6.2 / 5.8 / 6.4 ms | 约 40% |
|
|
276
|
+
|
|
277
|
+
首轮包含槽位表与交互期细线账本的首次重建;稳态从 9 ~ 11.7 ms 降到 5.8 ~ 7.4 ms。改后的 CPU profile(42 ms 采样窗口,208 samples):`patchLineSlotsInner` 30.8%、`patchLineSlots` 17.3%、`applyLineNarrowFast` 13.0%、`estimateLinePatchRuns` 8.7%、`bufferSubData` 5.8%、`resolveLinePaintInto` 3.8%;原先的 `applyResolvedStyles` / `refreshLine` 已不在热点列表里。这说明剩余成本主要是「实例槽位补丁 + 上传」,继续压缩解析侧能拿的收益已经很小。
|
|
278
|
+
|
|
279
|
+
正确性回归:`selftest-perf.html` 新增 4 条断言,覆盖窄路后 `getLineStyle` 的最新读数、`dataVersion` 不递增、逐线自身线宽 / 颜色优先、虚线图案不被覆盖,以及存在线路规则时回退整份解析且规则仍压过新的全局样式;另加 1 条 DIAG 记录 2000 线的窄路耗时。`selftest-demos.html` 覆盖 `flyToCamera`、`getLineStyle`、`dataVersion` 三个 demo 读数与 `onDataChange` 同步。
|
|
280
|
+
|
|
281
|
+
#### 第十八轮:程序化相机运动复用交互快路径,关闭聚合不再空转整排
|
|
282
|
+
|
|
283
|
+
这一轮先查「没有指针事件时,相机 API 为什么没吃到交互期的优化」。`zoomBy` / `setCamera` / `centerOn` / `flyToCamera` 最终都走 `notifyCameraChange()`,但轻量画法的判定只看 `interacting` 与动画,所以外部控件、定时视角同步与飞行动画仍按全质量路径绘制。另一半问题是聚合脏标记:只要缩放比例变了就无条件 `clusterDirty = true`,即使 `pointCluster` 根本没开,下一帧也会跑一次 `layoutScene()` 并重写 / 上传整份点实例缓冲。
|
|
284
|
+
|
|
285
|
+
现在的口径:
|
|
286
|
+
|
|
287
|
+
- **聚合只在该算的时候算**:关闭聚合、当前缩放档不聚合且上一帧也没有聚合圆 / 隐藏点时,`flushPointClusterLayout()` 只收掉脏标记,不调用 `layoutScene()`。真正跨出聚合档、关配置、改数据 / 选中 / 拖动时仍立即重排,不能延迟状态生效。
|
|
288
|
+
- **相机运动期只推迟成员关系**:相机导致的聚合成员变化先沿用上一档,停稳后一次重算;平移不标聚合脏,因为聚合半径是屏幕像素、比例没变。
|
|
289
|
+
- **程序化运动复用两种轻量画法**:真实相机位置变化后 160 ms 内,非 MSAA 后备缓冲与 `gl.LINES` 细线路径同时生效;每次真实变化重新计时,同一位置重复 `setCamera` 不续期。停稳后补一张全质量帧,刷新通道宽度并恢复符号预烤。
|
|
290
|
+
- **停稳条件不只盯轻量帧**:如果当前场景没有线、又显式关了 `interactionNoMsaa`,运动帧可能一种轻量几何都没画;只要还有被推迟的聚合重排,计时器也补一帧,避免聚合结果停在旧缩放档。
|
|
291
|
+
|
|
292
|
+
实测环境与命令:无头 Chrome + ANGLE(AMD Radeon Graphics,D3D11),1280×800,10 万点 / 5 万线,`quality: 'high'`:
|
|
293
|
+
|
|
294
|
+
```powershell
|
|
295
|
+
node scripts/bench-scale.mjs --points=100000 --lines=50000 --gpu=true --panFrames=40 --zoomFrames=30
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
| 指标 | 改前 | 改后 |
|
|
299
|
+
| --- | --- | --- |
|
|
300
|
+
| 连续缩放 p50 | 67.9 ms | **22.5 ms** |
|
|
301
|
+
| 连续缩放 p95 | 76.2 ms | **25.1 ms** |
|
|
302
|
+
| 连续缩放 avg | 60.77 ms | **20.57 ms** |
|
|
303
|
+
| 连续平移 p50 | 17.1 ms | 17.2 ms(不变,属于帧节拍波动) |
|
|
304
|
+
| `refresh()` | 56.2 ms | **53.7 ms** |
|
|
305
|
+
|
|
306
|
+
改后终态读数为 `thinLines: false`、`noMsaa: false`、`frameMs: 0.10`;CPU profile 里主要是 idle / program,`render` 自身约占 0.1%。所以这里的收益不是把引擎单帧压到 1 ms,而是消除了「关闭聚合时每次缩放都整份重排 + 上传」以及运动期的 MSAA / 细线光栅化成本;剩余时间基本是 GPU 光栅化与 60 Hz 帧节拍。`selftest-perf.html` 增加 7 条断言(其中 1 条覆盖没有轻量帧时的延迟聚合补算),四页回归 `full 94 / demos 365 / docs 134 / perf 181` 共 **774** 条通过 / 0 失败;公开实例成员、options 与数据字段计数不变。
|
|
307
|
+
|
|
308
|
+
#### 第十九轮:线片段着色管线专用化
|
|
309
|
+
|
|
310
|
+
这一轮先回答「为什么上一轮之后还是感觉没提升多少」。10 万线交互的 CPU profile 仍约 **98.6% idle**、`render` 自身约 **0.1%**,说明主线程不是瓶颈;上一轮省掉的是场景重排、实例上传与相机排帧。剩余成本落在 GPU:`gl.LINES` 细线虽然已经避开细长三角形,但片元仍复用了通用线路着色器,逐像素执行虚线取模、`smoothstep`、边缘覆盖率与光晕分支,即使这一遍画的是 1px 实线。
|
|
311
|
+
|
|
312
|
+
- `THIN_LINE_FRAGMENT_SHADER`:交互期 `gl.LINES` 只把实例颜色写到输出,顶点侧也不再携带虚线 / 边缘 / 光晕 varying。
|
|
313
|
+
- `SOLID_LINE_FRAGMENT_SHADER`:整批无虚线且这一遍不是热力光晕的四边形线路只算颜色与(非 MSAA 帧的)覆盖率;有虚线或光晕仍走 `LINE_FRAGMENT_SHADER`。
|
|
314
|
+
- `engine.js` 的 `drawLineBatch` 按批选择管线,`refreshLineThinLedger` 同时提供「是否全实线」;端点圆头保持绘制,所有交互帧仍是全分辨率,停稳 160 ms 后照旧补 MSAA 静态帧。
|
|
315
|
+
|
|
316
|
+
实测环境:无头 Chrome + ANGLE(AMD Radeon Graphics,D3D11),1280×800,`quality: 'high'`,三次运行取中位。
|
|
317
|
+
|
|
318
|
+
| 场景 | 改前 p50 / p95 | 改后 p50 / p95 |
|
|
319
|
+
| --- | --- | --- |
|
|
320
|
+
| 10 万点 / 5 万线缩放 | 23.2 / 28.6 ms | **16.7 / 16.8 ~ 16.9 ms** |
|
|
321
|
+
| 10 万点 / 10 万线缩放 | 42.6 / 46.3 ms | **18.0 / 21.4 ms** |
|
|
322
|
+
| 10 万点 / 10 万线、2px 实线(只走四边形轻量片元) | 82.4 / — | **63.9 / — ms** |
|
|
323
|
+
|
|
324
|
+
16 ~ 18 ms 已接近 60Hz 帧节拍,不能再用它宣称无上限提升;要继续明显提速,只能减少可见线段数或屏幕覆盖面积。细线快路径的实际门槛是最大半宽 ≤ 0.6 设备像素且无虚线(dpr = 1 时约 1.2px 线宽),2px 实线不会走 `gl.LINES`,这也是「某些场景感觉提升有限」的直接原因。`selftest-perf.html` 新增 1 条像素级对拍,验证细线与四边形在同一交互状态下位置 / 颜色一致、不会整批画丢;该页 182 / 1(共 183 条,标签读数失败在 HEAD 已复现)。
|
|
325
|
+
|
|
254
326
|
### WebGPU 值不值得上
|
|
255
327
|
|
|
256
328
|
| 维度 | 现状 | WebGPU 能带来的变化 |
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
| `channelTangentInset` | `number \| null` | `null` | 两端切点往节点里收多少 CSS 像素:缺省(`null`)按成员回线里最粗那条的线宽收,线因此不会从节点边缘探出去;`0` 表示切点正好落在节点边上,**负数外收**(切点往节点外让、回线整段比节点宽);单个通道可用 `tangentInset` 覆盖;内收两侧合计最多收掉节点宽度的 40%,外收单侧最多让出 50% |
|
|
27
27
|
| `channelMaxGroups` | `number` | `0` | 一条通道最多几个分组(`0` 表示不限):新增通道时用来判断还能不能变成新分组,见「新增通道」 |
|
|
28
28
|
| `channelGroupMaxLines` | `number` | `0` | 一个分组最多几条回线(`0` 表示不限):新增通道时用来判断还能不能并进某一组,见「新增通道」 |
|
|
29
|
-
| `channelDraftStyle` | `GisViewChannelDraftStyle` | 蓝色 2px + 两端圆点,箭头关闭 | 新增通道草稿预览的全局样式:`color` / `width` / `dot` / `dotColor` / `arrow` / `arrowSize` / `arrowPositions` / `arrowReverse` / `arrowColor` / `circuitSpacing` / `opacity` / `customDraw`;`beginAddChannel({ channelDraftStyle })` 可按这一次草稿覆盖,`updateAddChannelStyle(patch)` 可在草稿期间增量修改 |
|
|
29
|
+
| `channelDraftStyle` | `GisViewChannelDraftStyle` | 蓝色 2px + 两端圆点,箭头关闭 | 新增通道草稿预览的全局样式:`color` / `width` / `dot` / `dotColor` / `dots`(`false` 关示例点,或 `{ show, size, color, shape, from, to }` 分端配置;示例点固定在点中的节点中心)/ `layer`(`'above'` 默认,`'below-points'` 让示例线 / 箭头 / `customDraw` 位于真实节点之下)/ `arrow` / `arrowSize` / `arrowPositions` / `arrowReverse` / `arrowColor` / `circuitSpacing` / `opacity` / `customDraw`;`beginAddChannel({ channelDraftStyle })` 可按这一次草稿覆盖,`updateAddChannelStyle(patch)` 可在草稿期间增量修改 |
|
|
30
30
|
| `webglLayers` | `GisViewWebGLLayer[]` | `[]` | WebGL 自定义绘制层:每层提供 `draw({ gl, canvas, viewport, camera, frame, project, unproject, requestRender })`,在内置内容之后按 `order` 绘制;运行时也可用 `addWebGLLayer` / `updateWebGLLayer` / `removeWebGLLayer` 维护 |
|
|
31
31
|
| `background` | `GisViewBackground` | 浅色底 | 背景层,支持底色、图片与 GeoJSON |
|
|
32
32
|
| `pointStyle` | `GisViewPointStyle` | 见下 | 点的默认样式,可被单个点覆盖;运行时按字段合并用 `updatePointStyle(patch)`(`updateOptions({ pointStyle })` 是整份换) |
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
| `labelStates` | `GisViewLabelState[]` | 无 | 标签的运行时状态(`getLabelStates()` 的那一份:拖出来的偏移、改过的内容与样式、运行时加的标签、隐藏覆盖):创建时喂回来就回显,等价于创建之后调 `setLabelStates(states)`;`updateOptions({ labelStates })` 同样认。`exportData({ format: 'input' })` 的结果里就叫 `labelStates`,存档 → 回灌直接接上 |
|
|
44
44
|
| `graphics` | `GisViewGraphic[]` | 无 | 与节点无关的扩展图形:按世界坐标放 SVG 路径 / 图片 / Canvas,支持锚点、偏移、旋转、透明度、`zIndex` 与 `scaleWithView`;位于画布之上、标签之下,运行时用 `addGraphic` / `addGraphics` / `updateGraphic` / `removeGraphic` / `clearGraphics` 增删改,见「扩展图形(graphic)」 |
|
|
45
45
|
| `tooltip` | `GisViewTooltipOptions` | 无 | 悬停提示:点 / 线 / 通道分别配置内容,见「悬浮提示」 |
|
|
46
|
-
| `minimap` | `GisViewMinimapOptions \| null` | 无 | 内置鹰眼图:位置、尺寸、节点 / 线路 / 视口框三份样式与交互都可配,`extent` 决定小图按数据范围还是「数据 ∪ 底图」铺(默认 `auto`,GeoJSON 底图不会缩成一个点),`zoomable`
|
|
46
|
+
| `minimap` | `GisViewMinimapOptions \| null` | 无 | 内置鹰眼图:位置、尺寸、节点 / 线路 / 视口框三份样式与交互都可配,`extent` 决定小图按数据范围还是「数据 ∪ 底图」铺(默认 `auto`,GeoJSON 底图不会缩成一个点),`extentFollowContent` 默认 `false`,首次铺好后内容变化不再改小图范围;`extentFollowCamera` 默认 `false`、打开后才允许 `auto` 范围随相机收窄。`zoomable` 三态互斥:`false` 关闭、`true` 手动缩放小图自身、`'follow'` 让整体范围跟随主图(`followZoomScale` 是主图倍数的指数,跟随模式下 `setMinimapZoom` / `zoomMinimapBy` 不抢控制权);空白处拖动可平移小图或直接框选让主图显示过去(`dragAction`,`box` 不依赖缩放,手动模式下 Ctrl / ⌘ 才切换动作),每格倍率 `zoomStep`。通道还能只画一根;小图同样支持规则(`pointRules` / `lineRules`,缺省沿用主图规则的颜色、层级、最终节点尺寸与图标、样式链线宽,节点 / 线路尺寸按两边视口比例缩放且不受主图相机倍数影响),可以只画某几层(`levels`)、关掉分层叠画(`layered`)、按三组系数给节点与线路定尺寸(整体倍数 `pointSizeScale` / `lineWidthScale` 对自有与继承要素都生效;跟随小图倍数 `pointZoomScale` / `lineZoomScale` 在小图自身放大时也作用于继承要素;跟随主视图地图倍数 `pointMapZoomScale` / `lineMapZoomScale` 只作用于自有规则 / 样式),视口框与框选矩形的颜色 / 背景 / 边框 / 圆角也能配(`boxStyle` / `selectStyle`),`extent` 还能直接写死一份世界范围、容器可加 `className` / `style`、`layers` 按 `placement` 分数据前 / 数据后、段内按 `order` 拆出多层自绘内容(旧 `draw` 钩子仍兼容并排在最后)、`onInteraction` 在手势结束时给出类型 / 世界坐标 / 相机、`maxPixelRatio` 限制备份倍率上限,不配则不产生任何 DOM,见「鹰眼图」 |
|
|
47
47
|
| `filter` | `GisViewFilterInput \| null` | 无 | 初始筛选条件,等价于创建之后调用 `setFilter`;`mode` 缺省 `'hide'`,写 `'remove'` 则删除不命中的要素,见「筛选」 |
|
|
48
48
|
| `filterWorker` | `boolean \| GisViewFilterWorkerOptions` | `{ threshold: 20000 }` | 筛选是否用 Web Worker 计算:默认点 + 线总数超过阈值才用,`false` 表示始终同步算 |
|
|
49
49
|
| `searchWorker` | `boolean \| GisViewSearchWorkerOptions` | `{ threshold: 20000 }` | [异步搜索](14-视图与筛选.md#搜索与定位)是否用 Web Worker 计算:默认点 + 线总数超过阈值才用,`false` 表示 `searchAsync` 也同步算;同步的 `search` 一直在主线程算,不受这一项影响 |
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
| `pixelRatio` | `number` | `devicePixelRatio` | 手动指定设备像素比(夹在 0.5 ~ 3);宿主缩放(CSS `zoom` / `transform: scale`)的比例会乘在它上面,合计夹在 0.5 ~ 4 |
|
|
94
94
|
| `maxCanvasPixels` | `number` | `4000000` | 画布总像素预算:`cssWidth × cssHeight × 倍率²` 超过它时按 `sqrt(预算 / CSS 面积)` 压渲染倍率(全屏与高分屏不因像素数翻十倍而掉帧);传 `0` 不设上限 |
|
|
95
95
|
| `antialias` | `boolean` | 开(软件光栅自动关) | 画布是否开 MSAA。同一份十万级线段实测:MSAA 4× 下单帧光栅化是关掉时的近 5 倍(见「画质」里的实测表),关掉能明显提速、代价是线条与圆形边缘有锯齿;当前实际状态见 `getStats().antialias`(软件光栅下引擎默认关,写 `true` 可强制打开) |
|
|
96
|
-
| `interactionThinLines` | `boolean` | `true` |
|
|
96
|
+
| `interactionThinLines` | `boolean` | `true` | 交互期细线快路径:可见线段最大半宽 ≤ 0.6 设备像素(dpr = 1 时约 1.2px 线宽)且整批没有虚线时,拖动 / 缩放期间改用 `gl.LINES` 画(1 设备像素、无光晕与虚线),停手立刻回到四边形展开。2px 实线不会走这一档,但全实线四边形另有轻量片元。位置不跳、悬停 / 选中不受影响;这一帧走没走快路径见 `getStats().thinLines`,实测见「画质」 |
|
|
97
97
|
| `interactionNoMsaa` | `boolean` | `true` | 非 MSAA 后备缓冲(交互 / 动画期):拖动 / 缩放 / 框选期间与动画在跑的那些帧,整帧先画进一张不带 MSAA 的后备贴图,帧末整幅贴回画布;停手(或动画停帧)之后那一帧照旧直接画进带 MSAA 的画布,所以静止画面逐像素不变(代价是这些活动帧的边缘暂时没有抗锯齿)。十万级实测交互期单帧 133 → 36.6 ms、拖动 p50 130 → 16 ~ 22 ms,动画帧 212 → 53 ms/帧(只开涟漪 187 → 48、只开线路动点 199 → 47);透明底 / 自定义底色的导出场景与没开 MSAA 的画布不走这条,这一帧走没走见 `getStats().noMsaa`,实测见「画质」 |
|
|
98
98
|
| `renderer` | `'auto' \| 'webgl2' \| 'webgpu'`(也认布尔开关) | `'auto'` | 渲染后端开关:当前实装的绘制后端只有 WebGL2 —— 十万级下 `frameMs` 只有 0.05 ~ 0.2 ms,开销在填充率与 DOM 覆盖层上,换 WebGPU 省不到(第 18 章),所以 `'auto'` 只会在后台探一次 WebGPU 能力、绘制仍走 WebGL2,`'webgl2'` 连探测都不跑(无 GPU 的远程桌面里省一次 `requestAdapter`),`'webgpu'` 探完明确报一句「已回退 WebGL2、为什么」;`true` / `false` 等价于 `'webgpu'` / `'webgl2'`。读数用 `getRendererInfo()`,见「渲染后端(WebGPU 开关)」 |
|
|
99
99
|
| `ariaLabel` | `string` | `GIS 视图` | 画布的无障碍名称 |
|
|
@@ -887,7 +887,7 @@ view.updateOptions({ quality: 'high' })
|
|
|
887
887
|
|
|
888
888
|
- **类型**:`boolean`
|
|
889
889
|
- **默认值**:`true`
|
|
890
|
-
-
|
|
890
|
+
- **说明**:交互期细线快路径:可见线段最大半宽 ≤ 0.6 设备像素(dpr = 1 时约 1.2px 线宽)且整批没有虚线时,拖动 / 缩放期间改用 `gl.LINES` 画(1 设备像素、无光晕与虚线),停手立刻回到四边形展开。2px 实线不会走这一档,但全实线四边形另有轻量片元。位置不跳、悬停 / 选中不受影响;这一帧走没走快路径见 `getStats().thinLines`,实测见「画质」
|
|
891
891
|
- **参考**:见「MSAA 与交互期细线」一节,子字段在那里的表里逐个展开
|
|
892
892
|
|
|
893
893
|
#### `interactionNoMsaa`
|
|
@@ -1004,7 +1004,7 @@ view.setFilter(null) // 清掉筛选
|
|
|
1004
1004
|
|
|
1005
1005
|
- **类型**:`GisViewMinimapOptions | null`
|
|
1006
1006
|
- **默认值**:无
|
|
1007
|
-
- **说明**:内置鹰眼图:位置、尺寸、节点 / 线路 /
|
|
1007
|
+
- **说明**:内置鹰眼图:位置、尺寸、节点 / 线路 / 视口框三份样式与交互都可配;`position` / `margin` 定角落,`offset` 相对角落动态移动整张图,`container` 可挂到外部 `div`(`getMinimapElement()` 取根节点做整图拖动)。`extent` 决定小图按数据范围还是「数据 ∪ 底图」铺(默认 `auto`,GeoJSON 底图不会缩成一个点);`extentFollowContent` 默认 `false`,首次铺好后筛选 / 显隐 / 增删内容不再改范围与缩放,打开后才跟进当前可见内容;`extentFollowCamera` 默认 `false`、打开后才允许 `auto` 范围随相机收窄。`zoomable` 三态互斥:`false` 关闭、`true` 手动缩放小图自身、`'follow'` 让整体范围跟随主图(`followZoomScale` 是主图倍数的指数;跟随模式下 `setMinimapZoom` / `zoomMinimapBy` 不抢控制权,`zoom` 是基准倍数);空白处拖动可平移小图或直接框选让主图显示过去(`dragAction`,`box` 不依赖缩放,手动模式下 Ctrl / ⌘ 才切换动作),每格倍率 `zoomStep`。通道关闭 `channelCircuits` 时按当前可见成员逐顶点平均成一根居中代表线;小图同样支持规则(`pointRules` / `lineRules`,缺省沿用主图规则的颜色 / 层级、最终节点尺寸与图标及样式链线宽,节点 / 线路尺寸按两边视口比例缩放且不受主图相机倍数影响),可以只画某几层(`levels`)、关掉分层叠画(`layered`)、按三组系数给节点与线路定尺寸(整体倍数 `pointSizeScale` / `lineWidthScale` 对自有与继承要素都生效;跟随小图倍数 `pointZoomScale` / `lineZoomScale` 在小图自身放大时也作用于继承要素;跟随主视图地图倍数 `pointMapZoomScale` / `lineMapZoomScale` 只作用于自有规则 / 样式),视口框与框选矩形的颜色 / 背景 / 边框 / 圆角也能配(`boxStyle` / `selectStyle`),`backgroundStyle` 显式设置时接管画布底色,`extent` 还能直接写死一份世界范围、容器可加 `className` / `style`、`layers` 按 `placement` 分数据前 / 数据后、段内按 `order` 拆出多层自绘内容(旧 `draw` 钩子仍兼容并排在最后)、`onInteraction` 在手势结束时给出类型 / 世界坐标 / 相机、`maxPixelRatio` 限制备份倍率上限,不配则不产生任何 DOM,见「鹰眼图」
|
|
1008
1008
|
- **参考**:见「鹰眼图」一节,子字段在那里的表里逐个展开
|
|
1009
1009
|
|
|
1010
1010
|
```js
|
|
@@ -1014,6 +1014,15 @@ createGisView(container, {
|
|
|
1014
1014
|
width: 220,
|
|
1015
1015
|
height: 130,
|
|
1016
1016
|
position: 'bottom-right',
|
|
1017
|
+
offset: [0, 0],
|
|
1018
|
+
container: '#minimap-host',
|
|
1019
|
+
backgroundStyle: 'rgba(255, 255, 255, 0.92)',
|
|
1020
|
+
extent: 'auto',
|
|
1021
|
+
extentFollowContent: false,
|
|
1022
|
+
extentFollowCamera: false,
|
|
1023
|
+
dragAction: 'box',
|
|
1024
|
+
zoomable: 'follow',
|
|
1025
|
+
followZoomScale: 0.8,
|
|
1017
1026
|
levels: [1, 5, 20],
|
|
1018
1027
|
pointStyle: { color: '#2f6fed' },
|
|
1019
1028
|
layers: [
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
| `onCameraChange` | `GisViewCamera` | 平移或缩放后触发 |
|
|
37
37
|
| `onViewport` | `GisViewViewport` | 视口尺寸 / 显示比例变化(画布按新尺寸重铺之后才发):`{ cssWidth, cssHeight, pixelRatio, displayScale }`,自建面板与小图按它跟着调整 |
|
|
38
38
|
| `onStats` | `GisViewEngineStats` | 渲染统计(点数、线数、线路批次真正铺的段数 `lineInstances`、符号数、绘制次数、`fps` / `idle` / 帧耗时、拾取耗时 `pickMs`、密度场读数 `heatDensity`,以及这一帧的光栅与线段路径 `antialias` / `software` / `thinLines`),按 `statsInterval` 节流(默认 250ms 一次)。静止画面按需渲染,这时 `idle` 为 `true`、`fps` 为 `0`,`frameMs` 是最近一帧的耗时;首帧一定会报一次(面板打开就有读数,不会一直空着) |
|
|
39
|
-
| `onDataChange` | `GisViewDataChangePayload` | 数据变更的统一出口:调用接口改数据、拖拽 / 复制 / 合并落地、拐点增删、通道新增 / 移除 / 分组都会发,载荷带动作 `type`、最新数据与条数,见「数据变更与其它事件」 |
|
|
39
|
+
| `onDataChange` | `GisViewDataChangePayload` | 数据变更的统一出口:调用接口改数据、拖拽 / 复制 / 合并落地、拐点增删、通道新增 / 移除 / 分组都会发,载荷带动作 `type`、数据修订号 `dataVersion`、最新数据与条数,见「数据变更与其它事件」 |
|
|
40
40
|
| `onSelectChange` | `GisViewSelectChangePayload` | 选中集变化:只在选中集真的变了时发一条(框选过程中的重复同步与数据补发都不发),接口选中也走它;载荷带 `ids` / `count` / 各类型条数与来源 `cause` |
|
|
41
41
|
| `onShortcut` | `GisViewShortcutPayload` | 快捷键命中:`action`(`cancel` / `copy` / `paste` / `remove` / `fitView` / `undo` / `redo`)、`key` 与 `handled`(组件有没有接住,`false` 时可以接着做自己的处理 —— 没得撤销 / 重做时也是 `false`) |
|
|
42
42
|
| `onRender` | `GisViewRenderPayload` | 节流过的帧回调:`onStats` 的读数 + `frame` / `interval` / `timestamp` 与当前 `camera`,间隔见 `renderEmitInterval` |
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
|
|
54
54
|
组件的交互回调很多(选中、拖拽、复制、合并、拐点、通道…),要把「数据变了」写回自己的状态不必每个都接一遍:
|
|
55
55
|
`onDataChange` 是数据变更的统一出口,`type` 说明这次是什么动作,`points` / `lines` / `channels`
|
|
56
|
-
就是组件内部那一份数据(只读引用),`counts`
|
|
56
|
+
就是组件内部那一份数据(只读引用),`counts` 是三个条数,`dataVersion` 是数据修订号:每次数据变更 +1,只改全局配置 / 样式时不递增。
|
|
57
57
|
|
|
58
58
|
```js
|
|
59
59
|
const view = createGisView('#map', {
|