gis-view-webgl2 0.1.2 → 0.1.4
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 +21 -14
- package/dist/gis-view.css +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +421 -76
- package/dist/index.js +1 -1
- package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +151 -0
- package/docs/GisView.md +4 -4
- 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 +137 -0
- package/docs/api/index.html +23 -9
- package/docs/demos/ApiCoverageDemo.vue +644 -0
- package/docs/demos/ChannelDemo.vue +14 -12
- package/docs/demos/ClusterDemo.vue +251 -0
- package/docs/demos/CopyMergeDemo.vue +3 -4
- package/docs/demos/EventDemo.vue +3 -3
- package/docs/demos/ExtensionDemo.vue +69 -12
- package/docs/demos/GisViewDemo.vue +64 -8809
- package/docs/demos/SearchFilterDemo.vue +13 -11
- package/docs/demos/api-index.js +58 -47
- package/docs/demos/demos.js +34 -17
- package/docs/demos/gis-view-demo/GisViewDemoCardHeader.vue +29 -0
- package/docs/demos/gis-view-demo/GisViewDemoDialogs.vue +82 -0
- package/docs/demos/gis-view-demo/GisViewDemoFooter.vue +16 -0
- package/docs/demos/gis-view-demo/GisViewDemoHeading.vue +16 -0
- package/docs/demos/gis-view-demo/GisViewDemoPanelStack.vue +71 -0
- package/docs/demos/gis-view-demo/GisViewDemoStage.vue +219 -0
- package/docs/demos/gis-view-demo/demo.css +1230 -0
- package/docs/demos/gis-view-demo/demoContext.js +12 -0
- package/docs/demos/gis-view-demo/panels/DataPanels.vue +303 -0
- package/docs/demos/gis-view-demo/panels/OpsPanels.vue +174 -0
- package/docs/demos/gis-view-demo/panels/StylePanels.vue +561 -0
- package/docs/demos/gis-view-demo/panels/ViewPanels.vue +396 -0
- package/docs/demos/gis-view-demo/useGisViewDemo.js +6188 -0
- 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 +3 -2
- package/docs/index.html +41 -4
- package/docs/internals/16-03-/344/274/230/345/214/226/344/270/216/345/217/226/350/210/215-/344/270/213.md +1 -1
- package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +3 -2
- package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +104 -16
- package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +15 -14
- 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 +40 -3
- package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +50 -3
- package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +6 -2
- 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 +39 -7
- package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +13 -4
- package/docs/manual/13-/345/212/250/346/225/210/344/270/216/345/233/276/345/205/203.md +3 -0
- package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +121 -49
- package/docs/manual/15-/345/257/274/345/207/272/344/270/216/351/233/206/346/210/220.md +37 -3
- package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +17 -8
- package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +45 -25
- package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +91 -20
- 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 +3 -3
- package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +25 -1
- 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 +11 -8
- package/docs/steps/README.md +17 -11
- package/docs/steps/selftest-actions.html +3 -5
- package/docs/steps/selftest-demo.html +27 -18
- package/docs/steps/selftest-demos.html +409 -32
- package/docs/steps/selftest-docs.html +33 -4
- package/docs/steps/selftest-effects.html +200 -0
- package/docs/steps/selftest-features.html +603 -21
- package/docs/steps/selftest-labels.html +74 -0
- package/docs/steps/selftest-perf.html +293 -20
- package/docs/steps/selftest-scale.html +150 -29
- package/docs/steps/selftest-select.html +90 -0
- package/docs/steps/step-10-full.js +1 -1
- package/docs/steps/step-12-events.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useGisViewDemoContext } from '../demoContext.js'
|
|
3
|
+
const {
|
|
4
|
+
LABEL_POSITIONS, heatSeed, EFFECT_SYMBOL_OPTIONS, effectLineOn, effectPointOn, effectSymbol, effectLineCount,
|
|
5
|
+
effectPeriod, effectRingRadius, effectRingCount, effectText, prebakeText, applyEffects, perItemFancy,
|
|
6
|
+
perItemFollow, perItemOff, applyPrebake, applyPrebakeExact, runPrebakeNow, clearPrebake, building, activePanel,
|
|
7
|
+
pointSize, lineWidth, lineTypeMode, dcLineMark, dcLineAnchor, dcLineParallel, lineDirectionMark,
|
|
8
|
+
lineDirectionCount, lineDirectionReverse, dcLineButtonText, cursorMode, pointSizeScale, lineWidthScale,
|
|
9
|
+
pointZoomScale, lineZoomScale, fitSpacing, fitSpacingMinDistance, fitSpacingMaxZoom, zoomBaseReadout,
|
|
10
|
+
pointShape, symbolByStationType, symbolIconMode, symbolStrokeWidth, pointLayering, lineLayering, perPointStyle,
|
|
11
|
+
perPointSymbol, applyRules, showLabels, labelPosition, labelMaxCount, labelVoltageScope, LABEL_VOLTAGE_SCOPES,
|
|
12
|
+
labelAvoidOverlap, labelScanMode, labelOptimize, labelTemplate, labelHtml, labelBackground, labelColor,
|
|
13
|
+
labelFontSize, labelDraggable, labelEditable, labelHideOnInteract, showLineLabels, lineLabelPosition,
|
|
14
|
+
lineLabelTemplate, lineLabelMaxCount, lineLabelAvoidOverlap, lineLabelScanMode, lineLabelVoltageScope,
|
|
15
|
+
lineLabelHideOnInteract, lineLabelFollowOnInteract, channelMemberLabels, lineLabelParallel, lineLabelDraggable,
|
|
16
|
+
lineLabelEditable, lineLabelHtml, lineLabelBackground, lineLabelColor, lineLabelFontSize, LINE_LABEL_POSITIONS,
|
|
17
|
+
showTooltip, tooltipHtml, tooltipChannelScope, visiblePointCount, datasetMode, RULE_PRESETS, rulePreset,
|
|
18
|
+
ruleJson, ruleReadout, syncRuleJson, applyRuleUpdate, heatmapEnabled, heatmapTarget, HEATMAP_TARGETS,
|
|
19
|
+
heatmapPointActive, HEATMAP_PALETTES, heatmapPalette, heatmapDomainMode, heatmapMin, heatmapMax,
|
|
20
|
+
heatmapMissing, heatmapWidthMin, heatmapWidthMax, heatmapSizeMin, heatmapSizeMax, heatmapDensity,
|
|
21
|
+
heatmapDensityStyle, heatmapDensityLayer, heatmapDensityLevels, heatmapDensityRadius, heatmapDensityThreshold,
|
|
22
|
+
heatmapDensityCore, heatmapDensityGamma, heatmapDensityWeight, heatmapDensityOpacity, heatmapGlow,
|
|
23
|
+
heatmapGlowStrength, heatmapGlowLine, heatmapGlowPoint, heatmapGlowBlend, heatmapOpacityMin, heatmapOpacityMax,
|
|
24
|
+
heatmapMinimap, heatmapFieldStats, applyZoomBase, labelEditId, newLabelPosition, newLabelPositions,
|
|
25
|
+
labelEditContent, labelEditFontSize, labelEditColor, labelEditReadout, labelStateReadout, applyLabelEdit,
|
|
26
|
+
resetLabelEdit, resetAllLabels, labelRows, labelListReadout, labelRoundTripReadout, pickLabelRow, addLabelHere,
|
|
27
|
+
removeLabelHere, seedInitialLabels, roundTripLabels, saveLabelStates, restoreLabelStates, rerollHeatData,
|
|
28
|
+
focusDcLine,
|
|
29
|
+
} = useGisViewDemoContext()
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<template>
|
|
33
|
+
<div v-show="activePanel === 'style-heat'" class="demo-panel-body">
|
|
34
|
+
<div class="demo-controls">
|
|
35
|
+
<label><input v-model="heatmapEnabled" type="checkbox" /> 启用热力图</label>
|
|
36
|
+
<label class="demo-slider">
|
|
37
|
+
作用对象
|
|
38
|
+
<select v-model="heatmapTarget" :disabled="!heatmapEnabled">
|
|
39
|
+
<option v-for="item in HEATMAP_TARGETS" :key="item.value" :value="item.value">{{ item.label }}</option>
|
|
40
|
+
</select>
|
|
41
|
+
</label>
|
|
42
|
+
<button type="button" :disabled="building" @click="rerollHeatData">重新随机一份热力数据</button>
|
|
43
|
+
<span class="demo-control-hint">种子 {{ heatSeed }}:节点 / 线路 / 通道都按新一份「热区场」重算字段值,坐标与拓扑一动不动</span>
|
|
44
|
+
<label class="demo-slider">
|
|
45
|
+
色带
|
|
46
|
+
<select v-model="heatmapPalette" :disabled="!heatmapEnabled">
|
|
47
|
+
<option v-for="item in HEATMAP_PALETTES" :key="item.value" :value="item.value">{{ item.label }}</option>
|
|
48
|
+
</select>
|
|
49
|
+
</label>
|
|
50
|
+
<label class="demo-slider">
|
|
51
|
+
值域
|
|
52
|
+
<select v-model="heatmapDomainMode" :disabled="!heatmapEnabled">
|
|
53
|
+
<option value="auto">自动(按数据最小 / 最大)</option>
|
|
54
|
+
<option value="fixed">指定(下面两个数)</option>
|
|
55
|
+
</select>
|
|
56
|
+
</label>
|
|
57
|
+
<label>最小 <input v-model.number="heatmapMin" type="number" step="0.1" :disabled="!heatmapEnabled || heatmapDomainMode !== 'fixed'" /></label>
|
|
58
|
+
<label>最大 <input v-model.number="heatmapMax" type="number" step="0.1" :disabled="!heatmapEnabled || heatmapDomainMode !== 'fixed'" /></label>
|
|
59
|
+
<label class="demo-slider">
|
|
60
|
+
缺值
|
|
61
|
+
<select v-model="heatmapMissing" :disabled="!heatmapEnabled" title="字段缺值或不是数字时怎么办">
|
|
62
|
+
<option value="keep">保持原样(不参与)</option>
|
|
63
|
+
<option value="min">按值域最小值算</option>
|
|
64
|
+
<option value="max">按值域最大值算</option>
|
|
65
|
+
</select>
|
|
66
|
+
</label>
|
|
67
|
+
<label class="demo-slider">
|
|
68
|
+
线宽倍数
|
|
69
|
+
<input v-model.number="heatmapWidthMin" type="range" min="0.4" max="4" step="0.1" :disabled="!heatmapEnabled" />
|
|
70
|
+
<input v-model.number="heatmapWidthMax" type="range" min="0.4" max="4" step="0.1" :disabled="!heatmapEnabled" />
|
|
71
|
+
<span>{{ heatmapWidthMin.toFixed(1) }} ~ {{ heatmapWidthMax.toFixed(1) }}×</span>
|
|
72
|
+
</label>
|
|
73
|
+
<label class="demo-slider">
|
|
74
|
+
节点尺寸倍数
|
|
75
|
+
<input v-model.number="heatmapSizeMin" type="range" min="0.5" max="3" step="0.1" :disabled="!heatmapEnabled || !heatmapPointActive" />
|
|
76
|
+
<input v-model.number="heatmapSizeMax" type="range" min="0.5" max="3" step="0.1" :disabled="!heatmapEnabled || !heatmapPointActive" />
|
|
77
|
+
<span>{{ heatmapSizeMin.toFixed(1) }} ~ {{ heatmapSizeMax.toFixed(1) }}×</span>
|
|
78
|
+
</label>
|
|
79
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">节点也在热力图里:合成数据的节点与线路都按「热区场」随机生成 max_loading_rate(几团热点,不是均匀噪点),作用对象切「只按节点上色」看节点自己的颜色、切「节点 + 线路 + 通道」看两层叠在一起的效果;真实 / 样例数据的节点没有这一列,点上面的「重新随机」现生成一份。节点上的热力颜色落在填充色上,描边仍旧是电压配色;「节点尺寸倍数」与光晕的点尺寸只在这一档起作用。作用对象带上节点时图标不变:图标符号带 tint,填充按白色烘焙、逐实例染上热力色,描边走 currentStrokeColor 不受影响(贴图按「符号 + 描边色 + 尺寸」共用一张,10 万级也不会一个节点烤一张)—— 把节点从作用对象里去掉就是不参与热力图,图标本身始终是那一张</span></details>
|
|
80
|
+
<label><input v-model="heatmapDensity" type="checkbox" :disabled="!heatmapEnabled" /> 密度场(KDE,缺省平滑渐隐)</label>
|
|
81
|
+
<label class="demo-slider">
|
|
82
|
+
画法
|
|
83
|
+
<select v-model="heatmapDensityStyle" :disabled="!heatmapEnabled || !heatmapDensity" title="smooth = 连续色带、外缘一路淡到全透明;band = 分档等值线、档间硬边">
|
|
84
|
+
<option value="smooth">平滑渐隐(往外越来越淡)</option>
|
|
85
|
+
<option value="band">分档等值线(档间硬边)</option>
|
|
86
|
+
</select>
|
|
87
|
+
</label>
|
|
88
|
+
<label class="demo-slider">
|
|
89
|
+
层级
|
|
90
|
+
<select v-model="heatmapDensityLayer" :disabled="!heatmapEnabled || !heatmapDensity" title="热力图铺在数据之下还是压在上面;改它只换画的顺序,不重新烘焙">
|
|
91
|
+
<option value="below">数据之下(不挡节点与线路,要素密时会被盖住)</option>
|
|
92
|
+
<option value="above">数据之上(压住节点与线路,缺省)</option>
|
|
93
|
+
<option value="top">最上层(连框选与草稿一起压住)</option>
|
|
94
|
+
</select>
|
|
95
|
+
</label>
|
|
96
|
+
<label class="demo-slider">
|
|
97
|
+
密度档数
|
|
98
|
+
<input v-model.number="heatmapDensityLevels" type="range" min="3" max="20" step="1" :disabled="!heatmapEnabled || !heatmapDensity" />
|
|
99
|
+
<span>{{ heatmapDensityLevels }} 档</span>
|
|
100
|
+
</label>
|
|
101
|
+
<label class="demo-slider">
|
|
102
|
+
核半径
|
|
103
|
+
<input v-model.number="heatmapDensityRadius" type="range" min="1" max="16" step="0.5" :disabled="!heatmapEnabled || !heatmapDensity" />
|
|
104
|
+
<span>{{ heatmapDensityRadius.toFixed(1) }}% 长边</span>
|
|
105
|
+
</label>
|
|
106
|
+
<label class="demo-slider">
|
|
107
|
+
门槛
|
|
108
|
+
<input v-model.number="heatmapDensityThreshold" type="range" min="0" max="50" step="1" :disabled="!heatmapEnabled || !heatmapDensity" />
|
|
109
|
+
<span>场值 < {{ heatmapDensityThreshold }}% 不画</span>
|
|
110
|
+
</label>
|
|
111
|
+
<label class="demo-slider">
|
|
112
|
+
热核(band 用)
|
|
113
|
+
<input v-model.number="heatmapDensityCore" type="range" min="0" max="25" step="1" :disabled="!heatmapEnabled || !heatmapDensity" />
|
|
114
|
+
<span>{{ heatmapDensityCore === 0 ? '关(最热一档就是色带末端)' : `最热 ${heatmapDensityCore}% 提亮` }}</span>
|
|
115
|
+
</label>
|
|
116
|
+
<label class="demo-slider">
|
|
117
|
+
对比度
|
|
118
|
+
<input v-model.number="heatmapDensityGamma" type="range" min="0.4" max="3" step="0.1" :disabled="!heatmapEnabled || !heatmapDensity" />
|
|
119
|
+
<span>{{ heatmapDensityGamma.toFixed(2) }}</span>
|
|
120
|
+
</label>
|
|
121
|
+
<label class="demo-slider">
|
|
122
|
+
密度权重
|
|
123
|
+
<select v-model="heatmapDensityWeight" :disabled="!heatmapEnabled || !heatmapDensity" title="密度场里每个要素算多重">
|
|
124
|
+
<option value="value">按值域比例(值高 + 密集 = 热)</option>
|
|
125
|
+
<option value="count">只数密度(每个要素算一份)</option>
|
|
126
|
+
</select>
|
|
127
|
+
</label>
|
|
128
|
+
<label class="demo-slider">
|
|
129
|
+
密度层不透明度
|
|
130
|
+
<input v-model.number="heatmapDensityOpacity" type="range" min="0.1" max="1" step="0.05" :disabled="!heatmapEnabled || !heatmapDensity" />
|
|
131
|
+
<span>{{ heatmapDensityOpacity.toFixed(2) }}</span>
|
|
132
|
+
</label>
|
|
133
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">密度场(density):把参与热力图的节点 / 线路按核半径撒成一张密度栅格(KDE),再按色带上色铺上去 —— 主流热力图就是这一层。作用对象带上节点(缺省三类全开)时节点也按自己的值参与撒点:合成数据的节点带「热区场」的值,几团热点在密度场上糊开,不是平平一层。两种画法:smooth(缺省)按色带连续取值、alpha 跟着场值涨,从热核往外一路淡到全透明,就是 ECharts 地图热力图那种「往外化开」的团;band 是分档等值线,每档一个纯色、档与档之间硬边(色块 + 白心)。layer 决定铺在哪一层:above(缺省)数据之上、压住节点与线路 —— 真实数据 2164 个节点 + 3669 条回线几乎铺满画布,铺在下面基本被盖住;below 数据之下、不挡节点与线路(要素稀疏的数据集用这档最合适);top 最上层、连框选与草稿一起压住。改 layer 只换画的顺序,不重新烘焙。缺省就开着,写 density: false 回到逐要素上色 + 光晕的老观感。可调:style、layer、radius(核半径,世界单位)/ radiusRatio(占数据范围长边的比例,缺省 5.5%)、resolution(栅格长边格数,缺省 384)、levels(band 的档数)、threshold(低于它不画:smooth 缺省 2%、band 0.06)、edge(band 的外缘淡入宽度)、core(band 的热核,smooth 缺省关,见上面的「热核」)、gamma、max、weight、opacity。场按世界坐标烘一次,缩放平移不重算;要素特别多时撒点自动降采样(格子仍是细栅格的分辨率)。门槛与 gamma 一起决定盖住多大面积。换「画法」会自动把「门槛 / 热核」带回那一档的缺省(smooth 3% / 关、band 15% / 最热 7% 提亮)</span></details>
|
|
134
|
+
<label><input v-model="heatmapGlow" type="checkbox" :disabled="!heatmapEnabled" /> 热力光晕(热端发光,重叠越叠越亮)</label>
|
|
135
|
+
<label class="demo-slider">
|
|
136
|
+
光晕强度
|
|
137
|
+
<input v-model.number="heatmapGlowStrength" type="range" min="0" max="1" step="0.05" :disabled="!heatmapEnabled || !heatmapGlow" />
|
|
138
|
+
<span>{{ heatmapGlowStrength.toFixed(2) }}</span>
|
|
139
|
+
</label>
|
|
140
|
+
<label class="demo-slider">
|
|
141
|
+
光晕尺寸
|
|
142
|
+
<input v-model.number="heatmapGlowLine" type="range" min="1" max="8" step="0.1" :disabled="!heatmapEnabled || !heatmapGlow" />
|
|
143
|
+
<input v-model.number="heatmapGlowPoint" type="range" min="1" max="6" step="0.1" :disabled="!heatmapEnabled || !heatmapGlow || !heatmapPointActive" />
|
|
144
|
+
<span>线 {{ heatmapGlowLine.toFixed(1) }} / 点 {{ heatmapGlowPoint.toFixed(1) }}×</span>
|
|
145
|
+
</label>
|
|
146
|
+
<label class="demo-slider">
|
|
147
|
+
混合
|
|
148
|
+
<select v-model="heatmapGlowBlend" :disabled="!heatmapEnabled || !heatmapGlow" title="深底色用加法混合(重叠越叠越亮),浅底色自动退回普通混合">
|
|
149
|
+
<option value="auto">自动(按背景亮度)</option>
|
|
150
|
+
<option value="add">加法(发光感最强)</option>
|
|
151
|
+
<option value="normal">普通</option>
|
|
152
|
+
</select>
|
|
153
|
+
</label>
|
|
154
|
+
<label class="demo-slider">
|
|
155
|
+
色带透明度
|
|
156
|
+
<input v-model.number="heatmapOpacityMin" type="range" min="0" max="1" step="0.05" :disabled="!heatmapEnabled" />
|
|
157
|
+
<input v-model.number="heatmapOpacityMax" type="range" min="0" max="1" step="0.05" :disabled="!heatmapEnabled" />
|
|
158
|
+
<span>{{ heatmapOpacityMin.toFixed(2) }} ~ {{ heatmapOpacityMax.toFixed(2) }}</span>
|
|
159
|
+
</label>
|
|
160
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">光晕(glow):本色之外再铺一圈更宽 / 更大的渐隐色,冷端不发光、热端最亮,深底色上用加法混合(重叠处越叠越亮)、浅底色自动退回普通混合;底色浅时把「色带透明度」的冷端压低(缺省 0.45)就是低值淡淡一层、高值才显色的观感。glow: false 关掉,写数字就是强度,写对象还能逐项给 { strength, size: [线, 点], blend };逐要素用 heatmap: { glow: … } 单独调(渐隐按符号自己的形状铺:方形 / 圆角符号得到的是同形状的晕,不再一律是圆点)</span></details>
|
|
161
|
+
<label><input v-model="heatmapMinimap" type="checkbox" :disabled="!heatmapEnabled" /> 鹰眼图沿用同一份(勾掉只给小图关)</label>
|
|
162
|
+
<span class="demo-control-hint">{{ heatmapFieldStats }}</span>
|
|
163
|
+
</div>
|
|
164
|
+
<div class="demo-controls">
|
|
165
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">热力图按 field 取数(这里固定 max_loading_rate)到 colors 色带上取颜色,再按 width / size 的区间用同一个比例缩放线宽与节点尺寸;优先级是「状态样式 > 热力图 > 要素自身 > 规则 > style > 默认」,逐要素可以用 heatmap: false 排除、或写对象换字段 / 值域。回线自己带 max_loading_rate 就按自己的上色;自己没这个字段时才回落到所属通道的值(作用对象里要勾上通道),两边都没有就按「缺值」处理 —— 合成数据的通道与回线都带值,切「只按通道自己的值上色」就能对比「每一回各自的颜色」。节点与线路共用同一条色带:合成数据的节点与线路都按同一份「热区场」取值(几团热点),切「只按节点上色」看节点自己的颜色、切「节点 + 线路 + 通道」看两层叠在一起的效果。new.json 里线路这一列恒为 1.5、节点根本没有这一列,真实数据看不出渐变 —— 想看效果就切到「合成数据」,或在任意数据集上点上面的「重新随机」现生成一份(样例数据的线路是按序号派生的演示值)。这里的每一项都是 updateOptions({ heatmap }),数据与拾取都不动</span></details>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
<div v-show="activePanel === 'style-line'" class="demo-panel-body">
|
|
170
|
+
<div class="demo-controls">
|
|
171
|
+
<label class="demo-slider">
|
|
172
|
+
点大小
|
|
173
|
+
<input v-model.number="pointSize" type="range" min="4" max="20" step="1" />
|
|
174
|
+
<span>{{ pointSize }}px</span>
|
|
175
|
+
</label>
|
|
176
|
+
<label class="demo-slider">
|
|
177
|
+
线宽
|
|
178
|
+
<input v-model.number="lineWidth" type="range" min="0.5" max="5" step="0.1" />
|
|
179
|
+
<span>{{ lineWidth.toFixed(1) }}px</span>
|
|
180
|
+
</label>
|
|
181
|
+
<label class="demo-slider">
|
|
182
|
+
线型
|
|
183
|
+
<select v-model="lineTypeMode">
|
|
184
|
+
<option value="data">数据 / 规则(默认实线)</option>
|
|
185
|
+
<option value="solid">全部实线 solid</option>
|
|
186
|
+
<option value="dashed">全部虚线 dashed</option>
|
|
187
|
+
<option value="dotted">全部点线 dotted</option>
|
|
188
|
+
<option value="dashdot">全部点划线 dashdot</option>
|
|
189
|
+
</select>
|
|
190
|
+
</label>
|
|
191
|
+
<label><input v-model="dcLineMark" type="checkbox" /> 直流线路中点挂 PATH_DC_LINE</label>
|
|
192
|
+
<label class="demo-slider">
|
|
193
|
+
标记定位
|
|
194
|
+
<select v-model="dcLineAnchor" :disabled="!dcLineMark">
|
|
195
|
+
<option value="auto">自动(无拐点跟比例,有拐点钉在线上)</option>
|
|
196
|
+
<option value="follow">跟随线路</option>
|
|
197
|
+
<option value="fixed">写死坐标</option>
|
|
198
|
+
</select>
|
|
199
|
+
</label>
|
|
200
|
+
<label><input v-model="dcLineParallel" type="checkbox" :disabled="!dcLineMark" /> 与线路平行</label>
|
|
201
|
+
<label><input v-model="lineDirectionMark" type="checkbox" /> 线路方向箭头</label>
|
|
202
|
+
<label class="demo-slider">
|
|
203
|
+
箭头数量
|
|
204
|
+
<select v-model.number="lineDirectionCount" :disabled="!lineDirectionMark">
|
|
205
|
+
<option :value="1">1(中点)</option>
|
|
206
|
+
<option :value="2">2(三等分点)</option>
|
|
207
|
+
<option :value="3">3(四等分点)</option>
|
|
208
|
+
</select>
|
|
209
|
+
</label>
|
|
210
|
+
<label><input v-model="lineDirectionReverse" type="checkbox" :disabled="!lineDirectionMark" /> 指回起点</label>
|
|
211
|
+
<button type="button" :disabled="building" @click="focusDcLine">{{ dcLineButtonText }}</button>
|
|
212
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">PATH_DC_LINE 挂在线路的中点(position: 0.5),白底、描边取线路的电压配色:样例数据 test.json 里有 1 条 dc_line(「直流送电」),真实数据 new.json 的 channel_data 也带 dc_line —— 上面这个按钮按当前数据集的条数定位(按钮上写着条数),点一下就把第一条选中并居中,选中后线中间那个带箭头的方框就是它(图片 / SVG 装饰的贴图是异步烘出来的,切过去的第一下可能要等一帧)。标记定位的「自动」是这一轮的默认行为:线路没有拐点时按 position 的比例跟随(一直待在中点,拖端点也跟着走),加过拐点之后装饰就跟拐点一样钉住 —— 钉的是那一刻线路上的那个位置,锚点坐标不变、画之前投到当前路径上,拖端点 / 拐点、增删拐点装饰都还贴着线走,不会留在原地脱离线;「跟随线路」一直跟着新几何走,「写死坐标」把挂载那一刻的中点当 at 写死(线路改了装饰留在原处,可能脱离线)。勾上「与线路平行」装饰按锚点处的线路方向转(方框里的箭头指向线路方向),斜线、折线上都看得出来。下面的「线路方向箭头」是组件自带的另一条路(options.lineDirection):不用写装饰,沿弧长等分摆箭头、朝向跟着线路切向走(起点 → 终点),逐条线想要不同的数量 / 位置就写在线自己的 direction 上。</span></details>
|
|
213
|
+
<label class="demo-slider">
|
|
214
|
+
光标档位
|
|
215
|
+
<select v-model="cursorMode">
|
|
216
|
+
<option value="default">默认(跟随 CSS 变量)</option>
|
|
217
|
+
<option value="keys">按分类换关键字</option>
|
|
218
|
+
<option value="image">图片光标(data URI + 热点)</option>
|
|
219
|
+
<option value="ctrl">按住 Ctrl 换一套</option>
|
|
220
|
+
</select>
|
|
221
|
+
</label>
|
|
222
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">线型逐条配置(写进每条线自己的 lineType)—— 也可以由规则 / lineStyle 统一给,数据里带 line_types 的按数据走;运行中改单条用 view.updateLine(id, { lineType })(批量 patchLines)、改全局用 view.updateLineStyle({ lineType, dashOffset });图案长度是 CSS 像素,缩放时屏幕上的长短不变。光标按「悬停到哪一类要素上」分开配(节点 / 线路 / 通道 / 拐点,外加空白 / 拖动 / 草稿几个状态),支持系统关键字、var(--x) 与图片 url + 热点,按住 Ctrl / ⌘ 还能整批换一套;要素自己写了 cursor / ctrlCursor 时以要素为准</span></details>
|
|
223
|
+
<label class="demo-slider">
|
|
224
|
+
节点形状
|
|
225
|
+
<select v-model="pointShape">
|
|
226
|
+
<option value="auto">数据自带</option>
|
|
227
|
+
<option value="circle">全部圆形</option>
|
|
228
|
+
<option value="square">全部方形</option>
|
|
229
|
+
<option value="rounded">圆角方形</option>
|
|
230
|
+
</select>
|
|
231
|
+
</label>
|
|
232
|
+
<label class="demo-slider">
|
|
233
|
+
节点放大
|
|
234
|
+
<input v-model.number="pointSizeScale" type="range" min="0.5" max="10" step="0.1" />
|
|
235
|
+
<span>×{{ pointSizeScale.toFixed(1) }}</span>
|
|
236
|
+
</label>
|
|
237
|
+
<label class="demo-slider">
|
|
238
|
+
线宽放大
|
|
239
|
+
<input v-model.number="lineWidthScale" type="range" min="0.5" max="3" step="0.1" />
|
|
240
|
+
<span>×{{ lineWidthScale.toFixed(1) }}</span>
|
|
241
|
+
</label>
|
|
242
|
+
<label class="demo-slider">
|
|
243
|
+
节点跟随缩放
|
|
244
|
+
<input v-model.number="pointZoomScale" type="range" min="0" max="1" step="0.1" />
|
|
245
|
+
<span>{{ pointZoomScale.toFixed(1) }}</span>
|
|
246
|
+
</label>
|
|
247
|
+
<label class="demo-slider">
|
|
248
|
+
线路跟随缩放
|
|
249
|
+
<input v-model.number="lineZoomScale" type="range" min="0" max="1" step="0.1" />
|
|
250
|
+
<span>{{ lineZoomScale.toFixed(1) }}</span>
|
|
251
|
+
</label>
|
|
252
|
+
<label class="demo-slider">
|
|
253
|
+
适应节点间距
|
|
254
|
+
<input v-model="fitSpacing" type="checkbox" />
|
|
255
|
+
<span>{{ fitSpacing ? '开' : '关' }}</span>
|
|
256
|
+
</label>
|
|
257
|
+
<label class="demo-slider">
|
|
258
|
+
最小中心距
|
|
259
|
+
<input v-model.number="fitSpacingMinDistance" type="number" min="1" step="1" :disabled="!fitSpacing" />
|
|
260
|
+
<span>px</span>
|
|
261
|
+
</label>
|
|
262
|
+
<label class="demo-slider">
|
|
263
|
+
最大放大
|
|
264
|
+
<input v-model.number="fitSpacingMaxZoom" type="number" min="0" step="1" :disabled="!fitSpacing" />
|
|
265
|
+
<span>{{ fitSpacingMaxZoom > 0 ? `×${fitSpacingMaxZoom}` : '不限' }}</span>
|
|
266
|
+
</label>
|
|
267
|
+
<button type="button" @click="applyZoomBase()">以当前比例为基准</button>
|
|
268
|
+
<span class="demo-control-hint">放大与跟随缩放是两个系数:滚轮缩放时再乘一次联动系数(基准为首次适应视图的比例);「适应节点间距」打开后,首次适应与 fitView 会按最近可见节点中心距反推比例,远处孤立点允许落到视口外{{ zoomBaseReadout ? ` · ${zoomBaseReadout}` : '' }}</span>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<div v-show="activePanel === 'style-rules'" class="demo-panel-body">
|
|
274
|
+
<div class="demo-controls">
|
|
275
|
+
<label><input v-model="applyRules" type="checkbox" /> 按电压等级配色 / 定大小</label>
|
|
276
|
+
<label><input v-model="symbolByStationType" type="checkbox" :disabled="!applyRules" /> 按站点类型换符号</label>
|
|
277
|
+
<label>
|
|
278
|
+
图标类型
|
|
279
|
+
<select v-model="symbolIconMode" :disabled="!applyRules || !symbolByStationType">
|
|
280
|
+
<option value="svg">test.js 路径(SVG)</option>
|
|
281
|
+
<option value="square">方块</option>
|
|
282
|
+
</select>
|
|
283
|
+
</label>
|
|
284
|
+
<label class="demo-slider">
|
|
285
|
+
图标描边
|
|
286
|
+
<input v-model.number="symbolStrokeWidth" type="number" min="0" max="6" step="0.5" :disabled="!applyRules || !symbolByStationType || symbolIconMode !== 'svg'" />
|
|
287
|
+
</label>
|
|
288
|
+
<label><input v-model="pointLayering" type="checkbox" :disabled="!applyRules" /> 按电压分层(高电压在上)</label>
|
|
289
|
+
<label><input v-model="lineLayering" type="checkbox" :disabled="!applyRules" /> 线路按电压分层(高电压线路在上)</label>
|
|
290
|
+
<label><input v-model="perPointSymbol" type="checkbox" /> 逐点符号(节点自己配)</label>
|
|
291
|
+
<label><input v-model="perPointStyle" type="checkbox" :disabled="datasetMode !== 'synthetic'" /> 逐点样式(金色节点)</label>
|
|
292
|
+
</div>
|
|
293
|
+
|
|
294
|
+
<div class="demo-controls">
|
|
295
|
+
<strong class="demo-control-group">规则更新</strong>
|
|
296
|
+
<label class="demo-slider">
|
|
297
|
+
规则方案
|
|
298
|
+
<select v-model="rulePreset">
|
|
299
|
+
<option v-for="preset in RULE_PRESETS" :key="preset.value" :value="preset.value">{{ preset.label }}</option>
|
|
300
|
+
</select>
|
|
301
|
+
</label>
|
|
302
|
+
<button type="button" @click="applyRuleUpdate">更新规则并重渲染</button>
|
|
303
|
+
<button type="button" @click="syncRuleJson()">用面板配置回填 JSON</button>
|
|
304
|
+
<span class="demo-control-hint">{{ ruleReadout }}</span>
|
|
305
|
+
</div>
|
|
306
|
+
<div class="demo-controls demo-controls--rules">
|
|
307
|
+
<textarea v-model="ruleJson" rows="9" spellcheck="false"></textarea>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
</div>
|
|
311
|
+
|
|
312
|
+
<div v-show="activePanel === 'style-label'" class="demo-panel-body">
|
|
313
|
+
<div class="demo-controls">
|
|
314
|
+
<strong class="demo-control-group">节点标签</strong>
|
|
315
|
+
<label><input v-model="showLabels" type="checkbox" /> 显示</label>
|
|
316
|
+
<label class="demo-slider">
|
|
317
|
+
位置
|
|
318
|
+
<select v-model="labelPosition">
|
|
319
|
+
<option v-for="position in LABEL_POSITIONS" :key="position" :value="position">{{ position }}</option>
|
|
320
|
+
</select>
|
|
321
|
+
</label>
|
|
322
|
+
<label class="demo-slider">
|
|
323
|
+
内容
|
|
324
|
+
<input v-model="labelTemplate" type="text" :disabled="labelHtml" />
|
|
325
|
+
</label>
|
|
326
|
+
<label><input v-model="labelHtml" type="checkbox" /> 用 HTML</label>
|
|
327
|
+
<label class="demo-slider">
|
|
328
|
+
底色
|
|
329
|
+
<select v-model="labelBackground">
|
|
330
|
+
<option value="">默认(白底 88%)</option>
|
|
331
|
+
<option value="rgba(255, 255, 255, 0.92)">白</option>
|
|
332
|
+
<option value="rgba(23, 36, 54, 0.82)">深色</option>
|
|
333
|
+
<option value="rgba(224, 86, 160, 0.16)">淡粉</option>
|
|
334
|
+
<option value="transparent">透明</option>
|
|
335
|
+
</select>
|
|
336
|
+
</label>
|
|
337
|
+
<label class="demo-slider">
|
|
338
|
+
文字色
|
|
339
|
+
<select v-model="labelColor">
|
|
340
|
+
<option value="">默认(#1f3550)</option>
|
|
341
|
+
<option value="#1b4b7a">深蓝</option>
|
|
342
|
+
<option value="#ffffff">白</option>
|
|
343
|
+
<option value="#e056a0">品红</option>
|
|
344
|
+
<option value="#c62828">红</option>
|
|
345
|
+
</select>
|
|
346
|
+
</label>
|
|
347
|
+
<label class="demo-slider">
|
|
348
|
+
字号
|
|
349
|
+
<select v-model.number="labelFontSize">
|
|
350
|
+
<option :value="0">默认(12px)</option>
|
|
351
|
+
<option :value="11">11px</option>
|
|
352
|
+
<option :value="14">14px</option>
|
|
353
|
+
<option :value="16">16px</option>
|
|
354
|
+
</select>
|
|
355
|
+
</label>
|
|
356
|
+
<label class="demo-slider">
|
|
357
|
+
上限
|
|
358
|
+
<input v-model.lazy.number="labelMaxCount" type="range" min="0" max="120" step="4" />
|
|
359
|
+
<span>{{ labelMaxCount ? labelMaxCount : '不限' }}</span>
|
|
360
|
+
</label>
|
|
361
|
+
<label class="demo-slider">
|
|
362
|
+
候选
|
|
363
|
+
<select v-model="labelScanMode">
|
|
364
|
+
<option value="auto">自动</option>
|
|
365
|
+
<option :value="256">前 256 个</option>
|
|
366
|
+
<option :value="0">整屏扫描</option>
|
|
367
|
+
</select>
|
|
368
|
+
</label>
|
|
369
|
+
<label class="demo-slider">
|
|
370
|
+
显示范围
|
|
371
|
+
<select v-model="labelVoltageScope">
|
|
372
|
+
<option v-for="scope in LABEL_VOLTAGE_SCOPES" :key="scope.value" :value="scope.value">{{ scope.label }}</option>
|
|
373
|
+
</select>
|
|
374
|
+
</label>
|
|
375
|
+
<label><input v-model="labelAvoidOverlap" type="checkbox" /> 避让</label>
|
|
376
|
+
<label><input v-model="labelOptimize" type="checkbox" /> 标签优化</label>
|
|
377
|
+
<label><input v-model="labelHideOnInteract" type="checkbox" /> 交互时动态收起</label>
|
|
378
|
+
<label><input v-model="labelDraggable" type="checkbox" /> 可拖</label>
|
|
379
|
+
<label><input v-model="labelEditable" type="checkbox" /> 可编辑</label>
|
|
380
|
+
<span class="demo-control-hint">标签外观不用写 HTML:上面「底色 / 文字色 / 字号」三项就是 label.style(内联样式增量合并),留空 = 样式表默认(白底 88% / #1f3550 / 12px);逐条改可以选中标签走「标签编辑」里的 updateLabel。</span>
|
|
381
|
+
<span class="demo-control-hint">可见节点 {{ visiblePointCount.toLocaleString() }} · {{ labelOptimize ? '标签按优化档(避让 / 限数)' : '标签强制显示(不避让 / 不限数)' }}</span>
|
|
382
|
+
</div>
|
|
383
|
+
|
|
384
|
+
<div class="demo-controls">
|
|
385
|
+
<strong class="demo-control-group">线路标签</strong>
|
|
386
|
+
<label><input v-model="showLineLabels" type="checkbox" /> 显示</label>
|
|
387
|
+
<label class="demo-slider">
|
|
388
|
+
显示范围
|
|
389
|
+
<select v-model="lineLabelVoltageScope">
|
|
390
|
+
<option v-for="scope in LABEL_VOLTAGE_SCOPES" :key="scope.value" :value="scope.value">{{ scope.label }}</option>
|
|
391
|
+
</select>
|
|
392
|
+
</label>
|
|
393
|
+
<label class="demo-slider">
|
|
394
|
+
位置
|
|
395
|
+
<select v-model="lineLabelPosition">
|
|
396
|
+
<option v-for="position in LINE_LABEL_POSITIONS" :key="position.value" :value="position.value">{{ position.label }}</option>
|
|
397
|
+
</select>
|
|
398
|
+
</label>
|
|
399
|
+
<label class="demo-slider">
|
|
400
|
+
内容
|
|
401
|
+
<input v-model="lineLabelTemplate" type="text" :disabled="lineLabelHtml" />
|
|
402
|
+
</label>
|
|
403
|
+
<label><input v-model="lineLabelHtml" type="checkbox" /> 用 HTML</label>
|
|
404
|
+
<label class="demo-slider">
|
|
405
|
+
底色
|
|
406
|
+
<select v-model="lineLabelBackground">
|
|
407
|
+
<option value="">组件默认(白底 88%)</option>
|
|
408
|
+
<option value="rgba(23, 36, 54, 0.82)">深色胶囊(演示默认)</option>
|
|
409
|
+
<option value="rgba(21, 101, 192, 0.82)">蓝</option>
|
|
410
|
+
<option value="rgba(255, 255, 255, 0.92)">白</option>
|
|
411
|
+
</select>
|
|
412
|
+
</label>
|
|
413
|
+
<label class="demo-slider">
|
|
414
|
+
文字色
|
|
415
|
+
<select v-model="lineLabelColor">
|
|
416
|
+
<option value="">组件默认(#1f3550)</option>
|
|
417
|
+
<option value="#f3f7fc">浅色(演示默认)</option>
|
|
418
|
+
<option value="#ffffff">白</option>
|
|
419
|
+
<option value="#ffe08a">金黄</option>
|
|
420
|
+
</select>
|
|
421
|
+
</label>
|
|
422
|
+
<label class="demo-slider">
|
|
423
|
+
字号
|
|
424
|
+
<select v-model.number="lineLabelFontSize">
|
|
425
|
+
<option :value="0">组件默认(12px)</option>
|
|
426
|
+
<option :value="11">11px(演示默认)</option>
|
|
427
|
+
<option :value="12">12px</option>
|
|
428
|
+
<option :value="14">14px</option>
|
|
429
|
+
</select>
|
|
430
|
+
</label>
|
|
431
|
+
<label><input v-model="lineLabelParallel" type="checkbox" /> 与线路平行</label>
|
|
432
|
+
<label><input v-model="channelMemberLabels" type="checkbox" /> 通道回线各自显示</label>
|
|
433
|
+
<label class="demo-slider">
|
|
434
|
+
上限
|
|
435
|
+
<input v-model.lazy.number="lineLabelMaxCount" type="range" min="0" max="120" step="4" />
|
|
436
|
+
<span>{{ lineLabelMaxCount ? lineLabelMaxCount : '不限' }}</span>
|
|
437
|
+
</label>
|
|
438
|
+
<label class="demo-slider">
|
|
439
|
+
候选
|
|
440
|
+
<select v-model="lineLabelScanMode">
|
|
441
|
+
<option value="auto">自动</option>
|
|
442
|
+
<option :value="256">前 256 个</option>
|
|
443
|
+
<option :value="0">整屏扫描</option>
|
|
444
|
+
</select>
|
|
445
|
+
</label>
|
|
446
|
+
<label><input v-model="lineLabelAvoidOverlap" type="checkbox" /> 避让</label>
|
|
447
|
+
<label><input v-model="lineLabelHideOnInteract" type="checkbox" /> 交互时动态收起</label>
|
|
448
|
+
<label><input v-model="lineLabelFollowOnInteract" type="checkbox" /> 交互期跟随线路</label>
|
|
449
|
+
<label><input v-model="lineLabelDraggable" type="checkbox" /> 可拖</label>
|
|
450
|
+
<label><input v-model="lineLabelEditable" type="checkbox" /> 可编辑</label>
|
|
451
|
+
<span class="demo-control-hint">线路标签的底色 / 文字色 / 字号同样走 lineLabel.style(上面三个下拉),留空项回到样式表默认;逐条覆盖用 updateLabel('line', id, { style })。</span>
|
|
452
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">默认显示在线路中间的名字(position 0.5);一条线自己写了 lineLabel / lineLabelPosition / lineLabelOffset 时优先用它的,「通道回线各自显示」就是给通道里每条回线各写一个错开的 lineLabelPosition —— 这类线路不占扫描名额、也不参与屏幕小格去重,所以并行回线能各显示各的标签(标签较多时建议保留「避让」,重叠的自动不画;线路密的时候先点「放大」到通道看得清,标签才铺得开)。勾上「与线路平行」标签按锚点处的线路方向旋转,朝左的方向自动翻半圈,文字始终正着读(避让按标签未旋转时的尺寸算,转过的标签不会因为外接矩形变大被整片丢掉)。</span></details>
|
|
453
|
+
</div>
|
|
454
|
+
|
|
455
|
+
<div class="demo-controls">
|
|
456
|
+
<strong class="demo-control-group">悬浮提示</strong>
|
|
457
|
+
<label><input v-model="showTooltip" type="checkbox" /> 开启</label>
|
|
458
|
+
<label><input v-model="tooltipHtml" type="checkbox" /> 用 HTML</label>
|
|
459
|
+
<label class="demo-slider">
|
|
460
|
+
通道回线看
|
|
461
|
+
<select v-model="tooltipChannelScope" title="通道里的回线悬停时看哪一层的信息">
|
|
462
|
+
<option value="channel">整条通道</option>
|
|
463
|
+
<option value="group">所属分组</option>
|
|
464
|
+
<option value="line">这条回线</option>
|
|
465
|
+
</select>
|
|
466
|
+
</label>
|
|
467
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">通道里的回线悬停时默认看整条通道({name} 是通道名、{circuits} 是回数);切到「所属分组」看这一组({id} / {lineCount} / {waypointCount},分组没有的字段回落到通道)、切到「这条回线」只看这条线自己({name} / {vn_kv} / {channel_id})。</span></details>
|
|
468
|
+
</div>
|
|
469
|
+
|
|
470
|
+
<div class="demo-controls">
|
|
471
|
+
<strong class="demo-control-group">标签拖动与编辑</strong>
|
|
472
|
+
<span class="demo-control-hint">点一下标签选中它(上面勾上「可编辑」),按住拖动就把它挪到别处;挪出来的偏移记在组件里,之后再移动节点标签会在偏移的基础上跟着走</span>
|
|
473
|
+
</div>
|
|
474
|
+
<div class="demo-controls">
|
|
475
|
+
<label class="demo-slider">
|
|
476
|
+
内容
|
|
477
|
+
<input v-model="labelEditContent" type="text" placeholder="留空 = 不改" />
|
|
478
|
+
</label>
|
|
479
|
+
<label class="demo-slider">
|
|
480
|
+
字号
|
|
481
|
+
<input v-model="labelEditFontSize" type="text" placeholder="12px" />
|
|
482
|
+
</label>
|
|
483
|
+
<label class="demo-slider">
|
|
484
|
+
颜色
|
|
485
|
+
<input v-model="labelEditColor" type="text" placeholder="#1b4b7a" />
|
|
486
|
+
</label>
|
|
487
|
+
<button type="button" @click="applyLabelEdit()">应用</button>
|
|
488
|
+
<button type="button" @click="resetLabelEdit()">恢复这一条的默认</button>
|
|
489
|
+
<button type="button" @click="resetAllLabels()">全部恢复默认</button>
|
|
490
|
+
<span class="demo-control-hint">{{ labelEditReadout }}</span>
|
|
491
|
+
</div>
|
|
492
|
+
<div class="demo-controls">
|
|
493
|
+
<label class="demo-slider">
|
|
494
|
+
标签 id
|
|
495
|
+
<input v-model="labelEditId" type="text" placeholder="default" />
|
|
496
|
+
</label>
|
|
497
|
+
<button type="button" @click="addLabelHere()">加一条标签</button>
|
|
498
|
+
<button type="button" @click="removeLabelHere()">删这一条</button>
|
|
499
|
+
<label class="demo-slider">
|
|
500
|
+
新增位置
|
|
501
|
+
<select v-model="newLabelPosition" title="addLabel 的 position:节点标签是八向(上 / 下 / 左 / 右…),线路标签是沿线位置(0 ~ 1)">
|
|
502
|
+
<option v-for="position in newLabelPositions" :key="String(position.value)" :value="position.value">{{ position.label }}</option>
|
|
503
|
+
</select>
|
|
504
|
+
</label>
|
|
505
|
+
<span class="demo-control-hint">{{ labelListReadout }}</span>
|
|
506
|
+
</div>
|
|
507
|
+
<div class="demo-controls">
|
|
508
|
+
<button v-for="row in labelRows" :key="row.id" type="button" @click="pickLabelRow(row)">{{ row.id }}{{ row.added ? ' · 运行时' : '' }}{{ row.hidden ? ' · 隐藏' : '' }}</button>
|
|
509
|
+
<span class="demo-control-hint">点一条切换编辑目标:同一个要素上可以有好几条标签</span>
|
|
510
|
+
</div>
|
|
511
|
+
<div class="demo-controls">
|
|
512
|
+
<button type="button" @click="seedInitialLabels()">初始标签:给前 3 个节点写 4 条 labels</button>
|
|
513
|
+
<span class="demo-control-hint">标签也可以一开始就在:数据里写 labels(位置 / 样式 / 偏移各写各的),一条 label 配置都不写也画得出来;这几条照样能点、能拖、能改</span>
|
|
514
|
+
</div>
|
|
515
|
+
<div class="demo-controls">
|
|
516
|
+
<button type="button" @click="roundTripLabels()">导出 labels 再写回(回显)</button>
|
|
517
|
+
<button type="button" @click="saveLabelStates()">保存标签状态</button>
|
|
518
|
+
<button type="button" @click="restoreLabelStates()">灌回保存的状态</button>
|
|
519
|
+
<span class="demo-control-hint">{{ labelRoundTripReadout }}</span>
|
|
520
|
+
</div>
|
|
521
|
+
<div class="demo-controls">
|
|
522
|
+
<span class="demo-control-hint">{{ labelStateReadout }}</span>
|
|
523
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">拖动与编辑是两个开关(节点标签、线路标签各自一份):关着时标签照旧 pointer-events: none,一点都不挡画布;开着时标签自己接住指针,拖动不会把画布一起拖走。「可编辑」点一下发 labelClick 把这一条交给面板,改什么由使用方调 updateLabel 落下去(内容 / 字号 / 颜色只是几个例子,style 是内联样式的增量合并,写什么进去就加什么);「恢复默认」一次清掉这一条的偏移与全部覆盖,getLabelStates() 随时能拿到当前记着的那些条 —— 要做持久化就存它。偏移与内容都是按 id 记的(没写 id 才按下标),换数据之后同 id 的标签仍然带着自己那一份。</span></details>
|
|
524
|
+
</div>
|
|
525
|
+
|
|
526
|
+
</div>
|
|
527
|
+
|
|
528
|
+
<div v-show="activePanel === 'style-effect'" class="demo-panel-body">
|
|
529
|
+
<div class="demo-controls">
|
|
530
|
+
<label class="demo-slider"><input v-model="effectLineOn" type="checkbox" @change="applyEffects" />线路动点</label>
|
|
531
|
+
<label class="demo-slider"><input v-model="effectPointOn" type="checkbox" @change="applyEffects" />节点涟漪</label>
|
|
532
|
+
<button type="button" @click="applyEffects">下发全局配置(updateOptions)</button>
|
|
533
|
+
<span class="demo-control-hint">动画效果:{{ effectText }}</span>
|
|
534
|
+
</div>
|
|
535
|
+
<div class="demo-controls">
|
|
536
|
+
<label class="demo-slider">图标<select v-model="effectSymbol" @change="applyEffects"><option v-for="item in EFFECT_SYMBOL_OPTIONS" :key="item.value" :value="item.value">{{ item.label }}</option></select></label>
|
|
537
|
+
<label class="demo-slider">同时几个<input v-model.number="effectLineCount" type="number" min="1" max="8" @change="applyEffects" /></label>
|
|
538
|
+
<label class="demo-slider">一趟几秒<input v-model.number="effectPeriod" type="number" min="0.5" max="10" step="0.5" @change="applyEffects" /></label>
|
|
539
|
+
</div>
|
|
540
|
+
<div class="demo-controls">
|
|
541
|
+
<label class="demo-slider">涟漪半径<input v-model.number="effectRingRadius" type="number" min="8" max="80" step="2" @change="applyEffects" /></label>
|
|
542
|
+
<label class="demo-slider">同时几圈<input v-model.number="effectRingCount" type="number" min="1" max="4" @change="applyEffects" /></label>
|
|
543
|
+
<span class="demo-control-hint">半径 / 线宽都是 CSS 像素,缩放时不跟着变大;动点带描边与阴影,样式与节点的「符号」同一套</span>
|
|
544
|
+
</div>
|
|
545
|
+
<div class="demo-controls">
|
|
546
|
+
<button type="button" @click="perItemFancy">逐条覆盖:黄色 3 个(1.5 秒一趟)</button>
|
|
547
|
+
<button type="button" @click="perItemFollow">逐条覆盖:交回全局(effect: true)</button>
|
|
548
|
+
<button type="button" @click="perItemOff">逐条覆盖:这几条关掉(effect: false)</button>
|
|
549
|
+
</div>
|
|
550
|
+
<div class="demo-controls">
|
|
551
|
+
<button type="button" @click="applyPrebakeExact" title="getSymbolCombos 收出这份数据真正会画到的组合,再按 prebake.combos 逐条烤:不重不漏的一份(真实数据实测 26 条 vs 规则表全排列 1741 条)">按实际组合配一份(精确)</button>
|
|
552
|
+
<button type="button" @click="applyPrebake" title="按规则表做全排列(符号 × 点色 × 尺寸 + 线色 × 图标):省事,但颜色与尺寸由同一字段决定时会烤出大量用不到的组合">按规则表全排列配一份(粗)</button>
|
|
553
|
+
<button type="button" @click="runPrebakeNow">再烤一遍(runPrebake)</button>
|
|
554
|
+
<button type="button" @click="clearPrebake">关掉预热</button>
|
|
555
|
+
<span class="demo-control-hint">预热(prebake):{{ prebakeText }}</span>
|
|
556
|
+
</div>
|
|
557
|
+
<div class="demo-controls">
|
|
558
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">效果分两层:全局缺省(<code>updateOptions({ effects })</code> 或 <code>options.effects</code>)与逐要素(数据里的 <code>points[].effect</code> / <code>lines[].effect</code>)。上面那三个「逐条覆盖」按钮演示的就是逐要素的三种写法:写一份自己的、<code>true</code> 交回全局、<code>false</code> 这几条不动 —— 只在数据里逐条配也会动,全局一个都不配也行。三层「关」是四件事:什么都不配 / <code>effects: false</code> 一处关掉(谁都别动)/ <code>effects.line: false</code> 只关全局那一份 / 逐条 <code>effect: false</code>。线路的图标按弧长跑(拐点上连着走、朝向跟着所在那一段),节点涟漪每帧只改一个 <code>u_time</code>,两者都只铺视口里的、按「画多少」付费;页签切到后台或系统要求减少动态效果时直接停帧(<code>respectReducedMotion</code> 缺省尊重它,想照跑就关掉)。预热不改变画面:它把「会画到的那些贴图」在首帧之前烤好,省掉第一次画到时的解码 + 光栅化,稳态帧与它无关,再烤一遍命中的是缓存。收组合有两种写法:<strong>按实际组合(精确)</strong>走 <code>getSymbolCombos()</code>,把这份数据真正会用到的组合收出来(真实数据实测 <strong>26 条</strong>:照着它配预热零张新画布,逐条命中);<strong>按规则表全排列(粗)</strong>是笛卡尔积,颜色与尺寸由同一个字段决定时(都跟着电压走那种)会把用不到的组合也烤一遍 —— 同一份数据收出 <strong>1741 条</strong>、多烤 21 倍画布,无头下首帧从 29 ms 掉到 963 ms。<strong>「提前预知」的正确用法是清单要准,不是越多越好。</strong></span></details>
|
|
559
|
+
</div>
|
|
560
|
+
</div>
|
|
561
|
+
</template>
|