waveform-analysis 0.1.26 → 0.1.28

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 (31) hide show
  1. package/README.md +2 -2
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +535 -575
  4. package/dist/types/components/core/layout.d.ts +2 -4
  5. package/dist/types/components/core/types.d.ts +0 -3
  6. package/dist/types/utils/formatters.d.ts +9 -10
  7. package/dist/types/utils/index.d.ts +1 -1
  8. package/package.json +1 -1
  9. package/src/components/core/layout.test.ts +7 -8
  10. package/src/components/core/layout.ts +10 -20
  11. package/src/components/core/trackLayoutBuilder.ts +4 -23
  12. package/src/components/core/types.ts +0 -3
  13. package/src/components/core/useWaveformLayout.ts +5 -27
  14. package/src/components/interaction/WaveformTooltip.test.ts +16 -0
  15. package/src/components/interaction/useWaveformZoom.ts +12 -8
  16. package/src/components/rendering/WaveformTrackAxes.vue +4 -26
  17. package/src/components/waveformChartCases/compactAndSharedHover.test.ts +7 -7
  18. package/src/components/waveformChartCases/dataAndHoverPerformance.test.ts +2 -2
  19. package/src/components/waveformChartCases/dataLifecycle.test.ts +4 -4
  20. package/src/components/waveformChartCases/frameGridAndFormatting.test.ts +29 -22
  21. package/src/components/waveformChartCases/interactionAndAnnotationCreation.test.ts +1 -1
  22. package/src/components/waveformChartCases/layoutAndDomains.test.ts +16 -14
  23. package/src/components/waveformChartCases/multiAxisAndPagination.test.ts +8 -8
  24. package/src/components/waveformChartCases/presentationAndAxes.test.ts +6 -4
  25. package/src/components/waveformChartCases/presentationMode.test.ts +1 -1
  26. package/src/components/waveformChartCases/viewportBoxAndPan.test.ts +15 -0
  27. package/src/components/waveformChartCases/viewportConstraintsAndReset.test.ts +59 -11
  28. package/src/components/waveformChartCases/wheelZoomOut.test.ts +114 -0
  29. package/src/utils/formatters.test.ts +40 -31
  30. package/src/utils/formatters.ts +45 -45
  31. package/src/utils/index.ts +0 -1
@@ -4,22 +4,28 @@
4
4
  export type TimeUnit = 'ms' | 's'
5
5
 
6
6
  export interface ScientificAxisLabelOptions {
7
+ /** @deprecated Y-axis labels always use five significant digits before localization. */
7
8
  precision?: number
8
9
  axisMin?: number
9
10
  axisMax?: number
11
+ topTickValue?: number
10
12
  }
11
13
 
12
14
  /** @deprecated Use ScientificAxisLabelOptions. */
13
- export type ScientificYAxisLabelOptions = ScientificAxisLabelOptions & {
14
- topTickValue?: number
15
- }
15
+ export type ScientificYAxisLabelOptions = ScientificAxisLabelOptions
16
16
 
17
- const DEFAULT_Y_AXIS_PRECISION = 2
18
- const SCIENTIFIC_MIN_ABSOLUTE_VALUE = 0.01
19
- const SCIENTIFIC_MAX_PLAIN_ABSOLUTE_VALUE = 100
17
+ const SCIENTIFIC_MIN_ABSOLUTE_VALUE = 0.001
18
+ const SCIENTIFIC_MAX_PLAIN_ABSOLUTE_VALUE = 1000
19
+ const Y_AXIS_NUMBER_FORMATTER = new Intl.NumberFormat('zh-CN', {
20
+ maximumFractionDigits: 4,
21
+ })
20
22
  const TOOLTIP_NUMBER_FORMATTER = new Intl.NumberFormat('zh-CN', {
21
23
  maximumFractionDigits: 4,
22
24
  })
25
+ const X_AXIS_TIME_FORMATTER = new Intl.NumberFormat('zh-CN', {
26
+ maximumFractionDigits: 0,
27
+ useGrouping: false,
28
+ })
23
29
 
24
30
  function formatFixedNumber(value: number, precision: number): string {
25
31
  const formatted = value.toFixed(Math.max(0, precision))
@@ -38,9 +44,10 @@ export function shouldUseScientificAxisLabel(maxAbsoluteValue: number): boolean
38
44
  export function resolveScientificAxisExponent(axisMin?: number, axisMax?: number): number | null {
39
45
  if (typeof axisMin !== 'number' || typeof axisMax !== 'number') return null
40
46
 
41
- const maxAbsoluteValue = Math.max(Math.abs(axisMin), Math.abs(axisMax))
42
- return shouldUseScientificAxisLabel(maxAbsoluteValue)
43
- ? Math.floor(Math.log10(maxAbsoluteValue))
47
+ const maxValue = Math.max(axisMin, axisMax)
48
+ const absoluteMaxValue = Math.abs(maxValue)
49
+ return shouldUseScientificAxisLabel(absoluteMaxValue)
50
+ ? Math.floor(Math.log10(absoluteMaxValue))
44
51
  : null
45
52
  }
46
53
 
@@ -49,6 +56,13 @@ function formatExponent(exponent: number): string {
49
56
  return `E${sign}${Math.abs(exponent).toString().padStart(2, '0')}`
50
57
  }
51
58
 
59
+ function formatYAxisNumber(value: number): string {
60
+ if (Object.is(value, -0)) return '0'
61
+ const roundedValue = value === 0 ? 0 : Number(value.toPrecision(5))
62
+ const formatted = Y_AXIS_NUMBER_FORMATTER.format(roundedValue)
63
+ return formatted === '-0' ? '0' : formatted
64
+ }
65
+
52
66
  /** Format a Y-axis tick, sharing one exponent derived from the complete axis domain. */
53
67
  export function formatScientificAxisLabel(
54
68
  value: number,
@@ -56,10 +70,13 @@ export function formatScientificAxisLabel(
56
70
  ): string {
57
71
  if (!Number.isFinite(value)) return String(value)
58
72
 
59
- const precision = options.precision ?? DEFAULT_Y_AXIS_PRECISION
60
73
  const exponent = resolveScientificAxisExponent(options.axisMin, options.axisMax)
61
74
  const scaledValue = exponent === null ? value : value / 10 ** exponent
62
- return formatFixedNumber(scaledValue, precision)
75
+ const formattedValue = formatYAxisNumber(scaledValue)
76
+ const topTickValue = options.topTickValue ?? options.axisMax
77
+ return exponent !== null && value === topTickValue
78
+ ? `${formatExponent(exponent)} ${formattedValue}`
79
+ : formattedValue
63
80
  }
64
81
 
65
82
  /** Return the shared E-style multiplier for an axis, or null for a plain axis. */
@@ -86,6 +103,13 @@ export function formatTooltipNumber(value: number): string {
86
103
  return TOOLTIP_NUMBER_FORMATTER.format(value)
87
104
  }
88
105
 
106
+ /** Format an X-axis time value as a plain integer without grouping separators. */
107
+ function formatAxisTimeValue(value: number): string {
108
+ if (!Number.isFinite(value)) return String(value)
109
+ const formatted = X_AXIS_TIME_FORMATTER.format(value)
110
+ return formatted === '-0' ? '0' : formatted
111
+ }
112
+
89
113
  /** Convert a number to complete plain decimal text without forcing exponential notation. */
90
114
  export function formatPlainNumber(value: number): string {
91
115
  if (!Number.isFinite(value)) return String(value)
@@ -134,54 +158,34 @@ export function endpointFractionDigits(domain: [number, number], timeUnit: TimeU
134
158
  }
135
159
 
136
160
  /**
137
- * 按完整 X 轴显示域格式化端点时间
161
+ * 将 X 轴端点时间格式化为当前显示单位下的普通整数
138
162
  * @param value 时间值(秒)
139
- * @param domain 数据域
163
+ * @param _domain 数据域(为保持现有调用签名而保留)
140
164
  * @param timeUnit 时间单位
141
165
  * @returns 格式化的时间字符串
142
166
  */
143
167
  export function formatEndpointTime(
144
168
  value: number,
145
- domain: [number, number],
169
+ _domain: [number, number],
146
170
  timeUnit: TimeUnit,
147
171
  ): string {
148
- const [axisMin, axisMax] = domain.map((domainValue) => displayTime(domainValue, timeUnit)) as [
149
- number,
150
- number,
151
- ]
152
- return formatScientificAxisLabel(displayTime(value, timeUnit), {
153
- axisMin,
154
- axisMax,
155
- })
172
+ return formatAxisTimeValue(displayTime(value, timeUnit))
156
173
  }
157
174
 
158
175
  /**
159
- * 按完整 X 轴显示域格式化时间刻度
176
+ * 将 X 轴时间刻度格式化为当前显示单位下的普通整数
160
177
  * @param value 时间值(秒)
161
178
  * @param timeUnit 时间单位
179
+ * @param _domain 数据域(为保持现有调用签名而保留)
162
180
  * @returns 格式化的时间字符串
163
181
  */
164
182
  export function formatAxisTime(
165
183
  value: number,
166
184
  timeUnit: TimeUnit,
167
- domain?: [number, number],
185
+ _domain?: [number, number],
168
186
  ): string {
169
- const displayValue = displayTime(value, timeUnit)
170
- const displayDomain = domain?.map((domainValue) => displayTime(domainValue, timeUnit)) as
171
- [number, number] | undefined
172
- return formatScientificAxisLabel(displayValue, {
173
- axisMin: displayDomain?.[0],
174
- axisMax: displayDomain?.[1],
175
- })
176
- }
177
-
178
- /** Return the shared multiplier for an X-axis domain in its selected display unit. */
179
- export function formatAxisTimeExponent(
180
- domain: [number, number],
181
- timeUnit: TimeUnit,
182
- ): string | null {
183
- const [axisMin, axisMax] = domain.map((value) => displayTime(value, timeUnit)) as [number, number]
184
- return formatScientificAxisExponent(axisMin, axisMax)
187
+ void _domain
188
+ return formatAxisTimeValue(displayTime(value, timeUnit))
185
189
  }
186
190
 
187
191
  /**
@@ -191,11 +195,7 @@ export function formatAxisTimeExponent(
191
195
  * @returns 格式化的时间字符串
192
196
  */
193
197
  export function formatTooltipTime(value: number, timeUnit: TimeUnit): string {
194
- const displayValue = displayTime(value, timeUnit)
195
- return displayValue.toLocaleString('zh-CN', {
196
- minimumFractionDigits: 4,
197
- maximumFractionDigits: 4,
198
- })
198
+ return formatTooltipNumber(displayTime(value, timeUnit))
199
199
  }
200
200
 
201
201
  /** Format an annotation X coordinate in the selected display time unit. */
@@ -11,7 +11,6 @@ export {
11
11
  endpointFractionDigits,
12
12
  formatEndpointTime,
13
13
  formatAxisTime,
14
- formatAxisTimeExponent,
15
14
  formatTooltipTime,
16
15
  formatAnnotationTime,
17
16
  formatPlainNumber,