@kylincloud/flamegraph 0.35.25 → 0.35.27
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/CHANGELOG.md +15 -0
- package/dist/ProfilerTable.d.ts.map +1 -1
- package/dist/Tooltip/FlamegraphTooltip.d.ts.map +1 -1
- package/dist/index.cjs.js +4 -4
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +4 -4
- package/dist/index.esm.js.map +1 -1
- package/dist/index.node.cjs.js +2 -2
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/index.node.esm.js +4 -4
- package/dist/index.node.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/ProfilerTable.tsx +29 -7
- package/src/Tooltip/FlamegraphTooltip.tsx +10 -5
- package/src/sass/flamegraph.scss +27 -6
- package/src/shims/Table.module.scss +30 -1
package/package.json
CHANGED
package/src/ProfilerTable.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/ProfilerTable.tsx
|
|
2
|
-
import React, { useRef, RefObject, useCallback, useState } from 'react';
|
|
2
|
+
import React, { useRef, RefObject, useCallback, useState, useEffect } from 'react';
|
|
3
3
|
import type Color from 'color';
|
|
4
4
|
import cl from 'classnames';
|
|
5
5
|
import type { Maybe } from 'true-myth';
|
|
@@ -329,7 +329,7 @@ const getTableBody = ({
|
|
|
329
329
|
const nameCell = (x: { name: string }) => (
|
|
330
330
|
<button className="table-item-button">
|
|
331
331
|
<div className="symbol-name" style={fitIntoTableCell(fitMode)}>
|
|
332
|
-
{x.name}
|
|
332
|
+
<bdi dir="ltr">{x.name}</bdi>
|
|
333
333
|
</div>
|
|
334
334
|
</button>
|
|
335
335
|
);
|
|
@@ -359,10 +359,13 @@ const getTableBody = ({
|
|
|
359
359
|
const getDoubleRow = (
|
|
360
360
|
x: DoubleCell & { name: string }
|
|
361
361
|
): BodyRow => {
|
|
362
|
-
const leftPercent = ratioToPercent(x.totalLeft / x.leftTicks);
|
|
363
|
-
const rghtPercent = ratioToPercent(x.totalRght / x.rightTicks);
|
|
362
|
+
const leftPercent = ratioToPercent(x.leftTicks > 0 ? x.totalLeft / x.leftTicks : 0);
|
|
363
|
+
const rghtPercent = ratioToPercent(x.rightTicks > 0 ? x.totalRght / x.rightTicks : 0);
|
|
364
364
|
|
|
365
|
-
|
|
365
|
+
let totalDiff = diffPercent(leftPercent, rghtPercent);
|
|
366
|
+
if (!Number.isFinite(totalDiff)) {
|
|
367
|
+
totalDiff = 0;
|
|
368
|
+
}
|
|
366
369
|
|
|
367
370
|
let diffCellColor = '';
|
|
368
371
|
if (totalDiff > 0) {
|
|
@@ -372,12 +375,14 @@ const getTableBody = ({
|
|
|
372
375
|
}
|
|
373
376
|
|
|
374
377
|
let diffValue = '';
|
|
375
|
-
if (
|
|
378
|
+
if (x.totalLeft === 0 && x.totalRght > 0) {
|
|
376
379
|
// this is a new function
|
|
377
380
|
diffValue = messages.diffNew;
|
|
378
|
-
} else if (
|
|
381
|
+
} else if (x.totalRght === 0 && x.totalLeft > 0) {
|
|
379
382
|
// this function has been removed
|
|
380
383
|
diffValue = messages.diffRemoved;
|
|
384
|
+
} else if (totalDiff === 0) {
|
|
385
|
+
diffValue = '0%';
|
|
381
386
|
} else if (totalDiff > 0) {
|
|
382
387
|
diffValue = `+${totalDiff.toFixed(2)}%`;
|
|
383
388
|
} else if (totalDiff < 0) {
|
|
@@ -664,11 +669,28 @@ const ProfilerTable = React.memo(function ProfilerTable({
|
|
|
664
669
|
enableSandwichView,
|
|
665
670
|
}: Omit<ProfilerTableProps, 'tableBodyRef'>) {
|
|
666
671
|
const tableBodyRef = useRef<HTMLTableSectionElement>(null);
|
|
672
|
+
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
673
|
+
const [scrollbarSize, setScrollbarSize] = useState(0);
|
|
667
674
|
const isDoubles = flamebearer.format === 'double';
|
|
668
675
|
|
|
676
|
+
useEffect(() => {
|
|
677
|
+
const bodyEl = tableBodyRef.current;
|
|
678
|
+
if (!bodyEl) return;
|
|
679
|
+
const next = bodyEl.offsetWidth - bodyEl.clientWidth;
|
|
680
|
+
if (Number.isFinite(next) && next !== scrollbarSize) {
|
|
681
|
+
setScrollbarSize(next);
|
|
682
|
+
}
|
|
683
|
+
}, [tableBodyRef.current, isDoubles, scrollbarSize]);
|
|
684
|
+
|
|
669
685
|
return (
|
|
670
686
|
<div
|
|
671
687
|
data-testid="table-view"
|
|
688
|
+
ref={wrapperRef}
|
|
689
|
+
style={
|
|
690
|
+
{
|
|
691
|
+
'--kylin-flamegraph-scrollbar-size': `${scrollbarSize}px`,
|
|
692
|
+
} as React.CSSProperties
|
|
693
|
+
}
|
|
672
694
|
className={
|
|
673
695
|
isDoubles
|
|
674
696
|
? 'flamegraph-table-wrapper flamegraph-table-wrapper--double'
|
|
@@ -214,8 +214,8 @@ export function formatDouble(
|
|
|
214
214
|
};
|
|
215
215
|
};
|
|
216
216
|
} {
|
|
217
|
-
const leftRatio = totalLeft / leftTicks;
|
|
218
|
-
const rightRatio = totalRight / rightTicks;
|
|
217
|
+
const leftRatio = leftTicks > 0 ? totalLeft / leftTicks : 0;
|
|
218
|
+
const rightRatio = rightTicks > 0 ? totalRight / rightTicks : 0;
|
|
219
219
|
|
|
220
220
|
const leftPercent = ratioToPercent(leftRatio);
|
|
221
221
|
const rightPercent = ratioToPercent(rightRatio);
|
|
@@ -236,7 +236,10 @@ export function formatDouble(
|
|
|
236
236
|
tooltipType: 'flamegraph',
|
|
237
237
|
};
|
|
238
238
|
|
|
239
|
-
|
|
239
|
+
let totalDiff = diffPercent(leftPercent, rightPercent);
|
|
240
|
+
if (!Number.isFinite(totalDiff)) {
|
|
241
|
+
totalDiff = 0;
|
|
242
|
+
}
|
|
240
243
|
|
|
241
244
|
let tooltipDiffColor = '';
|
|
242
245
|
if (totalDiff > 0) {
|
|
@@ -249,12 +252,14 @@ export function formatDouble(
|
|
|
249
252
|
// - new / removed 走 i18n,带安全兜底
|
|
250
253
|
// - 百分比 diff 不再带括号,直接 "+12.34%" / "-5.67%"
|
|
251
254
|
let tooltipDiffText = '';
|
|
252
|
-
if (
|
|
255
|
+
if (totalLeft === 0 && totalRight > 0) {
|
|
253
256
|
// 新函数
|
|
254
257
|
tooltipDiffText = i18n?.diffNew ?? '新增';
|
|
255
|
-
} else if (
|
|
258
|
+
} else if (totalRight === 0 && totalLeft > 0) {
|
|
256
259
|
// 被移除的函数
|
|
257
260
|
tooltipDiffText = i18n?.diffRemoved ?? '移除';
|
|
261
|
+
} else if (totalDiff === 0) {
|
|
262
|
+
tooltipDiffText = '0%';
|
|
258
263
|
} else if (totalDiff > 0) {
|
|
259
264
|
tooltipDiffText = `+${totalDiff.toFixed(2)}%`;
|
|
260
265
|
} else if (totalDiff < 0) {
|
package/src/sass/flamegraph.scss
CHANGED
|
@@ -28,14 +28,35 @@ pyro-flamegraph {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/* 只在差分火焰图(double)模式下启用滚动限制 */
|
|
31
|
+
/* 把滚动交给 tbody,表头固定在表格上方 */
|
|
31
32
|
.flamegraph-table-wrapper--double .flamegraph-table-scroll {
|
|
32
|
-
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
position: relative;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.flamegraph-table-wrapper--double .flamegraph-table-scroll table {
|
|
38
|
+
width: 100%;
|
|
39
|
+
table-layout: fixed;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.flamegraph-table-wrapper--double .flamegraph-table-scroll thead {
|
|
43
|
+
display: table;
|
|
44
|
+
width: calc(100% - var(--kylin-flamegraph-scrollbar-size, 0px));
|
|
45
|
+
table-layout: fixed;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.flamegraph-table-wrapper--double .flamegraph-table-scroll tbody {
|
|
49
|
+
display: block;
|
|
33
50
|
max-height: var(--kylin-flamegraph-table-max-height, 1000px);
|
|
34
|
-
overflow-y:
|
|
51
|
+
overflow-y: scroll;
|
|
35
52
|
overflow-x: hidden;
|
|
53
|
+
scrollbar-gutter: stable;
|
|
54
|
+
}
|
|
36
55
|
|
|
37
|
-
|
|
38
|
-
|
|
56
|
+
.flamegraph-table-wrapper--double .flamegraph-table-scroll tbody tr {
|
|
57
|
+
display: table;
|
|
58
|
+
width: 100%;
|
|
59
|
+
table-layout: fixed;
|
|
39
60
|
}
|
|
40
61
|
|
|
41
62
|
/* 表头固定 + 不透明背景,避免内容透出来 */
|
|
@@ -47,12 +68,12 @@ pyro-flamegraph {
|
|
|
47
68
|
|
|
48
69
|
/* 整行都有底色,避免列间缝隙透出内容 */
|
|
49
70
|
.flamegraph-table-wrapper--double .flamegraph-table-scroll thead tr {
|
|
50
|
-
background-color: var(--ps-
|
|
71
|
+
background-color: var(--ps-table-header-bg, var(--ps-ui-foreground, #ffffff));
|
|
51
72
|
}
|
|
52
73
|
|
|
53
74
|
/* 每个单元格再补一层底色,保证完全不透明 */
|
|
54
75
|
.flamegraph-table-wrapper--double .flamegraph-table-scroll thead th {
|
|
55
|
-
background-color: var(--ps-
|
|
76
|
+
background-color: var(--ps-table-header-bg, var(--ps-ui-foreground, #ffffff));
|
|
56
77
|
background-clip: padding-box; // 防止边框区域产生透明感
|
|
57
78
|
}
|
|
58
79
|
|
|
@@ -79,11 +79,40 @@
|
|
|
79
79
|
th {
|
|
80
80
|
border: 1px solid var(--ps-ui-border);
|
|
81
81
|
padding: 4px 10px;
|
|
82
|
-
width: 10%;
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
85
|
|
|
86
|
+
.table:global(.flamegraph-table-doubles) {
|
|
87
|
+
th:first-child,
|
|
88
|
+
td:first-child {
|
|
89
|
+
width: 55%;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
th:nth-child(2),
|
|
93
|
+
td:nth-child(2),
|
|
94
|
+
th:nth-child(3),
|
|
95
|
+
td:nth-child(3),
|
|
96
|
+
th:nth-child(4),
|
|
97
|
+
td:nth-child(4) {
|
|
98
|
+
width: 15%;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.table:global(.flamegraph-table) {
|
|
103
|
+
th:first-child,
|
|
104
|
+
td:first-child {
|
|
105
|
+
width: 55%;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
th:nth-child(2),
|
|
109
|
+
td:nth-child(2),
|
|
110
|
+
th:nth-child(3),
|
|
111
|
+
td:nth-child(3) {
|
|
112
|
+
width: 22.5%;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
87
116
|
.loadingSpinner {
|
|
88
117
|
text-align: center;
|
|
89
118
|
margin-top: 50px;
|