gis-view-webgl2 0.1.13 → 0.1.15

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 (62) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.d.ts +140 -60
  3. package/dist/index.js +1 -1
  4. package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +73 -5
  5. package/docs/GisView.md +49 -49
  6. 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 +87 -16
  7. package/docs/demos/ApiCoverageDemo.vue +1 -5
  8. package/docs/demos/BackendSyncDemo.vue +1 -2
  9. package/docs/demos/BackgroundDemo.vue +68 -1
  10. package/docs/demos/BasicDemo.vue +76 -76
  11. package/docs/demos/BatchAddDemo.vue +2 -1
  12. package/docs/demos/ChannelDemo.vue +1 -3
  13. package/docs/demos/ClusterDemo.vue +48 -1
  14. package/docs/demos/CopyMergeDemo.vue +899 -904
  15. package/docs/demos/DemoShell.vue +336 -336
  16. package/docs/demos/EventDemo.vue +300 -300
  17. package/docs/demos/ExtensionDemo.vue +200 -200
  18. package/docs/demos/GisViewDemo.vue +64 -64
  19. package/docs/demos/LabelDemo.vue +489 -489
  20. package/docs/demos/StyleDemo.vue +67 -67
  21. package/docs/demos/api-index.js +24 -29
  22. package/docs/demos/demos.js +92 -92
  23. package/docs/demos/gis-view-demo/useGisViewDemo.js +19 -14
  24. package/docs/demos/shared/demoData.js +107 -107
  25. package/docs/demos/shared/demoStyle.css +249 -249
  26. package/docs/format/02-/350/212/202/347/202/271/344/270/216/347/272/277/350/267/257.md +3 -3
  27. 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 -0
  28. package/docs/from0/01-/345/205/210/346/212/212/345/234/260/345/233/276/346/203/263/346/270/205/346/245/232.md +8 -7
  29. package/docs/index.html +3 -3
  30. package/docs/internals/04-/347/233/270/346/234/272/345/235/220/346/240/207/344/270/216/345/203/217/347/264/240.md +6 -4
  31. package/docs/internals/14-/350/203/214/346/231/257/345/261/202.md +2 -2
  32. package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +36 -16
  33. package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +38 -84
  34. package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +36 -19
  35. 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 +1 -1
  36. 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 +7 -7
  37. package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +15 -15
  38. 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 +1 -1
  39. package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +6 -0
  40. package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +1 -1
  41. package/docs/manual/15-/345/257/274/345/207/272/344/270/216/351/233/206/346/210/220.md +2 -0
  42. package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +10 -8
  43. package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +11 -7
  44. package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +27 -8
  45. package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +27 -4
  46. 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 +3 -3
  47. package/docs/playground/index.html +1 -1
  48. package/docs/sample-document/345/255/227/346/256/265/350/257/246/350/247/243.md +2 -2
  49. package/docs/steps/check-doc-truth.mjs +1 -1
  50. package/docs/steps/selftest-actions.html +4 -4
  51. package/docs/steps/selftest-data.html +5 -5
  52. package/docs/steps/selftest-demos.html +1683 -1619
  53. package/docs/steps/selftest-docs.html +4 -4
  54. package/docs/steps/selftest-effects.html +1 -1
  55. package/docs/steps/selftest-features.html +548 -47
  56. package/docs/steps/selftest-full.html +566 -566
  57. package/docs/steps/selftest-labels.html +647 -647
  58. package/docs/steps/selftest-perf.html +2282 -2237
  59. package/docs/steps/selftest-select.html +53 -14
  60. package/docs/steps/step-10-full.js +1 -4
  61. package/docs/steps/step-12-events.js +1 -4
  62. package/package.json +43 -43
@@ -1,17 +1,17 @@
1
- <script setup>
2
- /**
1
+ <script setup>
2
+ /**
3
3
  * 扩展能力:用同一个视图把六个扩展点串起来 ——
4
4
  * 运行时插件(view.use)、自定义图元(registerSymbol)、自定义条件运算符(registerOperator)
5
5
  * 自定义导出格式(defineExportFormat)、WebGL 自定义层(addWebGLLayer)与实例命令(registerCommand)。
6
6
  * 每一块都可单独开关,读数里能直接看到注册表与可见数据。
7
- */
8
- import { onBeforeUnmount, onMounted, ref } from 'vue'
9
- import { createGisView, defineExportFormat } from '../../src/index.js'
10
- import { buildDemoData } from './shared/demoData.js'
11
- import './shared/demoStyle.css'
12
-
13
- const emit = defineEmits(['notice'])
14
- const container = ref(null)
7
+ */
8
+ import { onBeforeUnmount, onMounted, ref } from 'vue'
9
+ import { createGisView, defineExportFormat } from '../../src/index.js'
10
+ import { buildDemoData } from './shared/demoData.js'
11
+ import './shared/demoStyle.css'
12
+
13
+ const emit = defineEmits(['notice'])
14
+ const container = ref(null)
15
15
  const operatorOn = ref(false)
16
16
  const symbolOn = ref(false)
17
17
  const pluginOn = ref(false)
@@ -23,15 +23,15 @@ const webglDrawCount = ref(0)
23
23
  const commandRegistered = ref(false)
24
24
  const commandReadout = ref('实例命令尚未注册。注册后可以执行 focusHighestLoad。')
25
25
  const readout = ref('正在创建视图…')
26
- const exportText = ref('尚未导出。点上面的按钮,会走 defineExportFormat 注册的同步适配器。')
27
-
28
- const dataset = buildDemoData({ count: 18, channels: 0 })
29
- const points = dataset.points.map((point, index) => ({ ...point, extension_index: index }))
30
- const lines = dataset.linesWithoutChannel
31
-
32
- let view = null
33
- let disposeOperator = null
34
- let disposeSymbol = null
26
+ const exportText = ref('尚未导出。点上面的按钮,会走 defineExportFormat 注册的同步适配器。')
27
+
28
+ const dataset = buildDemoData({ count: 18, channels: 0 })
29
+ const points = dataset.points.map((point, index) => ({ ...point, extension_index: index }))
30
+ const lines = dataset.linesWithoutChannel
31
+
32
+ let view = null
33
+ let disposeOperator = null
34
+ let disposeSymbol = null
35
35
  let disposePlugin = null
36
36
  let disposeExport = null
37
37
  let disposeWebgl = null
@@ -128,28 +128,28 @@ const drawWebglExtension = ({ gl, canvas, viewport, frame, project }) => {
128
128
  emit('notice', `WebGL 自定义层绘制失败:${error instanceof Error ? error.message : String(error)}`)
129
129
  }
130
130
  }
131
-
132
- /** 自定义图元:外圈实心 + 十字,颜色 / 描边 / 尺寸都取组件递进来的读数 */
131
+
132
+ /** 自定义图元:外圈实心 + 十字,颜色 / 描边 / 尺寸都取组件递进来的读数 */
133
133
  const paintSpark = (context, info) => {
134
- const centerX = info.width / 2
135
- const centerY = info.height / 2
136
- const radius = Math.min(info.width, info.height) * 0.31
137
- const stroke = Math.max(1, info.strokeWidth * info.scale)
138
- context.clearRect(0, 0, info.width, info.height)
139
- context.beginPath()
140
- context.arc(centerX, centerY, radius, 0, Math.PI * 2)
141
- context.fillStyle = info.color
142
- context.fill()
143
- context.lineWidth = stroke
144
- context.strokeStyle = info.strokeColor
145
- context.stroke()
146
- context.beginPath()
147
- context.moveTo(centerX - radius * 0.52, centerY)
148
- context.lineTo(centerX + radius * 0.52, centerY)
149
- context.moveTo(centerX, centerY - radius * 0.52)
150
- context.lineTo(centerX, centerY + radius * 0.52)
151
- context.lineWidth = Math.max(1, stroke * 0.72)
152
- context.strokeStyle = 'rgba(255, 255, 255, 0.92)'
134
+ const centerX = info.width / 2
135
+ const centerY = info.height / 2
136
+ const radius = Math.min(info.width, info.height) * 0.31
137
+ const stroke = Math.max(1, info.strokeWidth * info.scale)
138
+ context.clearRect(0, 0, info.width, info.height)
139
+ context.beginPath()
140
+ context.arc(centerX, centerY, radius, 0, Math.PI * 2)
141
+ context.fillStyle = info.color
142
+ context.fill()
143
+ context.lineWidth = stroke
144
+ context.strokeStyle = info.strokeColor
145
+ context.stroke()
146
+ context.beginPath()
147
+ context.moveTo(centerX - radius * 0.52, centerY)
148
+ context.lineTo(centerX + radius * 0.52, centerY)
149
+ context.moveTo(centerX, centerY - radius * 0.52)
150
+ context.lineTo(centerX, centerY + radius * 0.52)
151
+ context.lineWidth = Math.max(1, stroke * 0.72)
152
+ context.strokeStyle = 'rgba(255, 255, 255, 0.92)'
153
153
  context.stroke()
154
154
  }
155
155
  /** 同名覆盖的第二支画笔:菱形,用来演示 registerSymbol 重新注册后贴图与标签锚点一起更新 */
@@ -174,13 +174,13 @@ const paintSparkDiamond = (context, info) => {
174
174
  context.fillStyle = 'rgba(255, 255, 255, 0.92)'
175
175
  context.fill()
176
176
  }
177
-
177
+
178
178
  const visiblePointCount = () => view?.getVisibleData()?.points?.length ?? points.length
179
179
  const COMMAND_NAME = 'focusHighestLoad'
180
180
  const refreshReadout = () => {
181
- if (!view) {
182
- return
183
- }
181
+ if (!view) {
182
+ return
183
+ }
184
184
  const operators = view.listOperators()
185
185
  const symbols = view.listSymbols()
186
186
  const commands = view.listCommands()
@@ -194,32 +194,32 @@ const refreshReadout = () => {
194
194
  `WebGL 层 ${webglMounted.value ? `已挂载 · ${webglEnabled.value ? '绘制中' : '已隐藏'} · order ${webglOrder.value} · draw ${webglDrawCount.value} 次` : '未挂载'}`
195
195
  ].join(' · ')
196
196
  }
197
-
198
- const buildOptions = () => ({
199
- points,
200
- lines,
201
- pointStyle: { size: 8, color: '#ffffff', strokeColor: '#3678bf', strokeWidth: 2 },
202
- lineStyle: { width: 1.5, color: 'rgba(120, 168, 226, 0.62)' },
203
- showGrid: true,
204
- gridColor: 'rgba(126, 168, 214, 0.2)',
205
- fitPadding: 40,
206
- features: 'view',
207
- label: { enabled: true, content: '{name}', position: 'top', gap: 7, maxCount: 20, style: { color: '#27405f', fontSize: '11px' } },
197
+
198
+ const buildOptions = () => ({
199
+ points,
200
+ lines,
201
+ pointStyle: { size: 8, color: '#ffffff', strokeColor: '#3678bf', strokeWidth: 2 },
202
+ lineStyle: { width: 1.5, color: 'rgba(120, 168, 226, 0.62)' },
203
+ showGrid: true,
204
+ gridColor: 'rgba(126, 168, 214, 0.2)',
205
+ fitPadding: 40,
206
+ features: 'view',
207
+ label: { enabled: true, content: '{name}', position: 'top', gap: 7, maxCount: 20, style: { color: '#27405f', fontSize: '11px' } },
208
208
  onReady: () => emit('notice', '扩展能力:已挂载 6 个扩展点')
209
209
  })
210
-
211
- const toggleOperator = () => {
212
- operatorOn.value = !operatorOn.value
213
- view?.setFilter(operatorOn.value ? { extension_index: { evenIndex: true } } : null)
214
- refreshReadout()
215
- emit('notice', operatorOn.value ? '自定义运算符 evenIndex 正在筛选偶数节点' : '已清空自定义筛选')
216
- }
217
-
210
+
211
+ const toggleOperator = () => {
212
+ operatorOn.value = !operatorOn.value
213
+ view?.setFilter(operatorOn.value ? { extension_index: { evenIndex: true } } : null)
214
+ refreshReadout()
215
+ emit('notice', operatorOn.value ? '自定义运算符 evenIndex 正在筛选偶数节点' : '已清空自定义筛选')
216
+ }
217
+
218
218
  const toggleSymbol = () => {
219
- symbolOn.value = !symbolOn.value
219
+ symbolOn.value = !symbolOn.value
220
220
  // 一次批量补丁:只发一条 updatePoints、只记一步历史(与逐个 updatePoint({ symbol }) 的最终数据一致)
221
- const result = view?.patchPoints(points.map(point => point.id), { symbol: symbolOn.value ? 'spark' : null })
222
- refreshReadout()
221
+ const result = view?.patchPoints(points.map(point => point.id), { symbol: symbolOn.value ? 'spark' : null })
222
+ refreshReadout()
223
223
  emit('notice', symbolOn.value ? `已切到自定义图元 spark(${result?.count ?? 0} 个节点)` : '已回到内置圆形图元')
224
224
  }
225
225
  const cycleSymbolPainter = () => {
@@ -234,27 +234,27 @@ const cycleSymbolPainter = () => {
234
234
  refreshReadout()
235
235
  emit('notice', `同名重新注册 spark:画笔已换成${next === 'diamond' ? '菱形' : '十字'},画面当场重烘焙`)
236
236
  }
237
-
237
+
238
238
  const togglePlugin = () => {
239
- pluginOn.value = !pluginOn.value
240
- if (pluginOn.value) {
241
- disposePlugin = view?.use(instance => {
242
- const badge = document.createElement('div')
243
- badge.className = 'demo-extension-badge'
244
- badge.dataset.demo = 'extension-plugin-badge'
245
- badge.textContent = 'plugin · view.use()'
246
- instance.el.appendChild(badge)
247
- return {
248
- destroy() {
249
- badge.remove()
250
- }
251
- }
252
- }) ?? null
253
- }
254
- else {
255
- disposePlugin?.()
256
- disposePlugin = null
257
- }
239
+ pluginOn.value = !pluginOn.value
240
+ if (pluginOn.value) {
241
+ disposePlugin = view?.use(instance => {
242
+ const badge = document.createElement('div')
243
+ badge.className = 'demo-extension-badge'
244
+ badge.dataset.demo = 'extension-plugin-badge'
245
+ badge.textContent = 'plugin · view.use()'
246
+ instance.el.appendChild(badge)
247
+ return {
248
+ destroy() {
249
+ badge.remove()
250
+ }
251
+ }
252
+ }) ?? null
253
+ }
254
+ else {
255
+ disposePlugin?.()
256
+ disposePlugin = null
257
+ }
258
258
  refreshReadout()
259
259
  emit('notice', pluginOn.value ? '插件已挂载:左下角出现徽标' : '插件已卸载')
260
260
  }
@@ -349,46 +349,46 @@ const requestWebglFrame = () => {
349
349
  }
350
350
 
351
351
  const exportSummary = () => {
352
- if (!view) {
353
- return
354
- }
355
- try {
356
- const result = view.exportData({ format: 'extension-summary', labels: false })
357
- exportText.value = JSON.stringify(result, null, 2)
358
- emit('notice', `自定义导出完成:${result.highLoadCount} 个高负载节点`)
359
- }
360
- catch (error) {
361
- exportText.value = `导出失败:${error instanceof Error ? error.message : String(error)}`
362
- }
363
- }
364
-
365
- onMounted(() => {
366
- view = createGisView(container.value, buildOptions())
367
- disposeOperator = view.registerOperator('evenIndex', enabled => current => !enabled || Number(current) % 2 === 0)
368
- disposeSymbol = view.registerSymbol('spark', paintSpark)
369
- disposeExport = defineExportFormat('extension-summary', ({ document, counts }) => {
370
- const highLoad = document.points.filter(point => Number(point.max_loading_rate) >= 1)
371
- return {
372
- schema: 'gis-view.extension-summary.v1',
373
- counts,
374
- highLoadCount: highLoad.length,
375
- highLoadStations: highLoad.map(point => ({
376
- id: point.id,
377
- name: point.name,
378
- load: point.max_loading_rate
379
- }))
380
- }
381
- })
382
- refreshReadout()
383
- })
384
-
352
+ if (!view) {
353
+ return
354
+ }
355
+ try {
356
+ const result = view.exportData({ format: 'extension-summary', labels: false })
357
+ exportText.value = JSON.stringify(result, null, 2)
358
+ emit('notice', `自定义导出完成:${result.highLoadCount} 个高负载节点`)
359
+ }
360
+ catch (error) {
361
+ exportText.value = `导出失败:${error instanceof Error ? error.message : String(error)}`
362
+ }
363
+ }
364
+
365
+ onMounted(() => {
366
+ view = createGisView(container.value, buildOptions())
367
+ disposeOperator = view.registerOperator('evenIndex', enabled => current => !enabled || Number(current) % 2 === 0)
368
+ disposeSymbol = view.registerSymbol('spark', paintSpark)
369
+ disposeExport = defineExportFormat('extension-summary', ({ document, counts }) => {
370
+ const highLoad = document.points.filter(point => Number(point.max_loading_rate) >= 1)
371
+ return {
372
+ schema: 'gis-view.extension-summary.v1',
373
+ counts,
374
+ highLoadCount: highLoad.length,
375
+ highLoadStations: highLoad.map(point => ({
376
+ id: point.id,
377
+ name: point.name,
378
+ load: point.max_loading_rate
379
+ }))
380
+ }
381
+ })
382
+ refreshReadout()
383
+ })
384
+
385
385
  onBeforeUnmount(() => {
386
- disposePlugin?.()
387
- disposePlugin = null
388
- disposeSymbol?.()
389
- disposeSymbol = null
390
- disposeOperator?.()
391
- disposeOperator = null
386
+ disposePlugin?.()
387
+ disposePlugin = null
388
+ disposeSymbol?.()
389
+ disposeSymbol = null
390
+ disposeOperator?.()
391
+ disposeOperator = null
392
392
  disposeExport?.()
393
393
  disposeExport = null
394
394
  disposeWebgl?.()
@@ -396,52 +396,52 @@ onBeforeUnmount(() => {
396
396
  disposeCommand?.()
397
397
  disposeCommand = null
398
398
  view?.destroy()
399
- view = null
400
- })
401
- </script>
402
-
403
- <template>
404
- <section class="dv-demo">
405
- <div class="dv-stage">
406
- <div ref="container" class="dv-canvas"></div>
407
- <div class="dv-toolbar">
408
- <button type="button" @click="view?.fitView(40)">适应全部</button>
409
- </div>
410
- </div>
411
- <aside class="dv-panel">
412
- <div class="dv-group">
399
+ view = null
400
+ })
401
+ </script>
402
+
403
+ <template>
404
+ <section class="dv-demo">
405
+ <div class="dv-stage">
406
+ <div ref="container" class="dv-canvas"></div>
407
+ <div class="dv-toolbar">
408
+ <button type="button" @click="view?.fitView(40)">适应全部</button>
409
+ </div>
410
+ </div>
411
+ <aside class="dv-panel">
412
+ <div class="dv-group">
413
413
  <h3>六个扩展点</h3>
414
414
  <div class="dv-row">
415
415
  <button
416
- type="button"
417
- class="dv-button"
418
- :class="{ 'dv-button--primary': operatorOn }"
419
- :aria-pressed="operatorOn"
420
- data-demo="extension-operator"
421
- @click="toggleOperator"
422
- >{{ operatorOn ? '关闭自定义筛选' : '自定义运算符筛选' }}</button>
423
- </div>
424
- <div class="dv-row">
425
- <button
426
- type="button"
427
- class="dv-button"
428
- :class="{ 'dv-button--primary': symbolOn }"
429
- :aria-pressed="symbolOn"
430
- data-demo="extension-symbol"
416
+ type="button"
417
+ class="dv-button"
418
+ :class="{ 'dv-button--primary': operatorOn }"
419
+ :aria-pressed="operatorOn"
420
+ data-demo="extension-operator"
421
+ @click="toggleOperator"
422
+ >{{ operatorOn ? '关闭自定义筛选' : '自定义运算符筛选' }}</button>
423
+ </div>
424
+ <div class="dv-row">
425
+ <button
426
+ type="button"
427
+ class="dv-button"
428
+ :class="{ 'dv-button--primary': symbolOn }"
429
+ :aria-pressed="symbolOn"
430
+ data-demo="extension-symbol"
431
431
  @click="toggleSymbol"
432
432
  >{{ symbolOn ? '换回内置圆形' : '使用自定义图元' }}</button>
433
433
  <button type="button" class="dv-button" :disabled="!symbolOn" data-demo="extension-symbol-variant" @click="cycleSymbolPainter">同名换画笔</button>
434
434
  </div>
435
- <div class="dv-row">
436
- <button
437
- type="button"
438
- class="dv-button"
439
- :class="{ 'dv-button--primary': pluginOn }"
440
- :aria-pressed="pluginOn"
441
- data-demo="extension-plugin"
442
- @click="togglePlugin"
443
- >{{ pluginOn ? '卸载运行时插件' : '挂载运行时插件' }}</button>
444
- </div>
435
+ <div class="dv-row">
436
+ <button
437
+ type="button"
438
+ class="dv-button"
439
+ :class="{ 'dv-button--primary': pluginOn }"
440
+ :aria-pressed="pluginOn"
441
+ data-demo="extension-plugin"
442
+ @click="togglePlugin"
443
+ >{{ pluginOn ? '卸载运行时插件' : '挂载运行时插件' }}</button>
444
+ </div>
445
445
  <div class="dv-row">
446
446
  <button type="button" class="dv-button dv-button--primary" data-demo="extension-export" @click="exportSummary">自定义格式导出</button>
447
447
  </div>
@@ -472,44 +472,44 @@ onBeforeUnmount(() => {
472
472
  <button type="button" class="dv-button" :disabled="!webglMounted" data-demo="extension-webgl-request" @click="requestWebglFrame">requestRender()</button>
473
473
  </div>
474
474
  <p class="dv-hint">运算符注册进条件语言,图元注册进符号表,插件挂在实例上,导出格式挂在模块注册表,WebGL 层直接拿 <code>gl</code> 在内置内容之后画自己的东西,实例命令把业务动作注册进当前视图;六者都不需要改组件源码。图元切换走一次 <code>patchPoints</code> 批量补丁,WebGL 层可用 <code>enabled</code> / <code>order</code> 原地维护,命令通过 <code>executeCommand</code> 同步执行并返回 handler 的结果。</p>
475
- </div>
475
+ </div>
476
476
  <div class="dv-group">
477
477
  <h3>注册表读数</h3>
478
478
  <p class="dv-readout" data-demo="extension-readout" aria-live="polite">{{ readout }}</p>
479
479
  <p class="dv-readout" data-demo="extension-command-readout" aria-live="polite">{{ commandReadout }}</p>
480
480
  </div>
481
- <div class="dv-group">
482
- <h3>导出结果</h3>
483
- <pre class="dv-readout demo-extension-export" data-demo="extension-export-text">{{ exportText }}</pre>
484
- </div>
485
- </aside>
486
- </section>
487
- </template>
488
-
489
- <style scoped>
490
- .demo-extension-export {
491
- max-height: 190px;
492
- margin: 0;
493
- overflow: auto;
494
- white-space: pre-wrap;
495
- word-break: break-all;
496
- font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
497
- font-size: 11px;
498
- }
499
-
500
- :global(.demo-extension-badge) {
501
- position: absolute;
502
- left: 10px;
503
- bottom: 10px;
504
- z-index: 4;
505
- padding: 5px 9px;
506
- border: 1px solid rgba(54, 120, 191, 0.35);
507
- border-radius: 999px;
508
- background: rgba(255, 255, 255, 0.9);
509
- color: #2f5e94;
510
- font-size: 11px;
511
- line-height: 1.4;
512
- pointer-events: none;
513
- box-shadow: 0 4px 14px rgba(31, 62, 105, 0.14);
514
- }
515
- </style>
481
+ <div class="dv-group">
482
+ <h3>导出结果</h3>
483
+ <pre class="dv-readout demo-extension-export" data-demo="extension-export-text">{{ exportText }}</pre>
484
+ </div>
485
+ </aside>
486
+ </section>
487
+ </template>
488
+
489
+ <style scoped>
490
+ .demo-extension-export {
491
+ max-height: 190px;
492
+ margin: 0;
493
+ overflow: auto;
494
+ white-space: pre-wrap;
495
+ word-break: break-all;
496
+ font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
497
+ font-size: 11px;
498
+ }
499
+
500
+ :global(.demo-extension-badge) {
501
+ position: absolute;
502
+ left: 10px;
503
+ bottom: 10px;
504
+ z-index: 4;
505
+ padding: 5px 9px;
506
+ border: 1px solid rgba(54, 120, 191, 0.35);
507
+ border-radius: 999px;
508
+ background: rgba(255, 255, 255, 0.9);
509
+ color: #2f5e94;
510
+ font-size: 11px;
511
+ line-height: 1.4;
512
+ pointer-events: none;
513
+ box-shadow: 0 4px 14px rgba(31, 62, 105, 0.14);
514
+ }
515
+ </style>
@@ -1,64 +1,64 @@
1
- <script setup>
2
- import { provide } from 'vue'
3
- import './gis-view-demo/demo.css'
4
- import { DEMO_CONTEXT } from './gis-view-demo/demoContext.js'
5
- import { useGisViewDemo } from './gis-view-demo/useGisViewDemo.js'
6
- import GisViewDemoHeading from './gis-view-demo/GisViewDemoHeading.vue'
7
- import GisViewDemoCardHeader from './gis-view-demo/GisViewDemoCardHeader.vue'
8
- import GisViewDemoPanelStack from './gis-view-demo/GisViewDemoPanelStack.vue'
9
- import GisViewDemoStage from './gis-view-demo/GisViewDemoStage.vue'
10
- import GisViewDemoDialogs from './gis-view-demo/GisViewDemoDialogs.vue'
11
- import GisViewDemoFooter from './gis-view-demo/GisViewDemoFooter.vue'
12
-
13
- const demoContext = useGisViewDemo()
14
- // 现有自测通过根组件 setupState 读取这些 demo 内部读数;状态主体仍在 composable 里。
15
- const {
16
- applyLabelEdit,
17
- channelMemberLabels,
18
- channelReadyPayload,
19
- convertFromLngLat,
20
- convertFromScreen,
21
- convertLngLatText,
22
- convertReadout,
23
- convertScreenText,
24
- dataChangeLabel,
25
- dataShapeReadout,
26
- dataset,
27
- exportDataSample,
28
- featurePreset,
29
- hostScaleText,
30
- labelEditFontSize,
31
- labelEditId,
32
- labelEditReadout,
33
- labelEditTarget,
34
- labelListReadout,
35
- labelRoundTripReadout,
36
- labelRows,
37
- labelStateReadout,
38
- liveDragHint,
39
- lngLatText,
40
- perfStatsText,
41
- perfText,
42
- qualityText,
43
- resetAllLabels,
44
- ruleReadout,
45
- screenText,
46
- viewRef,
47
- warningText
48
- } = demoContext
49
-
50
- provide(DEMO_CONTEXT, demoContext)
51
- </script>
52
-
53
- <template>
54
- <div class="demo-view gis-view-demo">
55
- <GisViewDemoHeading />
56
- <section class="demo-card">
57
- <GisViewDemoCardHeader />
58
- <GisViewDemoPanelStack />
59
- <GisViewDemoStage />
60
- <GisViewDemoDialogs />
61
- <GisViewDemoFooter />
62
- </section>
63
- </div>
64
- </template>
1
+ <script setup>
2
+ import { provide } from 'vue'
3
+ import './gis-view-demo/demo.css'
4
+ import { DEMO_CONTEXT } from './gis-view-demo/demoContext.js'
5
+ import { useGisViewDemo } from './gis-view-demo/useGisViewDemo.js'
6
+ import GisViewDemoHeading from './gis-view-demo/GisViewDemoHeading.vue'
7
+ import GisViewDemoCardHeader from './gis-view-demo/GisViewDemoCardHeader.vue'
8
+ import GisViewDemoPanelStack from './gis-view-demo/GisViewDemoPanelStack.vue'
9
+ import GisViewDemoStage from './gis-view-demo/GisViewDemoStage.vue'
10
+ import GisViewDemoDialogs from './gis-view-demo/GisViewDemoDialogs.vue'
11
+ import GisViewDemoFooter from './gis-view-demo/GisViewDemoFooter.vue'
12
+
13
+ const demoContext = useGisViewDemo()
14
+ // 现有自测通过根组件 setupState 读取这些 demo 内部读数;状态主体仍在 composable 里。
15
+ const {
16
+ applyLabelEdit,
17
+ channelMemberLabels,
18
+ channelReadyPayload,
19
+ convertFromLngLat,
20
+ convertFromScreen,
21
+ convertLngLatText,
22
+ convertReadout,
23
+ convertScreenText,
24
+ dataChangeLabel,
25
+ dataShapeReadout,
26
+ dataset,
27
+ exportDataSample,
28
+ featurePreset,
29
+ hostScaleText,
30
+ labelEditFontSize,
31
+ labelEditId,
32
+ labelEditReadout,
33
+ labelEditTarget,
34
+ labelListReadout,
35
+ labelRoundTripReadout,
36
+ labelRows,
37
+ labelStateReadout,
38
+ liveDragHint,
39
+ lngLatText,
40
+ perfStatsText,
41
+ perfText,
42
+ qualityText,
43
+ resetAllLabels,
44
+ ruleReadout,
45
+ screenText,
46
+ viewRef,
47
+ warningText
48
+ } = demoContext
49
+
50
+ provide(DEMO_CONTEXT, demoContext)
51
+ </script>
52
+
53
+ <template>
54
+ <div class="demo-view gis-view-demo">
55
+ <GisViewDemoHeading />
56
+ <section class="demo-card">
57
+ <GisViewDemoCardHeader />
58
+ <GisViewDemoPanelStack />
59
+ <GisViewDemoStage />
60
+ <GisViewDemoDialogs />
61
+ <GisViewDemoFooter />
62
+ </section>
63
+ </div>
64
+ </template>