@kylincloud/flamegraph 0.35.27 → 0.35.29
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 +35 -0
- package/dist/FlameGraph/FlameGraphComponent/DiffLegend.d.ts.map +1 -1
- package/dist/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.d.ts.map +1 -1
- package/dist/FlameGraph/FlameGraphComponent/Flamegraph.d.ts +16 -2
- package/dist/FlameGraph/FlameGraphComponent/Flamegraph.d.ts.map +1 -1
- package/dist/FlameGraph/FlameGraphComponent/Flamegraph_render.d.ts +15 -2
- package/dist/FlameGraph/FlameGraphComponent/Flamegraph_render.d.ts.map +1 -1
- package/dist/FlameGraph/FlameGraphComponent/Highlight.d.ts.map +1 -1
- package/dist/FlameGraph/FlameGraphComponent/index.d.ts.map +1 -1
- package/dist/FlameGraph/normalize.d.ts.map +1 -1
- package/dist/FlameGraph/uniqueness.d.ts.map +1 -1
- package/dist/Icons.d.ts.map +1 -1
- package/dist/ProfilerTable.d.ts.map +1 -1
- package/dist/SharedQueryInput.d.ts.map +1 -1
- package/dist/Toolbar.d.ts.map +1 -1
- package/dist/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/flamegraphRenderWorker.js +2 -0
- package/dist/flamegraphRenderWorker.js.map +1 -0
- 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 +4 -4
- 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/dist/shims/Table.d.ts +15 -1
- package/dist/shims/Table.d.ts.map +1 -1
- package/dist/shims/Tooltip.d.ts.map +1 -1
- package/dist/workers/createFlamegraphRenderWorker.d.ts +2 -0
- package/dist/workers/createFlamegraphRenderWorker.d.ts.map +1 -0
- package/dist/workers/flamegraphRenderWorker.d.ts +2 -0
- package/dist/workers/flamegraphRenderWorker.d.ts.map +1 -0
- package/dist/workers/profilerTableWorker.d.ts +73 -0
- package/dist/workers/profilerTableWorker.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/FlameGraph/FlameGraphComponent/DiffLegend.module.css +8 -2
- package/src/FlameGraph/FlameGraphComponent/DiffLegend.tsx +12 -1
- package/src/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.module.css +93 -10
- package/src/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.tsx +9 -4
- package/src/FlameGraph/FlameGraphComponent/Flamegraph.ts +33 -8
- package/src/FlameGraph/FlameGraphComponent/Flamegraph_render.ts +289 -85
- package/src/FlameGraph/FlameGraphComponent/Highlight.tsx +43 -17
- package/src/FlameGraph/FlameGraphComponent/index.tsx +208 -57
- package/src/FlameGraph/FlameGraphComponent/styles.module.scss +8 -0
- package/src/FlameGraph/normalize.ts +9 -7
- package/src/FlameGraph/uniqueness.ts +69 -59
- package/src/Icons.tsx +18 -9
- package/src/ProfilerTable.tsx +463 -33
- package/src/SharedQueryInput.module.scss +50 -0
- package/src/SharedQueryInput.tsx +18 -3
- package/src/Toolbar.module.scss +90 -0
- package/src/Toolbar.tsx +30 -16
- package/src/Tooltip/Tooltip.tsx +49 -16
- package/src/i18n.tsx +1 -1
- package/src/sass/_common.scss +22 -3
- package/src/sass/_css-variables.scss +5 -1
- package/src/sass/flamegraph.scss +26 -23
- package/src/shims/Table.module.scss +91 -13
- package/src/shims/Table.tsx +202 -7
- package/src/shims/Tooltip.module.scss +40 -0
- package/src/shims/Tooltip.tsx +31 -3
- package/src/workers/createFlamegraphRenderWorker.ts +7 -0
- package/src/workers/flamegraphRenderWorker.ts +198 -0
- package/src/workers/profilerTableWorker.ts +368 -0
package/src/Toolbar.module.scss
CHANGED
|
@@ -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
|
+
}
|
package/src/Toolbar.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import React, {
|
|
|
7
7
|
useLayoutEffect,
|
|
8
8
|
isValidElement,
|
|
9
9
|
memo,
|
|
10
|
+
useEffect,
|
|
10
11
|
} from 'react';
|
|
11
12
|
import classNames from 'classnames/bind';
|
|
12
13
|
import { faUndo } from '@fortawesome/free-solid-svg-icons/faUndo';
|
|
@@ -170,8 +171,21 @@ const Toolbar = memo(
|
|
|
170
171
|
setPalette,
|
|
171
172
|
}: ProfileHeaderProps) => {
|
|
172
173
|
const toolbarRef = useRef<HTMLDivElement>(null);
|
|
174
|
+
const [isKylin, setIsKylin] = useState(false);
|
|
173
175
|
const i18n = useFlamegraphI18n();
|
|
174
176
|
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
const el = toolbarRef.current;
|
|
179
|
+
if (!el) return;
|
|
180
|
+
const kylinEl = el.closest(
|
|
181
|
+
"[data-theme='kylin'], [data-flamegraph-color-mode='kylin']"
|
|
182
|
+
);
|
|
183
|
+
setIsKylin(!!kylinEl);
|
|
184
|
+
}, []);
|
|
185
|
+
|
|
186
|
+
const toolbarSquareWidth = isKylin ? 32 : TOOLBAR_SQUARE_WIDTH;
|
|
187
|
+
const queryInputWidth = isKylin ? 220 : QUERY_INPUT_WIDTH;
|
|
188
|
+
|
|
175
189
|
// 是否显示调色板选择器(仅在 diff 模式且有 palette 时显示)
|
|
176
190
|
const showPaletteDropdown = flamegraphType === 'double' && palette && setPalette;
|
|
177
191
|
|
|
@@ -182,11 +196,11 @@ const Toolbar = memo(
|
|
|
182
196
|
<Divider />
|
|
183
197
|
</>
|
|
184
198
|
),
|
|
185
|
-
width:
|
|
199
|
+
width: toolbarSquareWidth * 2 + DIVIDER_WIDTH,
|
|
186
200
|
};
|
|
187
201
|
const resetItem = {
|
|
188
202
|
el: <ResetView isFlamegraphDirty={isFlamegraphDirty} reset={reset} />,
|
|
189
|
-
width:
|
|
203
|
+
width: toolbarSquareWidth,
|
|
190
204
|
};
|
|
191
205
|
const focusOnSubtree = {
|
|
192
206
|
el: (
|
|
@@ -198,7 +212,7 @@ const Toolbar = memo(
|
|
|
198
212
|
<Divider />
|
|
199
213
|
</>
|
|
200
214
|
),
|
|
201
|
-
width:
|
|
215
|
+
width: toolbarSquareWidth + DIVIDER_WIDTH,
|
|
202
216
|
};
|
|
203
217
|
|
|
204
218
|
const viewSectionItem = enableChangingDisplay
|
|
@@ -210,7 +224,7 @@ const Toolbar = memo(
|
|
|
210
224
|
updateView={updateView}
|
|
211
225
|
/>
|
|
212
226
|
),
|
|
213
|
-
width:
|
|
227
|
+
width: toolbarSquareWidth * (flamegraphType === 'single' ? 5 : 3),
|
|
214
228
|
}
|
|
215
229
|
: null;
|
|
216
230
|
const exportDataItem = isValidElement(ExportData)
|
|
@@ -221,7 +235,7 @@ const Toolbar = memo(
|
|
|
221
235
|
{ExportData}
|
|
222
236
|
</>
|
|
223
237
|
),
|
|
224
|
-
width:
|
|
238
|
+
width: toolbarSquareWidth + DIVIDER_WIDTH,
|
|
225
239
|
}
|
|
226
240
|
: null;
|
|
227
241
|
|
|
@@ -261,7 +275,7 @@ const Toolbar = memo(
|
|
|
261
275
|
{/* 左侧:搜索框 */}
|
|
262
276
|
<div className={styles.searchWrapper}>
|
|
263
277
|
<SharedQueryInput
|
|
264
|
-
width={
|
|
278
|
+
width={queryInputWidth}
|
|
265
279
|
onHighlightChange={handleSearchChange}
|
|
266
280
|
highlightQuery={highlightQuery}
|
|
267
281
|
sharedQuery={sharedQuery}
|
|
@@ -430,17 +444,17 @@ const getViewOptions = (
|
|
|
430
444
|
}> =>
|
|
431
445
|
flamegraphType === 'single'
|
|
432
446
|
? [
|
|
447
|
+
{
|
|
448
|
+
label: messages.viewFlamegraph,
|
|
449
|
+
value: 'flamegraph',
|
|
450
|
+
Icon: FlamegraphIcon,
|
|
451
|
+
},
|
|
433
452
|
{ label: messages.viewTable, value: 'table', Icon: TableIcon },
|
|
434
453
|
{
|
|
435
454
|
label: messages.viewTableAndFlamegraph,
|
|
436
455
|
value: 'both',
|
|
437
456
|
Icon: TablePlusFlamegraphIcon,
|
|
438
457
|
},
|
|
439
|
-
{
|
|
440
|
-
label: messages.viewFlamegraph,
|
|
441
|
-
value: 'flamegraph',
|
|
442
|
-
Icon: FlamegraphIcon,
|
|
443
|
-
},
|
|
444
458
|
{ label: messages.viewSandwich, value: 'sandwich', Icon: SandwichIcon },
|
|
445
459
|
{
|
|
446
460
|
label: messages.viewGraphviz,
|
|
@@ -449,17 +463,17 @@ const getViewOptions = (
|
|
|
449
463
|
},
|
|
450
464
|
]
|
|
451
465
|
: [
|
|
466
|
+
{
|
|
467
|
+
label: messages.viewFlamegraph,
|
|
468
|
+
value: 'flamegraph',
|
|
469
|
+
Icon: FlamegraphIcon,
|
|
470
|
+
},
|
|
452
471
|
{ label: messages.viewTable, value: 'table', Icon: TableIcon },
|
|
453
472
|
{
|
|
454
473
|
label: messages.viewTableAndFlamegraph,
|
|
455
474
|
value: 'both',
|
|
456
475
|
Icon: TablePlusFlamegraphIcon,
|
|
457
476
|
},
|
|
458
|
-
{
|
|
459
|
-
label: messages.viewFlamegraph,
|
|
460
|
-
value: 'flamegraph',
|
|
461
|
-
Icon: FlamegraphIcon,
|
|
462
|
-
},
|
|
463
477
|
];
|
|
464
478
|
|
|
465
479
|
function ViewSection({
|
package/src/Tooltip/Tooltip.tsx
CHANGED
|
@@ -193,6 +193,8 @@ export function Tooltip({
|
|
|
193
193
|
}: TooltipProps) {
|
|
194
194
|
const tooltipRef = useRef<HTMLDivElement>(null);
|
|
195
195
|
const lastPosRef = useRef<{ x: number; y: number } | null>(null);
|
|
196
|
+
const rafRef = useRef<number | null>(null);
|
|
197
|
+
const lastMeasureRef = useRef<{ w: number; h: number } | null>(null);
|
|
196
198
|
|
|
197
199
|
const [content, setContent] = React.useState({
|
|
198
200
|
title: {
|
|
@@ -216,22 +218,29 @@ export function Tooltip({
|
|
|
216
218
|
|
|
217
219
|
const memoizedOnMouseMove = useCallback(
|
|
218
220
|
(e: MouseEvent) => {
|
|
219
|
-
if (
|
|
220
|
-
|
|
221
|
+
if (rafRef.current) {
|
|
222
|
+
cancelAnimationFrame(rafRef.current);
|
|
221
223
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
224
|
+
const x = e.clientX;
|
|
225
|
+
const y = e.clientY;
|
|
226
|
+
rafRef.current = requestAnimationFrame(() => {
|
|
227
|
+
if (!tooltipRef.current) {
|
|
228
|
+
throw new Error('Missing tooltipElement');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// 记录最后鼠标位置(给 useLayoutEffect 二次校正用)
|
|
232
|
+
lastPosRef.current = { x, y };
|
|
233
|
+
|
|
234
|
+
// 先更新内容(tooltip 高度可能因此变化)
|
|
235
|
+
setTooltipContent(setContent, onMouseOut, e);
|
|
236
|
+
|
|
237
|
+
// 用当前已渲染的尺寸先算一次位置(内容变化后的真实尺寸会在 useLayoutEffect 再校正)
|
|
238
|
+
const w = tooltipRef.current.clientWidth || 0;
|
|
239
|
+
const h = tooltipRef.current.clientHeight || 0;
|
|
240
|
+
|
|
241
|
+
const { left, top } = computeSafeTooltipPos(x, y, w, h);
|
|
242
|
+
setStyle({ top, left, visibility: 'visible' });
|
|
243
|
+
});
|
|
235
244
|
},
|
|
236
245
|
[setTooltipContent]
|
|
237
246
|
);
|
|
@@ -241,12 +250,23 @@ export function Tooltip({
|
|
|
241
250
|
if (!dataSourceEl) {
|
|
242
251
|
return () => { };
|
|
243
252
|
}
|
|
253
|
+
const onMouseLeave = () => {
|
|
254
|
+
onMouseOut();
|
|
255
|
+
};
|
|
256
|
+
const onWindowMove = (e: MouseEvent) => {
|
|
257
|
+
if (!dataSourceEl.contains(e.target as Node)) {
|
|
258
|
+
onMouseOut();
|
|
259
|
+
}
|
|
260
|
+
};
|
|
244
261
|
|
|
245
262
|
dataSourceEl.addEventListener(
|
|
246
263
|
'mousemove',
|
|
247
264
|
memoizedOnMouseMove as EventListener
|
|
248
265
|
);
|
|
249
266
|
dataSourceEl.addEventListener('mouseout', onMouseOut);
|
|
267
|
+
dataSourceEl.addEventListener('mouseleave', onMouseLeave);
|
|
268
|
+
window.addEventListener('mousemove', onWindowMove, { passive: true });
|
|
269
|
+
window.addEventListener('blur', onMouseLeave);
|
|
250
270
|
|
|
251
271
|
return () => {
|
|
252
272
|
dataSourceEl.removeEventListener(
|
|
@@ -254,6 +274,12 @@ export function Tooltip({
|
|
|
254
274
|
memoizedOnMouseMove as EventListener
|
|
255
275
|
);
|
|
256
276
|
dataSourceEl.removeEventListener('mouseout', onMouseOut);
|
|
277
|
+
dataSourceEl.removeEventListener('mouseleave', onMouseLeave);
|
|
278
|
+
window.removeEventListener('mousemove', onWindowMove as EventListener);
|
|
279
|
+
window.removeEventListener('blur', onMouseLeave);
|
|
280
|
+
if (rafRef.current) {
|
|
281
|
+
cancelAnimationFrame(rafRef.current);
|
|
282
|
+
}
|
|
257
283
|
};
|
|
258
284
|
}, [dataSourceRef.current, memoizedOnMouseMove]);
|
|
259
285
|
|
|
@@ -265,7 +291,14 @@ export function Tooltip({
|
|
|
265
291
|
|
|
266
292
|
const { x, y } = lastPosRef.current;
|
|
267
293
|
const rect = tooltipRef.current.getBoundingClientRect();
|
|
268
|
-
const
|
|
294
|
+
const w = rect.width;
|
|
295
|
+
const h = rect.height;
|
|
296
|
+
const last = lastMeasureRef.current;
|
|
297
|
+
if (last && Math.abs(last.w - w) < 1 && Math.abs(last.h - h) < 1) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
lastMeasureRef.current = { w, h };
|
|
301
|
+
const { left, top } = computeSafeTooltipPos(x, y, w, h);
|
|
269
302
|
|
|
270
303
|
setStyle((prev) => {
|
|
271
304
|
if (prev && prev.left === left && prev.top === top && prev.visibility === 'visible') {
|
package/src/i18n.tsx
CHANGED
|
@@ -296,7 +296,7 @@ export const zhCNMessages: FlamegraphMessages = {
|
|
|
296
296
|
diffLegendAddedLabel: '增加 (+)',
|
|
297
297
|
diffLegendSelectPalette: '选择颜色方案',
|
|
298
298
|
paletteDefaultName: '默认',
|
|
299
|
-
paletteColorBlindName: '
|
|
299
|
+
paletteColorBlindName: '色盲',
|
|
300
300
|
// 调色板补充描述(中文)
|
|
301
301
|
paletteDefaultDesc: '(绿色 → 红色)',
|
|
302
302
|
paletteColorBlindDesc: '(蓝色 → 红色)',
|
package/src/sass/_common.scss
CHANGED
|
@@ -131,9 +131,8 @@ tt {
|
|
|
131
131
|
padding: 6px 10px;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
background: var(--ps-neutral-9);
|
|
134
|
+
thead th {
|
|
135
|
+
background: var(--ps-table-header-bg, var(--ps-ui-foreground, #ffffff));
|
|
137
136
|
}
|
|
138
137
|
|
|
139
138
|
td {
|
|
@@ -182,3 +181,23 @@ tt {
|
|
|
182
181
|
}
|
|
183
182
|
}
|
|
184
183
|
}
|
|
184
|
+
|
|
185
|
+
// Kylin theme table density tweaks to match Insights UI
|
|
186
|
+
:global([data-theme='kylin']) {
|
|
187
|
+
.flamegraph-table {
|
|
188
|
+
font-size: 12px;
|
|
189
|
+
border-color: #d9d9d9;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.flamegraph-table th {
|
|
193
|
+
padding: 6px 8px;
|
|
194
|
+
border-left-color: #d9d9d9;
|
|
195
|
+
border-bottom-color: #d9d9d9;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.flamegraph-table td {
|
|
199
|
+
padding: 4px 8px;
|
|
200
|
+
border-left-color: #f0f0f0;
|
|
201
|
+
border-bottom-color: #f0f0f0;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
@@ -57,6 +57,8 @@
|
|
|
57
57
|
// 表头(使用实心背景,避免 sticky 时透出内容)
|
|
58
58
|
--ps-table-header-bg: #212124;
|
|
59
59
|
--ps-table-header-text: #d8d8d8;
|
|
60
|
+
--ps-table-sort-icon: #9a9aa0;
|
|
61
|
+
--ps-table-sort-icon-active: var(--ps-button-switch-bg-highlight);
|
|
60
62
|
|
|
61
63
|
// 选择器
|
|
62
64
|
--ps-selected-app: #df8b53;
|
|
@@ -209,6 +211,8 @@
|
|
|
209
211
|
--ps-tooltip-header-bg: #f0f0f0;
|
|
210
212
|
|
|
211
213
|
// 表头专用:完全不透明的白色
|
|
212
|
-
--ps-table-header-bg: #
|
|
214
|
+
--ps-table-header-bg: #fafafa;
|
|
213
215
|
--ps-table-header-text: #000000;
|
|
216
|
+
--ps-table-sort-icon: #bfbfbf;
|
|
217
|
+
--ps-table-sort-icon-active: #5d976f;
|
|
214
218
|
}
|
package/src/sass/flamegraph.scss
CHANGED
|
@@ -29,43 +29,41 @@ pyro-flamegraph {
|
|
|
29
29
|
|
|
30
30
|
/* 只在差分火焰图(double)模式下启用滚动限制 */
|
|
31
31
|
/* 把滚动交给 tbody,表头固定在表格上方 */
|
|
32
|
-
.flamegraph-table-wrapper--double
|
|
32
|
+
.flamegraph-table-wrapper--double {
|
|
33
|
+
border: 1px solid var(--ps-ui-border);
|
|
34
|
+
border-radius: 6px;
|
|
33
35
|
overflow: hidden;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.flamegraph-table-wrapper--double .flamegraph-table-scroll table {
|
|
38
|
-
width: 100%;
|
|
39
|
-
table-layout: fixed;
|
|
36
|
+
background-color: var(--ps-ui-foreground, #fff);
|
|
37
|
+
min-height: var(--kylin-flamegraph-pane-min-height, 320px);
|
|
40
38
|
}
|
|
41
39
|
|
|
42
|
-
.flamegraph-table-wrapper--double .flamegraph-table
|
|
43
|
-
|
|
44
|
-
width: calc(100% - var(--kylin-flamegraph-scrollbar-size, 0px));
|
|
45
|
-
table-layout: fixed;
|
|
40
|
+
.flamegraph-table-wrapper--double .flamegraph-table {
|
|
41
|
+
border: none;
|
|
46
42
|
}
|
|
47
43
|
|
|
48
|
-
.flamegraph-table-wrapper--double .flamegraph-table-scroll
|
|
49
|
-
display: block;
|
|
50
|
-
max-height: var(--kylin-flamegraph-table-max-height, 1000px);
|
|
51
|
-
overflow-y: scroll;
|
|
44
|
+
.flamegraph-table-wrapper--double .flamegraph-table-scroll {
|
|
52
45
|
overflow-x: hidden;
|
|
53
|
-
|
|
46
|
+
overflow-y: auto;
|
|
47
|
+
position: relative;
|
|
48
|
+
max-height: var(--kylin-flamegraph-table-max-height, 1000px);
|
|
54
49
|
}
|
|
55
50
|
|
|
56
|
-
.flamegraph-table-wrapper--double .flamegraph-table-scroll
|
|
57
|
-
display: table;
|
|
51
|
+
.flamegraph-table-wrapper--double .flamegraph-table-scroll table {
|
|
58
52
|
width: 100%;
|
|
59
53
|
table-layout: fixed;
|
|
60
54
|
}
|
|
61
55
|
|
|
62
|
-
/* 表头固定 + 不透明背景,避免内容透出来 */
|
|
63
56
|
.flamegraph-table-wrapper--double .flamegraph-table-scroll thead {
|
|
57
|
+
display: table-header-group;
|
|
64
58
|
position: sticky;
|
|
65
59
|
top: 0;
|
|
66
60
|
z-index: 3; // 比下面的行和 tooltip 都高一点
|
|
67
61
|
}
|
|
68
62
|
|
|
63
|
+
.flamegraph-table-wrapper--double .flamegraph-table-scroll tbody {
|
|
64
|
+
display: table-row-group;
|
|
65
|
+
}
|
|
66
|
+
|
|
69
67
|
/* 整行都有底色,避免列间缝隙透出内容 */
|
|
70
68
|
.flamegraph-table-wrapper--double .flamegraph-table-scroll thead tr {
|
|
71
69
|
background-color: var(--ps-table-header-bg, var(--ps-ui-foreground, #ffffff));
|
|
@@ -85,14 +83,19 @@ pyro-flamegraph {
|
|
|
85
83
|
|
|
86
84
|
/* 可选:稍微美化一下内部滚动条,轨道透明,避免太抢眼 */
|
|
87
85
|
.flamegraph-table-wrapper--double .flamegraph-table-scroll::-webkit-scrollbar {
|
|
88
|
-
width:
|
|
86
|
+
width: 6px;
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
.flamegraph-table-wrapper--double .flamegraph-table-scroll::-webkit-scrollbar-track {
|
|
92
|
-
background:
|
|
90
|
+
background: #f5f5f5;
|
|
91
|
+
border-radius: 6px;
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
.flamegraph-table-wrapper--double .flamegraph-table-scroll::-webkit-scrollbar-thumb {
|
|
96
|
-
background-color:
|
|
97
|
-
border-radius:
|
|
95
|
+
background-color: #bfbfbf;
|
|
96
|
+
border-radius: 6px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.flamegraph-table-wrapper--double .flamegraph-table-scroll::-webkit-scrollbar-thumb:hover {
|
|
100
|
+
background-color: #8c8c8c;
|
|
98
101
|
}
|
|
@@ -21,23 +21,23 @@
|
|
|
21
21
|
top: 3px;
|
|
22
22
|
position: relative;
|
|
23
23
|
margin-left: 7px;
|
|
24
|
+
}
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
26
|
+
.sortArrowUp,
|
|
27
|
+
.sortArrowDown {
|
|
28
|
+
display: none;
|
|
29
|
+
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
.sortArrow.asc {
|
|
32
|
+
border-top-color: transparent;
|
|
33
|
+
border-bottom-color: var(--ps-button-switch-bg-highlight);
|
|
34
|
+
top: -2px;
|
|
35
35
|
}
|
|
36
|
-
}
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
.sortArrow.desc {
|
|
38
|
+
border-top-color: var(--ps-button-switch-bg-highlight);
|
|
39
|
+
top: 3px;
|
|
40
|
+
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
tbody {
|
|
@@ -73,6 +73,11 @@
|
|
|
73
73
|
background: var(--ps-ui-element-bg-highlight);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
+
|
|
77
|
+
&.virtualSpacer {
|
|
78
|
+
pointer-events: none;
|
|
79
|
+
background: transparent !important;
|
|
80
|
+
}
|
|
76
81
|
}
|
|
77
82
|
|
|
78
83
|
td,
|
|
@@ -83,6 +88,79 @@
|
|
|
83
88
|
}
|
|
84
89
|
}
|
|
85
90
|
|
|
91
|
+
:global([data-theme='kylin']) {
|
|
92
|
+
.table {
|
|
93
|
+
thead th {
|
|
94
|
+
text-align: left;
|
|
95
|
+
background: #fafafa;
|
|
96
|
+
border-color: #d9d9d9;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
tbody td {
|
|
100
|
+
border-color: #f0f0f0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
tbody tr:not(.isRowSelected):hover {
|
|
104
|
+
background: #f5f5f5;
|
|
105
|
+
color: var(--ps-neutral-2);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
thead th {
|
|
109
|
+
&.sortable {
|
|
110
|
+
position: relative;
|
|
111
|
+
padding-right: 18px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.sortArrow {
|
|
115
|
+
display: inline-flex;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
margin-left: 6px;
|
|
118
|
+
line-height: 1;
|
|
119
|
+
border: 0;
|
|
120
|
+
position: absolute;
|
|
121
|
+
right: 6px;
|
|
122
|
+
top: 50%;
|
|
123
|
+
transform: translateY(-50%);
|
|
124
|
+
vertical-align: middle;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.sortArrowUp,
|
|
128
|
+
.sortArrowDown {
|
|
129
|
+
display: inline-block;
|
|
130
|
+
width: 0;
|
|
131
|
+
height: 0;
|
|
132
|
+
border-left: 4px solid transparent;
|
|
133
|
+
border-right: 4px solid transparent;
|
|
134
|
+
opacity: 0.35;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.sortArrowUp {
|
|
138
|
+
border-bottom: 5px solid var(--ps-table-sort-icon, var(--ps-ui-foreground-text));
|
|
139
|
+
margin-bottom: 2px;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.sortArrowDown {
|
|
143
|
+
border-top: 5px solid var(--ps-table-sort-icon, var(--ps-ui-foreground-text));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.sortArrow.active .sortArrowUp,
|
|
147
|
+
.sortArrow.active .sortArrowDown {
|
|
148
|
+
opacity: 0.45;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.sortArrow.asc .sortArrowUp {
|
|
152
|
+
border-bottom-color: var(--ps-table-sort-icon-active, var(--ps-button-switch-bg-highlight));
|
|
153
|
+
opacity: 1;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.sortArrow.desc .sortArrowDown {
|
|
157
|
+
border-top-color: var(--ps-table-sort-icon-active, var(--ps-button-switch-bg-highlight));
|
|
158
|
+
opacity: 1;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
86
164
|
.table:global(.flamegraph-table-doubles) {
|
|
87
165
|
th:first-child,
|
|
88
166
|
td:first-child {
|