@kylincloud/flamegraph 0.35.23 → 0.35.24

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/CHANGELOG.md +13 -0
  2. package/dist/FlameGraph/FlameGraphComponent/FlamegraphBreadcrumb.d.ts +16 -0
  3. package/dist/FlameGraph/FlameGraphComponent/FlamegraphBreadcrumb.d.ts.map +1 -0
  4. package/dist/FlameGraph/FlameGraphComponent/Flamegraph_render.d.ts +1 -0
  5. package/dist/FlameGraph/FlameGraphComponent/Flamegraph_render.d.ts.map +1 -1
  6. package/dist/FlameGraph/FlameGraphComponent/index.d.ts +13 -0
  7. package/dist/FlameGraph/FlameGraphComponent/index.d.ts.map +1 -1
  8. package/dist/FlameGraph/FlameGraphRenderer.d.ts +9 -1
  9. package/dist/FlameGraph/FlameGraphRenderer.d.ts.map +1 -1
  10. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  11. package/dist/format/format.d.ts +14 -0
  12. package/dist/format/format.d.ts.map +1 -1
  13. package/dist/i18n.d.ts +7 -0
  14. package/dist/i18n.d.ts.map +1 -1
  15. package/dist/index.cjs.js +3 -3
  16. package/dist/index.cjs.js.map +1 -1
  17. package/dist/index.esm.js +4 -4
  18. package/dist/index.esm.js.map +1 -1
  19. package/dist/index.node.cjs.js +4 -4
  20. package/dist/index.node.cjs.js.map +1 -1
  21. package/dist/index.node.esm.js +4 -4
  22. package/dist/index.node.esm.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/FlameGraph/FlameGraphComponent/FlamegraphBreadcrumb.module.scss +106 -0
  25. package/src/FlameGraph/FlameGraphComponent/FlamegraphBreadcrumb.tsx +98 -0
  26. package/src/FlameGraph/FlameGraphComponent/Flamegraph_render.ts +23 -21
  27. package/src/FlameGraph/FlameGraphComponent/index.tsx +33 -1
  28. package/src/FlameGraph/FlameGraphRenderer.tsx +144 -3
  29. package/src/Tooltip/Tooltip.tsx +1 -75
  30. package/src/format/format.ts +98 -0
  31. package/src/i18n.tsx +27 -0
@@ -5,6 +5,104 @@ export function numberWithCommas(x: number): string {
5
5
  return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
6
6
  }
7
7
 
8
+ type NumericWithUnit = {
9
+ value: number;
10
+ unit: string;
11
+ hasLessThan: boolean;
12
+ sign: string;
13
+ };
14
+
15
+ export function parseNumericWithUnit(
16
+ input?: string | number
17
+ ): NumericWithUnit | null {
18
+ if (input == null) return null;
19
+
20
+ if (typeof input === 'number') {
21
+ return { value: input, unit: '', hasLessThan: false, sign: '' };
22
+ }
23
+
24
+ let s = String(input).trim().replace(/\u2212/g, '-');
25
+ if (!s) return null;
26
+
27
+ let hasLessThan = false;
28
+ if (s.startsWith('<')) {
29
+ hasLessThan = true;
30
+ s = s.slice(1).trim();
31
+ }
32
+
33
+ const m = s.match(/^([+\-]?)(\d*\.?\d+)\s*(.*)$/);
34
+ if (!m) return null;
35
+
36
+ const sign = m[1] || '';
37
+ const numStr = m[2];
38
+ const unit = (m[3] || '').trim();
39
+
40
+ const value = parseFloat(numStr);
41
+ if (!Number.isFinite(value)) return null;
42
+
43
+ return { value, unit, hasLessThan, sign };
44
+ }
45
+
46
+ export function localizeDurationString(
47
+ input?: string,
48
+ isZh = false
49
+ ): string | undefined {
50
+ if (!input || !isZh) return input;
51
+
52
+ const parsed = parseNumericWithUnit(input);
53
+ if (!parsed) return input;
54
+
55
+ const { unit } = parsed;
56
+
57
+ let unitZh = unit;
58
+ const u = unit.toLowerCase();
59
+
60
+ if (u === 'ms') unitZh = '毫秒';
61
+ else if (u === 'μs' || u === 'µs' || u === 'us') unitZh = '微秒';
62
+ else if (u === 'second' || u === 'seconds') unitZh = '秒';
63
+ else if (u === 'minute' || u === 'minutes' || u === 'min' || u === 'mins')
64
+ unitZh = '分钟';
65
+ else if (u === 'hour' || u === 'hours') unitZh = '小时';
66
+ else if (u === 'day' || u === 'days') unitZh = '天';
67
+ else if (u === 'month' || u === 'months') unitZh = '月';
68
+ else if (u === 'year' || u === 'years') unitZh = '年';
69
+
70
+ const m = String(input).match(/^([<\s]*)([+\-]?\d*\.?\d+)(.*)$/);
71
+ if (!m) return input;
72
+
73
+ const prefix = m[1] || '';
74
+ const numberPart = m[2] || '';
75
+
76
+ return `${prefix}${numberPart} ${unitZh}`.trim();
77
+ }
78
+
79
+ export type SampleCountFormat = Array<{ value: number; label: string }>;
80
+
81
+ const defaultSampleCountFormat: SampleCountFormat = [
82
+ { value: 1e15, label: 'Quad' },
83
+ { value: 1e12, label: 'Tri' },
84
+ { value: 1e9, label: 'B' },
85
+ { value: 1e6, label: 'M' },
86
+ { value: 1e3, label: 'K' },
87
+ ];
88
+
89
+ export function formatSampleCount(
90
+ value: number,
91
+ format: SampleCountFormat = defaultSampleCountFormat
92
+ ): string {
93
+ const absValue = Math.abs(value);
94
+ for (const { value: threshold, label } of format) {
95
+ if (absValue >= threshold) {
96
+ const scaled = value / threshold;
97
+ const fixed = scaled.toFixed(2);
98
+ const trimmed = fixed.replace(/\.?0+$/, '');
99
+ return `${trimmed} ${label}`;
100
+ }
101
+ }
102
+
103
+ return numberWithCommas(value);
104
+ }
105
+
8
106
  export function formatPercent(ratio: number) {
9
107
  const percent = ratioToPercent(ratio);
10
108
  return `${percent}%`;
package/src/i18n.tsx CHANGED
@@ -77,6 +77,11 @@ export type FlamegraphMessages = {
77
77
  // 火焰图聚焦时的 collapsed 提示
78
78
  collapsedLevelsSingular: string; // "total (1 level collapsed)"
79
79
  collapsedLevelsPlural: string; // "total (n levels collapsed)"
80
+
81
+ // Breadcrumb
82
+ ofTotal: string;
83
+ clearFocus: string;
84
+ sampleCountFormat: Array<{ value: number; label: string }>;
80
85
  };
81
86
 
82
87
  const defaultTooltipUnitTitles: Record<Units, TooltipUnitMessages> = {
@@ -235,6 +240,17 @@ export const defaultMessages: FlamegraphMessages = {
235
240
  // 火焰图聚焦时的 collapsed 提示
236
241
  collapsedLevelsSingular: 'total (1 level collapsed)',
237
242
  collapsedLevelsPlural: 'total ({n} levels collapsed)',
243
+
244
+ // Breadcrumb
245
+ ofTotal: 'of total',
246
+ clearFocus: 'Clear focus',
247
+ sampleCountFormat: [
248
+ { value: 1e15, label: 'Quad' },
249
+ { value: 1e12, label: 'Tri' },
250
+ { value: 1e9, label: 'B' },
251
+ { value: 1e6, label: 'M' },
252
+ { value: 1e3, label: 'K' },
253
+ ],
238
254
  };
239
255
 
240
256
  export const zhCNMessages: FlamegraphMessages = {
@@ -298,9 +314,20 @@ export const zhCNMessages: FlamegraphMessages = {
298
314
  // 火焰图聚焦时的 collapsed 提示
299
315
  collapsedLevelsSingular: '总计(已折叠 1 层)',
300
316
  collapsedLevelsPlural: '总计(已折叠 {n} 层)',
317
+
318
+ // Breadcrumb
319
+ ofTotal: '占总量',
320
+ clearFocus: '清除聚焦',
321
+ sampleCountFormat: [
322
+ { value: 1e12, label: '兆' },
323
+ { value: 1e8, label: '亿' },
324
+ { value: 1e4, label: '万' },
325
+ { value: 1e3, label: '千' },
326
+ ],
301
327
  };
302
328
 
303
329
  const I18nContext = createContext<FlamegraphMessages>(defaultMessages);
330
+ export const FlamegraphI18nContext = I18nContext;
304
331
 
305
332
  export type FlamegraphI18nProviderProps = {
306
333
  messages?: Partial<FlamegraphMessages>;