@kylincloud/flamegraph 0.35.27 → 0.35.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 (37) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/FlameGraph/FlameGraphComponent/DiffLegend.d.ts.map +1 -1
  3. package/dist/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.d.ts.map +1 -1
  4. package/dist/FlameGraph/FlameGraphComponent/index.d.ts.map +1 -1
  5. package/dist/Icons.d.ts.map +1 -1
  6. package/dist/SharedQueryInput.d.ts.map +1 -1
  7. package/dist/Toolbar.d.ts.map +1 -1
  8. package/dist/index.cjs.js +4 -4
  9. package/dist/index.cjs.js.map +1 -1
  10. package/dist/index.esm.js +4 -4
  11. package/dist/index.esm.js.map +1 -1
  12. package/dist/index.node.cjs.js +2 -2
  13. package/dist/index.node.cjs.js.map +1 -1
  14. package/dist/index.node.esm.js +4 -4
  15. package/dist/index.node.esm.js.map +1 -1
  16. package/dist/shims/Table.d.ts.map +1 -1
  17. package/dist/shims/Tooltip.d.ts.map +1 -1
  18. package/package.json +1 -1
  19. package/src/FlameGraph/FlameGraphComponent/DiffLegend.module.css +8 -2
  20. package/src/FlameGraph/FlameGraphComponent/DiffLegend.tsx +12 -1
  21. package/src/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.module.css +93 -10
  22. package/src/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.tsx +9 -4
  23. package/src/FlameGraph/FlameGraphComponent/index.tsx +58 -56
  24. package/src/FlameGraph/FlameGraphComponent/styles.module.scss +8 -0
  25. package/src/Icons.tsx +18 -9
  26. package/src/SharedQueryInput.module.scss +50 -0
  27. package/src/SharedQueryInput.tsx +18 -3
  28. package/src/Toolbar.module.scss +90 -0
  29. package/src/Toolbar.tsx +30 -16
  30. package/src/i18n.tsx +1 -1
  31. package/src/sass/_common.scss +22 -3
  32. package/src/sass/_css-variables.scss +5 -1
  33. package/src/sass/flamegraph.scss +26 -23
  34. package/src/shims/Table.module.scss +86 -13
  35. package/src/shims/Table.tsx +7 -2
  36. package/src/shims/Tooltip.module.scss +40 -0
  37. package/src/shims/Tooltip.tsx +31 -3
@@ -1 +1 @@
1
- {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/shims/Table.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAoB,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAUrF,UAAU,UAAU;IAClB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;CACvH;AAED,MAAM,WAAW,IAAK,SAAQ,UAAU;IACtC,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED,UAAU,QAAS,SAAQ,UAAU;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GACrB;IACA,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACC;IACA,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,CAAC;AAEJ,KAAK,KAAK,GAAG,aAAa,GAAG;IAC3B,OAAO,EAAE,QAAQ,EAAE,CAAC;CACrB,CAAC;AAEF,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,eAAe,EAAE,MAAM,GAAG,KAAK,CAAC;CACjC;AAED,eAAO,MAAM,YAAY,YAAa,QAAQ,EAAE,KAAG,cAsBlD,CAAC;AAEF,UAAU,UAAU;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,KAAK,EAAE,KAAK,CAAC;IACb,YAAY,CAAC,EAAE,SAAS,CAAC,uBAAuB,CAAC,CAAC;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA0CD,iBAAS,KAAK,CAAC,EACb,eAAe,EACf,MAAM,EACN,gBAAgB,EAChB,KAAK,EACL,YAAY,EACZ,SAAS,EACT,SAAS,EACT,YAAY,GACb,EAAE,UAAU,2CAkEZ;AA2DD,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/shims/Table.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAoB,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAUrF,UAAU,UAAU;IAClB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;CACvH;AAED,MAAM,WAAW,IAAK,SAAQ,UAAU;IACtC,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED,UAAU,QAAS,SAAQ,UAAU;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GACrB;IACA,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACC;IACA,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,CAAC;AAEJ,KAAK,KAAK,GAAG,aAAa,GAAG;IAC3B,OAAO,EAAE,QAAQ,EAAE,CAAC;CACrB,CAAC;AAEF,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,eAAe,EAAE,MAAM,GAAG,KAAK,CAAC;CACjC;AAED,eAAO,MAAM,YAAY,YAAa,QAAQ,EAAE,KAAG,cAsBlD,CAAC;AAEF,UAAU,UAAU;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,KAAK,EAAE,KAAK,CAAC;IACb,YAAY,CAAC,EAAE,SAAS,CAAC,uBAAuB,CAAC,CAAC;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA0CD,iBAAS,KAAK,CAAC,EACb,eAAe,EACf,MAAM,EACN,gBAAgB,EAChB,KAAK,EACL,YAAY,EACZ,SAAS,EACT,SAAS,EACT,YAAY,GACb,EAAE,UAAU,2CAuEZ;AA2DD,eAAe,KAAK,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../src/shims/Tooltip.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AA2BD,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAe1C,CAAA"}
1
+ {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../src/shims/Tooltip.tsx"],"names":[],"mappings":"AACA,OAAO,KAAsC,MAAM,OAAO,CAAA;AAG1D,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AA2BD,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CA0C1C,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kylincloud/flamegraph",
3
- "version": "0.35.27",
3
+ "version": "0.35.28",
4
4
  "description": "KylinCloud flamegraph renderer (Pyroscope-based)",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.node.cjs.js",
@@ -1,7 +1,11 @@
1
1
  .flamegraph-legend {
2
2
  display: flex;
3
3
  align-items: center;
4
- font-size: 11px;
4
+ font-size: var(--legend-font-size, 11px);
5
+ line-height: var(--legend-line-height, 1);
6
+ --legend-item-width: 37px;
7
+ --legend-item-padding: 0;
8
+ --legend-item-height: auto;
5
9
  justify-content: center;
6
10
  }
7
11
 
@@ -11,7 +15,9 @@
11
15
  }
12
16
 
13
17
  .flamegraph-legend-item {
14
- width: 37px;
18
+ width: var(--legend-item-width, 37px);
19
+ height: var(--legend-item-height, auto);
20
+ padding: var(--legend-item-padding, 0);
15
21
  text-align: center;
16
22
 
17
23
  /* if for some reason the contents can't fit
@@ -14,11 +14,22 @@ export default function DiffLegend(props: DiffLegendProps) {
14
14
  const values = decideLegend(showMode);
15
15
 
16
16
  const color = NewDiffColor(palette);
17
+ const compactLegendStyle =
18
+ showMode === 'small'
19
+ ? ({
20
+ '--legend-item-width': '32px',
21
+ '--legend-item-padding': '2px 2px',
22
+ '--legend-font-size': '10px',
23
+ '--legend-line-height': '1.1',
24
+ '--legend-item-height': '16px',
25
+ } as React.CSSProperties)
26
+ : undefined;
17
27
 
18
28
  return (
19
29
  <div
20
30
  data-testid="flamegraph-legend"
21
31
  className={`${styles['flamegraph-legend']} ${styles['flamegraph-legend-list']}`}
32
+ style={compactLegendStyle}
22
33
  >
23
34
  {values.map((v) => (
24
35
  <div
@@ -43,7 +54,7 @@ function decideLegend(showMode: sizeMode) {
43
54
  }
44
55
 
45
56
  case 'small': {
46
- return [-100, -40, -20, 0, 20, 40, 100];
57
+ return [-100, -50, 0, 50, 100];
47
58
  }
48
59
 
49
60
  default:
@@ -10,38 +10,116 @@
10
10
  .triggerButton {
11
11
  display: flex;
12
12
  align-items: center;
13
- gap: 6px;
14
- padding: 4px 8px;
13
+ gap: 4px;
14
+ padding: 2px 16px 2px 6px;
15
15
  border: 1px solid var(--ps-ui-border);
16
16
  border-radius: 4px;
17
- background-color: var(--ps-immutable-off-white);
17
+ background-color: transparent;
18
18
  cursor: pointer;
19
- height: 37px;
19
+ height: 32px;
20
+ margin-right: 0;
20
21
  }
21
22
 
22
23
  .triggerButton:hover {
23
- background-color: var(--ps-ui-element-bg-highlight);
24
+ background-color: transparent;
25
+ border-color: #6aa27d;
26
+ }
27
+
28
+ .triggerButton:focus-visible,
29
+ .triggerButton[aria-expanded='true'] {
30
+ border-color: #3c7150;
31
+ box-shadow: 0 0 0 3px rgba(60, 113, 80, 0.22);
32
+ }
33
+
34
+ .triggerButton::after {
35
+ top: 50%;
36
+ right: 6px;
37
+ transform: translateY(-50%);
38
+ font-size: 10px;
24
39
  }
25
40
 
26
41
  .dropdownArrow {
27
42
  font-size: 8px;
28
43
  color: var(--ps-text-secondary);
29
- margin-left: 4px;
44
+ margin-left: 2px;
30
45
  }
31
46
 
32
47
  /* 菜单项样式 */
33
48
  .menuItem {
34
49
  display: flex;
35
50
  align-items: center;
36
- justify-content: space-between;
37
- gap: 12px;
38
- min-width: 200px;
39
- padding: 4px 0;
51
+ justify-content: flex-start;
52
+ gap: 6px;
53
+ min-width: 148px;
54
+ padding: 4px 8px;
40
55
  }
41
56
 
42
57
  .menuItemText {
43
58
  color: var(--ps-text-primary);
44
59
  font-size: 13px;
60
+ line-height: 1.2;
61
+ }
62
+
63
+ .dropdownMenu :global(.szh-menu__header) {
64
+ padding: 6px 12px 4px;
65
+ color: #8a8f99;
66
+ font-size: 12px;
67
+ font-weight: 500;
68
+ letter-spacing: 0.2px;
69
+ }
70
+
71
+ .dropdownMenu :global(.szh-menu) {
72
+ margin-top: 4px;
73
+ transform-origin: top center;
74
+ animation: dropdownZoomIn 0.18s ease-out;
75
+ }
76
+
77
+ .menuItemWrapper {
78
+ background-color: transparent !important;
79
+ border: 1px solid transparent;
80
+ border-radius: 6px;
81
+ margin: 2px 6px;
82
+ padding: 0;
83
+ }
84
+
85
+ .menuItemSelected {
86
+ background-color: rgba(93, 151, 111, 0.38) !important;
87
+ border-color: transparent;
88
+ }
89
+
90
+ .menuItemSelected .menuItemText {
91
+ font-weight: 600;
92
+ }
93
+
94
+ .menuItemWrapper:global(.szh-menu__item--hover),
95
+ .menuItemWrapper:global(.szh-menu__item--focus),
96
+ .menuItemWrapper:global(.szh-menu__item--active) {
97
+ background-color: #f5f5f5 !important;
98
+ border-color: transparent;
99
+ }
100
+
101
+ .menuItemSelected:global(.szh-menu__item--hover),
102
+ .menuItemSelected:global(.szh-menu__item--focus),
103
+ .menuItemSelected:global(.szh-menu__item--active) {
104
+ background-color: rgba(93, 151, 111, 0.38) !important;
105
+ border-color: transparent;
106
+ }
107
+
108
+ @keyframes dropdownZoomIn {
109
+ from {
110
+ opacity: 0;
111
+ transform: scaleY(0.92);
112
+ }
113
+ to {
114
+ opacity: 1;
115
+ transform: scaleY(1);
116
+ }
117
+ }
118
+
119
+ @media (prefers-reduced-motion: reduce) {
120
+ .dropdownMenu :global(.szh-menu) {
121
+ animation: none;
122
+ }
45
123
  }
46
124
 
47
125
  /* ========== 以下为旧样式,保留兼容性 ========== */
@@ -86,3 +164,8 @@
86
164
  height: 16px;
87
165
  flex-shrink: 0;
88
166
  }
167
+
168
+ :global([data-theme='kylin']) .triggerButton {
169
+ height: 28px;
170
+ padding: 1px 14px 1px 6px;
171
+ }
@@ -8,7 +8,6 @@ import {
8
8
  FlamegraphPalette,
9
9
  } from './colorPalette';
10
10
  import DiffLegend from './DiffLegend';
11
- import CheckIcon from './CheckIcon';
12
11
  // 在把通用 UI 抽成独立包之前,临时复用 shims 目录下的 Dropdown 封装
13
12
  // eslint-disable-next-line
14
13
  import Dropdown, { MenuItem, MenuButton } from '../../shims/Dropdown';
@@ -62,6 +61,7 @@ export const DiffLegendPaletteDropdown = (
62
61
  // 下拉菜单的无障碍 label 文案(i18n)
63
62
  label={messages.diffLegendSelectPalette}
64
63
  align="end"
64
+ className={styles.dropdownMenu}
65
65
  menuButton={
66
66
  <MenuButton
67
67
  className={cx(
@@ -82,13 +82,18 @@ export const DiffLegendPaletteDropdown = (
82
82
  }}
83
83
  >
84
84
  {paletteList.map((p) => (
85
- <MenuItem key={p.name} value={p}>
85
+ <MenuItem
86
+ key={p.name}
87
+ value={p}
88
+ className={cx(
89
+ styles.menuItemWrapper,
90
+ p.name === palette.name && styles.menuItemSelected
91
+ )}
92
+ >
86
93
  <div className={styles.menuItem}>
87
94
  <span className={styles.menuItemText}>
88
95
  {getPaletteName(p)} {getPaletteColorDesc(p)}
89
96
  </span>
90
- {/* 当前选中的调色板右侧展示对勾图标 */}
91
- {p.name === palette.name && <CheckIcon />}
92
97
  </div>
93
98
  </MenuItem>
94
99
  ))}
@@ -418,67 +418,69 @@ export default function FlameGraphComponent(props: FlamegraphProps) {
418
418
  'vertical-orientation': flamebearer.format === 'double',
419
419
  })}
420
420
  >
421
- {breadcrumb && (
422
- <FlamegraphBreadcrumb
423
- totalValueText={breadcrumb.totalValueText}
424
- totalSamplesText={breadcrumb.totalSamplesText}
425
- samplesLabel={breadcrumb.samplesLabel}
426
- unitLabel={breadcrumb.unitLabel}
427
- hasFocus={breadcrumb.hasFocus}
428
- focusPercent={breadcrumb.focusPercent}
429
- focusLabel={breadcrumb.focusLabel}
430
- ofTotalPlacement={breadcrumb.ofTotalPlacement}
431
- ofTotalLabel={breadcrumb.ofTotalLabel}
432
- clearFocusLabel={breadcrumb.clearFocusLabel}
433
- onClearFocus={breadcrumb.onClearFocus}
434
- />
435
- )}
436
- {/* Header 已简化,仅在 single 模式下显示标题 */}
437
- {/* DiffLegend 已移到 Toolbar */}
438
- {headerVisible && (
439
- <Header
440
- format={flamebearer.format}
441
- units={flamebearer.units}
442
- toolbarVisible={toolbarVisible}
443
- />
444
- )}
445
- <div
446
- data-testid={dataTestId}
447
- style={{
448
- position: 'relative',
449
- opacity: dataUnavailable && !showSingleLevel ? 0 : 1,
450
- }}
451
- >
452
- <canvas
453
- height="0"
454
- data-testid="flamegraph-canvas"
455
- data-highlightquery={highlightQuery}
456
- className={clsx('flamegraph-canvas', styles.canvas)}
457
- ref={canvasRef}
458
- onClick={!disableClick ? onClick : undefined}
459
- />
460
- <canvas
461
- height="0"
462
- data-testid="flamegraph-text-canvas"
463
- className={clsx('flamegraph-text-canvas', styles.textCanvas)}
464
- ref={textCanvasRef}
465
- />
466
- {flamegraph && canvasRef && (
467
- <Highlight
468
- barHeight={PX_PER_LEVEL}
469
- canvasRef={canvasRef}
470
- zoom={zoom}
471
- xyToHighlightData={xyToHighlightData}
421
+ <div className={indexStyles.flamegraphFrame}>
422
+ {breadcrumb && (
423
+ <FlamegraphBreadcrumb
424
+ totalValueText={breadcrumb.totalValueText}
425
+ totalSamplesText={breadcrumb.totalSamplesText}
426
+ samplesLabel={breadcrumb.samplesLabel}
427
+ unitLabel={breadcrumb.unitLabel}
428
+ hasFocus={breadcrumb.hasFocus}
429
+ focusPercent={breadcrumb.focusPercent}
430
+ focusLabel={breadcrumb.focusLabel}
431
+ ofTotalPlacement={breadcrumb.ofTotalPlacement}
432
+ ofTotalLabel={breadcrumb.ofTotalLabel}
433
+ clearFocusLabel={breadcrumb.clearFocusLabel}
434
+ onClearFocus={breadcrumb.onClearFocus}
472
435
  />
473
436
  )}
474
- {flamegraph && (
475
- <ContextMenuHighlight
476
- barHeight={PX_PER_LEVEL}
477
- node={rightClickedNode}
437
+ {/* Header 已简化,仅在 single 模式下显示标题 */}
438
+ {/* DiffLegend 已移到 Toolbar */}
439
+ {headerVisible && (
440
+ <Header
441
+ format={flamebearer.format}
442
+ units={flamebearer.units}
443
+ toolbarVisible={toolbarVisible}
478
444
  />
479
445
  )}
446
+ <div
447
+ data-testid={dataTestId}
448
+ style={{
449
+ position: 'relative',
450
+ opacity: dataUnavailable && !showSingleLevel ? 0 : 1,
451
+ }}
452
+ >
453
+ <canvas
454
+ height="0"
455
+ data-testid="flamegraph-canvas"
456
+ data-highlightquery={highlightQuery}
457
+ className={clsx('flamegraph-canvas', styles.canvas)}
458
+ ref={canvasRef}
459
+ onClick={!disableClick ? onClick : undefined}
460
+ />
461
+ <canvas
462
+ height="0"
463
+ data-testid="flamegraph-text-canvas"
464
+ className={clsx('flamegraph-text-canvas', styles.textCanvas)}
465
+ ref={textCanvasRef}
466
+ />
467
+ {flamegraph && canvasRef && (
468
+ <Highlight
469
+ barHeight={PX_PER_LEVEL}
470
+ canvasRef={canvasRef}
471
+ zoom={zoom}
472
+ xyToHighlightData={xyToHighlightData}
473
+ />
474
+ )}
475
+ {flamegraph && (
476
+ <ContextMenuHighlight
477
+ barHeight={PX_PER_LEVEL}
478
+ node={rightClickedNode}
479
+ />
480
+ )}
481
+ </div>
482
+ {showCredit ? <LogoLink /> : ''}
480
483
  </div>
481
- {showCredit ? <LogoLink /> : ''}
482
484
  {flamegraph && (
483
485
  <FlamegraphTooltip
484
486
  format={flamebearer.format}
@@ -8,3 +8,11 @@
8
8
  margin-right: 10px;
9
9
  }
10
10
  }
11
+
12
+ .flamegraphFrame {
13
+ border: 1px solid var(--ps-ui-border);
14
+ border-radius: 6px;
15
+ padding: 6px 8px 8px;
16
+ background-color: transparent;
17
+ min-height: var(--kylin-flamegraph-pane-min-height, 320px);
18
+ }
package/src/Icons.tsx CHANGED
@@ -2,27 +2,36 @@ import React from 'react';
2
2
 
3
3
  export const TableIcon = () => {
4
4
  return (
5
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
6
- <g id="z9nPJj.tif">
7
- <path d="M62,13.33V49.68c-.02,.05-.04,.11-.05,.16-.3,2.66-2.66,5.16-6.08,5.15-15.92,0-31.83,0-47.75-.01-.54,0-1.1-.06-1.62-.19-2.73-.69-4.52-3.09-4.52-5.88,0-12,.01-23.56,.01-34.9,0-.29,.01-.57,.05-.86,.35-2.3,1.62-3.91,3.84-4.75,.6-.23,1.27-.28,1.9-.41,16.13,0,32.27,0,48.4,0,.09,.01,.17,.04,.26,.04,2.66,.21,4.8,2.01,5.4,4.57,.06,.24,.1,.48,.14,.72ZM28.99,31.81c0-3.92-.01-7.91-.01-11.81H8c0,3.91,.01,7.9,.01,11.81H28.99Zm27,0c0-3.92-.01-7.92-.01-11.81h-20.97c0,3.92,.01,7.91,.01,11.81h20.97Zm-47.98,5.19c0,3.7,0,8,0,11.69v.31H29v-12m6.01,.04c0,3.93-.01,8.05-.01,11.96h20.99c0-.12,0-.22,0-.31,0-3.7,0-7.99,0-11.69" />
8
- </g>
5
+ <svg
6
+ xmlns="http://www.w3.org/2000/svg"
7
+ viewBox="64 64 896 896"
8
+ fill="currentColor"
9
+ >
10
+ <path d="M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 208H676V232h212v136zm0 224H676V432h212v160zM412 432h200v160H412V432zm200-64H412V232h200v136zm-476 64h212v160H136V432zm0-200h212v136H136V232zm0 424h212v136H136V656zm276 0h200v136H412V656zm476 136H676V656h212v136z" />
9
11
  </svg>
10
12
  );
11
13
  };
12
14
 
13
15
  export const TablePlusFlamegraphIcon = () => {
14
16
  return (
15
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
16
- <path d="M31,8.04H7.62c-.61,.13-1.26,.18-1.84,.41-2.14,.84-3.37,2.45-3.71,4.75-.04,.28-.05,.57-.05,.86,0,11.32-.02,22.88-.01,34.87,0,2.79,1.73,5.18,4.37,5.88,.51,.13,1.04,.19,1.57,.19,7.69,0,15.38,0,23.07,0V8.04Zm-2.92,11.99c0,3.9,.01,7.89,.01,11.8H7.82c0-3.9-.01-7.89-.01-11.8H28.08ZM7.82,49.01v-.31c0-3.69,0-7.99,0-11.68H28.1v11.99H7.82Z" />
17
- <path d="M58.67,7.9h-25.67V55h2.9c1.84,0,2.9-1.55,2.9-3.45V27.14h11.6v6.37c0,1.91,1.49,3.45,3.33,3.45h4.94c1.84,0,3.33-1.55,3.33-3.45V11.35c0-1.91-1.49-3.45-3.33-3.45Z" />
17
+ <svg
18
+ xmlns="http://www.w3.org/2000/svg"
19
+ viewBox="64 64 896 896"
20
+ fill="currentColor"
21
+ >
22
+ <path d="M464 144H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H212V212h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H612V212h200v200zM464 544H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H212V612h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H612V612h200v200z" />
18
23
  </svg>
19
24
  );
20
25
  };
21
26
 
22
27
  export const FlamegraphIcon = () => {
23
28
  return (
24
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
25
- <path d="M5.44,8H58.56c1.9,0,3.44,1.54,3.44,3.44v6.16s0,9.6,0,9.6v6.36c0,1.9-1.54,3.44-3.44,3.44h-5.11c-1.9,0-3.44-1.54-3.44-3.44v-6.36h-12s0,9.8,0,9.8v9s0,5.56,0,5.56c0,1.9-1.1,3.44-3,3.44h-6c-1.9,0-3-1.54-3-3.44v-5.56h-9c-1.99,0-3-1.52-3-3.4v-5.6H5.44c-1.9,0-3.44-1.74-3.44-3.64v-6.16s0-9.6,0-9.6v-6.16c0-1.9,1.54-3.44,3.44-3.44Z" />
29
+ <svg
30
+ xmlns="http://www.w3.org/2000/svg"
31
+ viewBox="64 64 896 896"
32
+ fill="currentColor"
33
+ >
34
+ <path d="M834.1 469.2A347.49 347.49 0 00751.2 354l-29.1-26.7a8.09 8.09 0 00-13 3.3l-13 37.3c-8.1 23.4-23 47.3-44.1 70.8-1.4 1.5-3 1.9-4.1 2-1.1.1-2.8-.1-4.3-1.5-1.4-1.2-2.1-3-2-4.8 3.7-60.2-14.3-128.1-53.7-202C555.3 171 510 123.1 453.4 89.7l-41.3-24.3c-5.4-3.2-12.3 1-12 7.3l2.2 48c1.5 32.8-2.3 61.8-11.3 85.9-11 29.5-26.8 56.9-47 81.5a295.64 295.64 0 01-47.5 46.1 352.6 352.6 0 00-100.3 121.5A347.75 347.75 0 00160 610c0 47.2 9.3 92.9 27.7 136a349.4 349.4 0 0075.5 110.9c32.4 32 70 57.2 111.9 74.7C418.5 949.8 464.5 959 512 959s93.5-9.2 136.9-27.3A348.6 348.6 0 00760.8 857c32.4-32 57.8-69.4 75.5-110.9a344.2 344.2 0 0027.7-136c0-48.8-10-96.2-29.9-140.9zM713 808.5c-53.7 53.2-125 82.4-201 82.4s-147.3-29.2-201-82.4c-53.5-53.1-83-123.5-83-198.4 0-43.5 9.8-85.2 29.1-124 18.8-37.9 46.8-71.8 80.8-97.9a349.6 349.6 0 0058.6-56.8c25-30.5 44.6-64.5 58.2-101a240 240 0 0012.1-46.5c24.1 22.2 44.3 49 61.2 80.4 33.4 62.6 48.8 118.3 45.8 165.7a74.01 74.01 0 0024.4 59.8 73.36 73.36 0 0053.4 18.8c19.7-1 37.8-9.7 51-24.4 13.3-14.9 24.8-30.1 34.4-45.6 14 17.9 25.7 37.4 35 58.4 15.9 35.8 24 73.9 24 113.1 0 74.9-29.5 145.4-83 198.4z" />
26
35
  </svg>
27
36
  );
28
37
  };
@@ -134,3 +134,53 @@
134
134
  border-right-color: var(--ps-immutable-linked-border);
135
135
  border-bottom-color: var(--ps-immutable-linked-border);
136
136
  }
137
+
138
+ .searchIcon {
139
+ position: absolute;
140
+ left: 10px;
141
+ top: 50%;
142
+ transform: translateY(-50%);
143
+ color: var(--ps-toolbar-icon-color);
144
+ font-size: 12px;
145
+ pointer-events: none;
146
+ display: inline-flex;
147
+ align-items: center;
148
+ z-index: 2;
149
+ }
150
+
151
+ :global([data-theme='kylin']) {
152
+ .search {
153
+ height: 28px;
154
+ border-radius: 4px;
155
+ padding: 0 10px 0 28px;
156
+ font-size: 12px;
157
+ color: #262626;
158
+ background: #ffffff;
159
+ border-color: #d9d9d9;
160
+ }
161
+
162
+ .search::placeholder {
163
+ color: #8c8c8c;
164
+ }
165
+
166
+ .search:hover {
167
+ border-color: #3c7150;
168
+ }
169
+
170
+ .search:focus-visible,
171
+ .search:focus {
172
+ border-color: #3c7150;
173
+ box-shadow: 0 0 0 2px rgba(60, 113, 80, 0.2);
174
+ }
175
+
176
+ .searchIcon {
177
+ color: #8c8c8c;
178
+ }
179
+
180
+ .sync,
181
+ .syncSelected {
182
+ height: 28px;
183
+ width: 28px;
184
+ border-radius: 4px;
185
+ }
186
+ }
@@ -1,7 +1,8 @@
1
1
  /* eslint-disable no-unused-expressions */
2
- import React, { useEffect, useMemo, ChangeEvent, useRef } from 'react';
2
+ import React, { useEffect, useMemo, ChangeEvent, useRef, useState } from 'react';
3
3
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
4
4
  import { faLink } from '@fortawesome/free-solid-svg-icons/faLink';
5
+ import { faSearch } from '@fortawesome/free-solid-svg-icons/faSearch';
5
6
  import Input from './shims/Input';
6
7
  import { Tooltip } from './shims/Tooltip';
7
8
  import styles from './SharedQueryInput.module.scss';
@@ -33,6 +34,8 @@ const SharedQueryInput = ({
33
34
  }: SharedQueryProps) => {
34
35
  const messages = useFlamegraphI18n();
35
36
  const prevSyncEnabled = usePreviousSyncEnabled(sharedQuery?.syncEnabled);
37
+ const wrapperRef = useRef<HTMLDivElement | null>(null);
38
+ const [isKylin, setIsKylin] = useState(false);
36
39
 
37
40
  const onQueryChange = (e: ChangeEvent<HTMLInputElement>) => {
38
41
  onHighlightChange(e.target.value);
@@ -58,6 +61,15 @@ const SharedQueryInput = ({
58
61
  }
59
62
  }, [sharedQuery?.searchQuery, sharedQuery?.syncEnabled]);
60
63
 
64
+ useEffect(() => {
65
+ const el = wrapperRef.current;
66
+ if (!el) return;
67
+ const kylinEl = el.closest(
68
+ "[data-theme='kylin'], [data-flamegraph-color-mode='kylin']"
69
+ );
70
+ setIsKylin(!!kylinEl);
71
+ }, []);
72
+
61
73
  const onToggleSync = () => {
62
74
  const newValue = sharedQuery?.syncEnabled ? false : sharedQuery?.id;
63
75
  sharedQuery?.toggleSync(newValue as string | false);
@@ -91,13 +103,16 @@ const SharedQueryInput = ({
91
103
  : messages.syncSearchBars;
92
104
 
93
105
  return (
94
- <div className={styles.wrapper} style={{ width }}>
106
+ <div ref={wrapperRef} className={styles.wrapper} style={{ width }}>
107
+ <span className={styles.searchIcon}>
108
+ <FontAwesomeIcon icon={faSearch} />
109
+ </span>
95
110
  <Input
96
111
  testId="flamegraph-search"
97
112
  className={inputClassName}
98
113
  type="search"
99
114
  name="flamegraph-search"
100
- placeholder={messages.searchPlaceholder}
115
+ placeholder={isKylin ? '搜索函数 / 过滤' : messages.searchPlaceholder}
101
116
  minLength={1}
102
117
  debounceTimeout={100}
103
118
  onChange={onQueryChange}
@@ -128,3 +128,93 @@ $buttonHeight: 37px;
128
128
  padding: 4px;
129
129
  z-index: 1;
130
130
  }
131
+
132
+ :global([data-theme='kylin']) {
133
+ .navbar {
134
+ height: 40px;
135
+ padding: 4px 0;
136
+ background-color: transparent;
137
+ border-color: transparent;
138
+ }
139
+
140
+ .searchWrapper {
141
+ width: 180px;
142
+ }
143
+
144
+ .navbar button {
145
+ color: #595959;
146
+ }
147
+
148
+ .toggleViewButton,
149
+ .fitModeButton,
150
+ .collapseNodeButton,
151
+ .resetViewButton {
152
+ height: 28px;
153
+ width: 28px;
154
+ border: 1px solid #d9d9d9;
155
+ background-color: #ffffff;
156
+ border-radius: 4px;
157
+ }
158
+
159
+ .toggleViewButton:hover,
160
+ .fitModeButton:hover,
161
+ .collapseNodeButton:hover,
162
+ .resetViewButton:hover {
163
+ border-color: #3c7150;
164
+ color: #3c7150;
165
+ background-color: #e6f4ea;
166
+ }
167
+
168
+ .collapseNodeButton,
169
+ .resetViewButton {
170
+ background-color: #fafafa;
171
+ }
172
+
173
+ .collapseNodeButton:disabled,
174
+ .resetViewButton:disabled {
175
+ color: #bfbfbf;
176
+ border-color: #d9d9d9;
177
+ background-color: #f5f5f5;
178
+ cursor: not-allowed;
179
+ }
180
+
181
+ .toggleViewButton.selected,
182
+ .fitModeButton.selected {
183
+ background-color: #3c7150;
184
+ border-color: #3c7150;
185
+ }
186
+
187
+ .toggleViewButton.selected svg {
188
+ color: #ffffff;
189
+ }
190
+
191
+ .fitModeButton.selected svg {
192
+ color: #ffffff;
193
+ }
194
+
195
+ .toggleViewButton svg,
196
+ .fitModeButton svg,
197
+ .collapseNodeButton svg,
198
+ .resetViewButton svg {
199
+ width: 16px;
200
+ height: 16px;
201
+ }
202
+
203
+ .divider {
204
+ height: 28px;
205
+ background-color: #e5e5e5;
206
+ }
207
+
208
+ .moreButton {
209
+ height: 28px;
210
+ border: 1px solid #d9d9d9;
211
+ border-radius: 4px;
212
+ background-color: #ffffff;
213
+ }
214
+
215
+ .moreButton:hover {
216
+ border-color: #3c7150;
217
+ color: #3c7150;
218
+ background-color: #e6f4ea;
219
+ }
220
+ }