waveform-analysis 0.1.24 → 0.1.26

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 (40) hide show
  1. package/README.md +45 -5
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +540 -487
  4. package/dist/types/App.vue.d.ts +4 -0
  5. package/dist/types/DemoRouterApp.vue.d.ts +3 -0
  6. package/dist/types/components/core/layout.d.ts +6 -3
  7. package/dist/types/components/core/trackLayoutBuilder.d.ts +2 -0
  8. package/dist/types/components/core/useWaveformChartController.d.ts +2 -0
  9. package/dist/types/components/core/waveformChartTypes.d.ts +2 -0
  10. package/dist/types/components/core/yDomain.d.ts +7 -0
  11. package/dist/types/demo/DemoChartHost.vue.d.ts +14 -0
  12. package/dist/types/demo/DemoControlPanel.vue.d.ts +11 -0
  13. package/dist/types/demo/DemoGridFrameControls.vue.d.ts +11 -0
  14. package/dist/types/demo/DemoTitleLegendControls.vue.d.ts +11 -0
  15. package/dist/types/demo/DemoViewControls.vue.d.ts +11 -0
  16. package/dist/types/demo/types.d.ts +84 -0
  17. package/dist/types/router.d.ts +3 -0
  18. package/dist/types/views/FixedYDomainDemo.vue.d.ts +3 -0
  19. package/package.json +2 -1
  20. package/src/DemoRouterApp.vue +14 -0
  21. package/src/components/core/fixedYDomainLayout.test.ts +116 -0
  22. package/src/components/core/layout.ts +43 -10
  23. package/src/components/core/trackLayoutBuilder.ts +17 -7
  24. package/src/components/core/useWaveformChartController.ts +10 -0
  25. package/src/components/core/useWaveformLayout.ts +20 -4
  26. package/src/components/core/waveformChartTypes.ts +2 -0
  27. package/src/components/core/yDomain.test.ts +56 -0
  28. package/src/components/core/yDomain.ts +50 -0
  29. package/src/components/interaction/useWaveformViewport.ts +6 -1
  30. package/src/components/rendering/WaveformTrack.vue +1 -1
  31. package/src/components/rendering/WaveformTrackAxes.vue +5 -7
  32. package/src/components/waveformChartCases/layoutAndDomains.test.ts +25 -0
  33. package/src/components/waveformChartCases/presentationAndAxes.test.ts +26 -6
  34. package/src/components/waveformChartCases/viewportBoxAndPan.test.ts +50 -0
  35. package/src/demoRoutes.css +197 -0
  36. package/src/main.ts +4 -2
  37. package/src/router.ts +21 -0
  38. package/src/styles.css +1 -2
  39. package/src/views/FixedYDomainDemo.test.ts +44 -0
  40. package/src/views/FixedYDomainDemo.vue +149 -0
@@ -0,0 +1,149 @@
1
+ <script setup lang="ts">
2
+ import { computed, ref } from 'vue'
3
+ import { InputNumber, RadioButton, RadioGroup } from 'ant-design-vue'
4
+
5
+ import { WaveformChart, type WaveformData } from '../components'
6
+
7
+ type RangeMode = 'auto' | 'global' | 'channel'
8
+
9
+ const rangeMode = ref<RangeMode>('global')
10
+ const globalMinimum = ref(-80)
11
+ const globalMaximum = ref(80)
12
+ const voltageMinimum = ref(-65)
13
+ const voltageMaximum = ref(65)
14
+ const currentMinimum = ref(-260)
15
+ const currentMaximum = ref(260)
16
+
17
+ const chartData: WaveformData = {
18
+ kind: 'series',
19
+ series: [
20
+ {
21
+ id: 'voltage',
22
+ name: '电压',
23
+ unit: 'V',
24
+ color: '#1677ff',
25
+ data: {
26
+ kind: 'points',
27
+ points: Array.from({ length: 800 }, (_, index) => {
28
+ const x = index / 80
29
+ const pulse = index % 240 >= 112 && index % 240 <= 122 ? 58 : 0
30
+ return { x, y: 48 * Math.sin(x * Math.PI * 1.5) + pulse }
31
+ }),
32
+ },
33
+ },
34
+ {
35
+ id: 'current',
36
+ name: '电流',
37
+ unit: 'mA',
38
+ color: '#d4380d',
39
+ data: {
40
+ kind: 'points',
41
+ points: Array.from({ length: 800 }, (_, index) => {
42
+ const x = index / 80
43
+ const pulse = index % 300 >= 184 && index % 300 <= 192 ? -210 : 0
44
+ return { x, y: 185 * Math.cos(x * Math.PI) + pulse }
45
+ }),
46
+ },
47
+ },
48
+ ],
49
+ }
50
+
51
+ function orderedDomain(minimum: number, maximum: number): [number, number] | undefined {
52
+ if (!Number.isFinite(minimum) || !Number.isFinite(maximum) || minimum === maximum) {
53
+ return undefined
54
+ }
55
+ return minimum < maximum ? [minimum, maximum] : [maximum, minimum]
56
+ }
57
+
58
+ const yDomain = computed<[number, number] | undefined>(() =>
59
+ rangeMode.value === 'global'
60
+ ? orderedDomain(globalMinimum.value, globalMaximum.value)
61
+ : undefined,
62
+ )
63
+ const yDomains = computed<Record<string, [number, number]> | undefined>(() => {
64
+ if (rangeMode.value !== 'channel') return undefined
65
+ const voltage = orderedDomain(voltageMinimum.value, voltageMaximum.value)
66
+ const current = orderedDomain(currentMinimum.value, currentMaximum.value)
67
+ return {
68
+ ...(voltage ? { voltage } : {}),
69
+ ...(current ? { current } : {}),
70
+ }
71
+ })
72
+ const rangeSummary = computed(() => {
73
+ if (rangeMode.value === 'auto') return '自动计算'
74
+ if (rangeMode.value === 'global') {
75
+ return yDomain.value ? `${yDomain.value[0]} ~ ${yDomain.value[1]}` : '自动计算'
76
+ }
77
+ const voltage = yDomains.value?.voltage
78
+ const current = yDomains.value?.current
79
+ return `电压 ${voltage?.[0] ?? '-'} ~ ${voltage?.[1] ?? '-'} V · 电流 ${
80
+ current?.[0] ?? '-'
81
+ } ~ ${current?.[1] ?? '-'} mA`
82
+ })
83
+ </script>
84
+
85
+ <template>
86
+ <main class="fixed-domain-demo">
87
+ <header class="fixed-domain-demo__toolbar">
88
+ <div>
89
+ <h1>固定振幅范围</h1>
90
+ <p>当前范围:{{ rangeSummary }}</p>
91
+ </div>
92
+ <RadioGroup v-model:value="rangeMode" button-style="solid" aria-label="Y 轴范围模式">
93
+ <RadioButton value="auto">自动</RadioButton>
94
+ <RadioButton value="global">全局固定</RadioButton>
95
+ <RadioButton value="channel">按通道固定</RadioButton>
96
+ </RadioGroup>
97
+ </header>
98
+
99
+ <section class="fixed-domain-demo__range-controls">
100
+ <template v-if="rangeMode === 'global'">
101
+ <label>
102
+ <span>下限</span>
103
+ <InputNumber v-model:value="globalMinimum" aria-label="全局振幅下限" />
104
+ </label>
105
+ <label>
106
+ <span>上限</span>
107
+ <InputNumber v-model:value="globalMaximum" aria-label="全局振幅上限" />
108
+ </label>
109
+ </template>
110
+ <template v-else-if="rangeMode === 'channel'">
111
+ <strong>电压</strong>
112
+ <label>
113
+ <span>下限</span>
114
+ <InputNumber v-model:value="voltageMinimum" aria-label="电压振幅下限" />
115
+ </label>
116
+ <label>
117
+ <span>上限</span>
118
+ <InputNumber v-model:value="voltageMaximum" aria-label="电压振幅上限" />
119
+ </label>
120
+ <strong>电流</strong>
121
+ <label>
122
+ <span>下限</span>
123
+ <InputNumber v-model:value="currentMinimum" aria-label="电流振幅下限" />
124
+ </label>
125
+ <label>
126
+ <span>上限</span>
127
+ <InputNumber v-model:value="currentMaximum" aria-label="电流振幅上限" />
128
+ </label>
129
+ </template>
130
+ <span v-else class="fixed-domain-demo__auto-state">根据可见数据自动计算</span>
131
+ </section>
132
+
133
+ <section class="fixed-domain-demo__chart">
134
+ <WaveformChart
135
+ :data="chartData"
136
+ :y-domain="yDomain"
137
+ :y-domains="yDomains"
138
+ display-mode="independent"
139
+ :grid="{ rowCount: 2, columnCount: 1, showPagination: false }"
140
+ :title="{ visible: true, text: '振幅上下限示例', align: 'left' }"
141
+ :zero-line="{ visible: true, color: '#98a2b3', width: 1, dash: '5 4' }"
142
+ :legend="{ position: 'top-right', backgroundColor: 'rgba(255,255,255,0.8)' }"
143
+ x-label="时间(s)"
144
+ time-unit="s"
145
+ :show-tooltip="true"
146
+ />
147
+ </section>
148
+ </main>
149
+ </template>