@parca/profile 0.16.444 → 0.16.445
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 +4 -0
- package/dist/ProfileIcicleGraph/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/index.js +3 -11
- package/dist/ProfileView/ColorStackLegend.d.ts.map +1 -0
- package/dist/{ProfileIcicleGraph/IcicleGraphArrow → ProfileView}/ColorStackLegend.js +2 -2
- package/dist/ProfileView/VisualizationPanel.d.ts +4 -1
- package/dist/ProfileView/VisualizationPanel.d.ts.map +1 -1
- package/dist/ProfileView/VisualizationPanel.js +4 -6
- package/dist/ProfileView/index.d.ts.map +1 -1
- package/dist/ProfileView/index.js +33 -10
- package/dist/ProfileViewWithData.d.ts.map +1 -1
- package/dist/ProfileViewWithData.js +1 -3
- package/dist/Table/index.d.ts +2 -29
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +52 -159
- package/dist/Table/utils/functions.d.ts +49 -0
- package/dist/Table/utils/functions.d.ts.map +1 -0
- package/dist/Table/utils/functions.js +181 -0
- package/dist/components/ActionButtons/GroupByDropdown.js +1 -1
- package/dist/components/ActionButtons/SortByDropdown.d.ts +3 -0
- package/dist/components/ActionButtons/SortByDropdown.d.ts.map +1 -0
- package/dist/components/ActionButtons/SortByDropdown.js +49 -0
- package/dist/components/VisualisationToolbar/MultiLevelDropdown.d.ts.map +1 -1
- package/dist/components/VisualisationToolbar/MultiLevelDropdown.js +3 -27
- package/dist/components/VisualisationToolbar/TableColumnsDropdown.d.ts.map +1 -1
- package/dist/components/VisualisationToolbar/TableColumnsDropdown.js +3 -1
- package/dist/components/VisualisationToolbar/index.d.ts +11 -0
- package/dist/components/VisualisationToolbar/index.d.ts.map +1 -1
- package/dist/components/VisualisationToolbar/index.js +13 -6
- package/dist/styles.css +1 -1
- package/package.json +2 -2
- package/src/ProfileIcicleGraph/index.tsx +2 -18
- package/src/{ProfileIcicleGraph/IcicleGraphArrow → ProfileView}/ColorStackLegend.tsx +2 -2
- package/src/ProfileView/VisualizationPanel.tsx +13 -10
- package/src/ProfileView/index.tsx +59 -9
- package/src/ProfileViewWithData.tsx +1 -3
- package/src/Table/index.tsx +121 -263
- package/src/Table/utils/functions.ts +284 -0
- package/src/components/ActionButtons/GroupByDropdown.tsx +1 -1
- package/src/components/ActionButtons/SortByDropdown.tsx +84 -0
- package/src/components/VisualisationToolbar/MultiLevelDropdown.tsx +7 -30
- package/src/components/VisualisationToolbar/TableColumnsDropdown.tsx +3 -1
- package/src/components/VisualisationToolbar/index.tsx +103 -58
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.d.ts.map +0 -1
- /package/dist/{ProfileIcicleGraph/IcicleGraphArrow → ProfileView}/ColorStackLegend.d.ts +0 -0
package/src/Table/index.tsx
CHANGED
|
@@ -32,11 +32,36 @@ import {
|
|
|
32
32
|
useURLState,
|
|
33
33
|
} from '@parca/components';
|
|
34
34
|
import {type RowRendererProps} from '@parca/components/dist/Table';
|
|
35
|
+
import {useCurrentColorProfile} from '@parca/hooks';
|
|
35
36
|
import {ProfileType} from '@parca/parser';
|
|
36
|
-
import {
|
|
37
|
+
import {isSearchMatch, valueFormatter} from '@parca/utilities';
|
|
37
38
|
|
|
39
|
+
import {getFilenameColors, getMappingColors} from '../ProfileIcicleGraph/IcicleGraphArrow/';
|
|
40
|
+
import {colorByColors} from '../ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes';
|
|
41
|
+
import useMappingList, {
|
|
42
|
+
useFilenamesList,
|
|
43
|
+
} from '../ProfileIcicleGraph/IcicleGraphArrow/useMappingList';
|
|
38
44
|
import {useProfileViewContext} from '../ProfileView/ProfileViewContext';
|
|
39
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
ColumnName,
|
|
47
|
+
DataRow,
|
|
48
|
+
DummyRow,
|
|
49
|
+
ROW_HEIGHT,
|
|
50
|
+
RowName,
|
|
51
|
+
addPlusSign,
|
|
52
|
+
getCalleeRows,
|
|
53
|
+
getCallerRows,
|
|
54
|
+
getRowColor,
|
|
55
|
+
getScrollTargetIndex,
|
|
56
|
+
isFirstSubRow,
|
|
57
|
+
isLastSubRow,
|
|
58
|
+
isSubRow,
|
|
59
|
+
ratioString,
|
|
60
|
+
rowBgClassNames,
|
|
61
|
+
sizeToBottomStyle,
|
|
62
|
+
sizeToHeightStyle,
|
|
63
|
+
sizeToWidthStyle,
|
|
64
|
+
} from './utils/functions';
|
|
40
65
|
import {getTopAndBottomExpandedRowModel} from './utils/topAndBottomExpandedRowModel';
|
|
41
66
|
|
|
42
67
|
const FIELD_MAPPING_FILE = 'mapping_file';
|
|
@@ -51,30 +76,6 @@ const FIELD_CUMULATIVE_DIFF = 'cumulative_diff';
|
|
|
51
76
|
const FIELD_CALLERS = 'callers';
|
|
52
77
|
const FIELD_CALLEES = 'callees';
|
|
53
78
|
|
|
54
|
-
export interface DataRow {
|
|
55
|
-
id: number;
|
|
56
|
-
name: string;
|
|
57
|
-
flat: bigint;
|
|
58
|
-
flatDiff: bigint;
|
|
59
|
-
cumulative: bigint;
|
|
60
|
-
cumulativeDiff: bigint;
|
|
61
|
-
mappingFile: string;
|
|
62
|
-
functionSystemName: string;
|
|
63
|
-
functionFileName: string;
|
|
64
|
-
callers?: DataRow[];
|
|
65
|
-
callees?: DataRow[];
|
|
66
|
-
subRows?: Row[];
|
|
67
|
-
isTopSubRow?: boolean;
|
|
68
|
-
isBottomSubRow?: boolean;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface DummyRow {
|
|
72
|
-
size: number;
|
|
73
|
-
message?: string;
|
|
74
|
-
isTopSubRow?: boolean;
|
|
75
|
-
isBottomSubRow?: boolean;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
79
|
export type Row = DataRow | DummyRow;
|
|
79
80
|
|
|
80
81
|
export const isDummyRow = (row: Row): row is DummyRow => {
|
|
@@ -94,50 +95,9 @@ interface TableProps {
|
|
|
94
95
|
setActionButtons?: (buttons: React.JSX.Element) => void;
|
|
95
96
|
isHalfScreen: boolean;
|
|
96
97
|
unit?: string;
|
|
98
|
+
metadataMappingFiles?: string[];
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
export type ColumnName =
|
|
100
|
-
| 'flat'
|
|
101
|
-
| 'flatPercentage'
|
|
102
|
-
| 'flatDiff'
|
|
103
|
-
| 'flatDiffPercentage'
|
|
104
|
-
| 'cumulative'
|
|
105
|
-
| 'cumulativePercentage'
|
|
106
|
-
| 'cumulativeDiff'
|
|
107
|
-
| 'cumulativeDiffPercentage'
|
|
108
|
-
| 'name'
|
|
109
|
-
| 'functionSystemName'
|
|
110
|
-
| 'functionFileName'
|
|
111
|
-
| 'mappingFile';
|
|
112
|
-
|
|
113
|
-
const rowBgClassNames = (isExpanded: boolean, isSubRow: boolean): Record<string, boolean> => {
|
|
114
|
-
return {
|
|
115
|
-
relative: true,
|
|
116
|
-
'bg-indigo-100 dark:bg-gray-600': isSubRow,
|
|
117
|
-
'bg-indigo-50 dark:bg-gray-700': isExpanded,
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
const ROW_HEIGHT = 29;
|
|
122
|
-
|
|
123
|
-
const sizeToHeightStyle = (size: number): Record<string, string> => {
|
|
124
|
-
return {
|
|
125
|
-
height: `${size * ROW_HEIGHT}px`,
|
|
126
|
-
};
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const sizeToWidthStyle = (size: number): Record<string, string> => {
|
|
130
|
-
return {
|
|
131
|
-
width: `${size * ROW_HEIGHT}px`,
|
|
132
|
-
};
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const sizeToBottomStyle = (size: number): Record<string, string> => {
|
|
136
|
-
return {
|
|
137
|
-
bottom: `-${size * ROW_HEIGHT}px`,
|
|
138
|
-
};
|
|
139
|
-
};
|
|
140
|
-
|
|
141
101
|
const CustomRowRenderer = ({
|
|
142
102
|
row,
|
|
143
103
|
usePointerCursor,
|
|
@@ -266,68 +226,6 @@ const CustomRowRenderer = ({
|
|
|
266
226
|
);
|
|
267
227
|
};
|
|
268
228
|
|
|
269
|
-
const getCallerRows = (callers: DataRow[]): Row[] => {
|
|
270
|
-
if (callers.length === 0) {
|
|
271
|
-
return [{size: 3, message: 'No callers.', isTopSubRow: true}];
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const rows = callers.map(row => {
|
|
275
|
-
return {...row, isTopSubRow: true};
|
|
276
|
-
});
|
|
277
|
-
if (rows.length >= 3) {
|
|
278
|
-
return rows;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return [...rows, {size: 3 - rows.length, message: '', isTopSubRow: true}];
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
const getCalleeRows = (callees: DataRow[]): Row[] => {
|
|
285
|
-
if (callees.length === 0) {
|
|
286
|
-
return [{size: 3, message: 'No callees.', isBottomSubRow: true}];
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
const rows = callees.map(row => {
|
|
290
|
-
return {...row, isBottomSubRow: true};
|
|
291
|
-
});
|
|
292
|
-
if (rows.length >= 3) {
|
|
293
|
-
return rows;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
return [{size: 3 - rows.length, message: '', isBottomSubRow: true}, ...rows];
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
export const getPercentageString = (value: bigint | number, total: bigint | number): string => {
|
|
300
|
-
if (total === 0n) {
|
|
301
|
-
return '0%';
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const percentage = (Number(value) / Number(total)) * 100;
|
|
305
|
-
return `${percentage.toFixed(2)}%`;
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
export const getRatioString = (value: bigint | number, total: bigint, filtered: bigint): string => {
|
|
309
|
-
if (filtered === 0n) {
|
|
310
|
-
return ` ${getPercentageString(value, total)}`;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
return `${getPercentageString(value, total)} / ${getPercentageString(value, filtered)}`;
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
export const possibleColumns = [
|
|
317
|
-
'flat',
|
|
318
|
-
'flatPercentage',
|
|
319
|
-
'flatDiff',
|
|
320
|
-
'flatDiffPercentage',
|
|
321
|
-
'cumulative',
|
|
322
|
-
'cumulativePercentage',
|
|
323
|
-
'cumulativeDiff',
|
|
324
|
-
'cumulativeDiffPercentage',
|
|
325
|
-
'name',
|
|
326
|
-
'functionSystemName',
|
|
327
|
-
'functionFileName',
|
|
328
|
-
'mappingFile',
|
|
329
|
-
];
|
|
330
|
-
|
|
331
229
|
export const Table = React.memo(function Table({
|
|
332
230
|
data,
|
|
333
231
|
total,
|
|
@@ -338,43 +236,81 @@ export const Table = React.memo(function Table({
|
|
|
338
236
|
setSearchString = () => {},
|
|
339
237
|
isHalfScreen,
|
|
340
238
|
unit,
|
|
239
|
+
metadataMappingFiles,
|
|
341
240
|
}: TableProps): React.JSX.Element {
|
|
241
|
+
const currentColorProfile = useCurrentColorProfile();
|
|
342
242
|
const [dashboardItems] = useURLState<string[]>('dashboard_items', {
|
|
343
243
|
alwaysReturnArray: true,
|
|
344
244
|
});
|
|
345
245
|
const [tableColumns] = useURLState<string[]>('table_columns', {
|
|
346
246
|
alwaysReturnArray: true,
|
|
347
247
|
});
|
|
348
|
-
|
|
248
|
+
const [colorBy, setColorBy] = useURLState('color_by');
|
|
349
249
|
const {isDarkMode} = useParcaContext();
|
|
350
250
|
const [expanded, setExpanded] = useState<ExpandedState>({});
|
|
351
251
|
const [scrollToIndex, setScrollToIndex] = useState<number | undefined>(undefined);
|
|
352
252
|
|
|
353
253
|
const {compareMode} = useProfileViewContext();
|
|
354
254
|
|
|
355
|
-
const
|
|
356
|
-
if (
|
|
357
|
-
return
|
|
255
|
+
const table = useMemo(() => {
|
|
256
|
+
if (loading || data == null) {
|
|
257
|
+
return null;
|
|
358
258
|
}
|
|
359
259
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
260
|
+
return tableFromIPC(data);
|
|
261
|
+
}, [data, loading]);
|
|
262
|
+
|
|
263
|
+
const mappingsList = useMappingList(metadataMappingFiles);
|
|
264
|
+
const filenamesList = useFilenamesList(table);
|
|
265
|
+
const colorByValue = colorBy === undefined || colorBy === '' ? 'binary' : (colorBy as string);
|
|
266
|
+
|
|
267
|
+
const mappingsListCount = useMemo(
|
|
268
|
+
() => mappingsList.filter(m => m !== '').length,
|
|
269
|
+
[mappingsList]
|
|
270
|
+
);
|
|
363
271
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
272
|
+
// If there is only one mapping file, we want to color by filename by default.
|
|
273
|
+
useEffect(() => {
|
|
274
|
+
if (mappingsListCount === 1 && colorBy !== 'filename') {
|
|
275
|
+
setColorBy('filename');
|
|
367
276
|
}
|
|
277
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
278
|
+
}, [mappingsListCount]);
|
|
279
|
+
|
|
280
|
+
const filenameColors = useMemo(() => {
|
|
281
|
+
const colors = getFilenameColors(filenamesList, isDarkMode, currentColorProfile);
|
|
282
|
+
return colors;
|
|
283
|
+
}, [isDarkMode, filenamesList, currentColorProfile]);
|
|
368
284
|
|
|
369
|
-
|
|
285
|
+
const mappingColors = useMemo(() => {
|
|
286
|
+
const colors = getMappingColors(mappingsList, isDarkMode, currentColorProfile);
|
|
287
|
+
return colors;
|
|
288
|
+
}, [isDarkMode, mappingsList, currentColorProfile]);
|
|
289
|
+
|
|
290
|
+
const colorByList = {
|
|
291
|
+
filename: filenameColors,
|
|
292
|
+
binary: mappingColors,
|
|
370
293
|
};
|
|
371
294
|
|
|
295
|
+
type ColorByKey = keyof typeof colorByList;
|
|
296
|
+
|
|
297
|
+
const colorByColors: colorByColors = colorByList[colorByValue as ColorByKey];
|
|
298
|
+
|
|
372
299
|
const columnHelper = createColumnHelper<Row>();
|
|
373
300
|
|
|
374
301
|
unit = useMemo(() => unit ?? profileType?.sampleUnit ?? '', [unit, profileType?.sampleUnit]);
|
|
375
302
|
|
|
376
303
|
const columns = useMemo<Array<ColumnDef<Row>>>(() => {
|
|
377
304
|
return [
|
|
305
|
+
columnHelper.accessor('color', {
|
|
306
|
+
id: 'color',
|
|
307
|
+
header: '',
|
|
308
|
+
cell: info => {
|
|
309
|
+
const color = info.getValue() as string;
|
|
310
|
+
return <div className="w-4 h-4 rounded-[4px]" style={{backgroundColor: color}} />;
|
|
311
|
+
},
|
|
312
|
+
size: 10,
|
|
313
|
+
}),
|
|
378
314
|
columnHelper.accessor('flat', {
|
|
379
315
|
id: 'flat',
|
|
380
316
|
header: 'Flat',
|
|
@@ -392,7 +328,7 @@ export const Table = React.memo(function Table({
|
|
|
392
328
|
if (isDummyRow(info.row.original)) {
|
|
393
329
|
return '';
|
|
394
330
|
}
|
|
395
|
-
return ratioString((info as CellContext<DataRow, bigint>).getValue());
|
|
331
|
+
return ratioString((info as CellContext<DataRow, bigint>).getValue(), total, filtered);
|
|
396
332
|
},
|
|
397
333
|
size: 120,
|
|
398
334
|
meta: {
|
|
@@ -418,7 +354,7 @@ export const Table = React.memo(function Table({
|
|
|
418
354
|
if (isDummyRow(info.row.original)) {
|
|
419
355
|
return '';
|
|
420
356
|
}
|
|
421
|
-
return ratioString((info as CellContext<DataRow, bigint>).getValue());
|
|
357
|
+
return ratioString((info as CellContext<DataRow, bigint>).getValue(), total, filtered);
|
|
422
358
|
},
|
|
423
359
|
size: 120,
|
|
424
360
|
meta: {
|
|
@@ -443,7 +379,7 @@ export const Table = React.memo(function Table({
|
|
|
443
379
|
if (isDummyRow(info.row.original)) {
|
|
444
380
|
return '';
|
|
445
381
|
}
|
|
446
|
-
return ratioString((info as CellContext<DataRow, bigint>).getValue());
|
|
382
|
+
return ratioString((info as CellContext<DataRow, bigint>).getValue(), total, filtered);
|
|
447
383
|
},
|
|
448
384
|
size: 150,
|
|
449
385
|
meta: {
|
|
@@ -469,7 +405,7 @@ export const Table = React.memo(function Table({
|
|
|
469
405
|
if (isDummyRow(info.row.original)) {
|
|
470
406
|
return '';
|
|
471
407
|
}
|
|
472
|
-
return ratioString((info as CellContext<DataRow, bigint>).getValue());
|
|
408
|
+
return ratioString((info as CellContext<DataRow, bigint>).getValue(), total, filtered);
|
|
473
409
|
},
|
|
474
410
|
size: 170,
|
|
475
411
|
meta: {
|
|
@@ -503,6 +439,7 @@ export const Table = React.memo(function Table({
|
|
|
503
439
|
|
|
504
440
|
const [columnVisibility, setColumnVisibility] = useState(() => {
|
|
505
441
|
return {
|
|
442
|
+
color: true,
|
|
506
443
|
flat: true,
|
|
507
444
|
flatPercentage: false,
|
|
508
445
|
flatDiff: compareMode,
|
|
@@ -552,37 +489,40 @@ export const Table = React.memo(function Table({
|
|
|
552
489
|
[selectSpan, dashboardItems.length]
|
|
553
490
|
);
|
|
554
491
|
|
|
555
|
-
const onRowDoubleClick = useCallback(
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
row.
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
const
|
|
573
|
-
|
|
574
|
-
|
|
492
|
+
const onRowDoubleClick = useCallback(
|
|
493
|
+
(row: RowType<Row>, rows: Array<RowType<Row>>) => {
|
|
494
|
+
if (isDummyRow(row.original)) {
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
if (!isSubRow(row.original)) {
|
|
498
|
+
row.toggleExpanded();
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
// find the original row for this subrow and toggle it
|
|
502
|
+
const newRow = rows.find(
|
|
503
|
+
r =>
|
|
504
|
+
!isDummyRow(r.original) &&
|
|
505
|
+
!isDummyRow(row.original) &&
|
|
506
|
+
r.original.name === row.original.name &&
|
|
507
|
+
!isSubRow(r.original)
|
|
508
|
+
);
|
|
509
|
+
const parentRow = rows.find(r => {
|
|
510
|
+
const parent = row.getParentRow()!;
|
|
511
|
+
if (isDummyRow(parent.original) || isDummyRow(r.original)) {
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
return r.original.name === parent.original.name;
|
|
515
|
+
});
|
|
516
|
+
if (parentRow == null || newRow == null) {
|
|
517
|
+
return;
|
|
575
518
|
}
|
|
576
|
-
return r.original.name === parent.original.name;
|
|
577
|
-
});
|
|
578
|
-
if (parentRow == null || newRow == null) {
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
519
|
|
|
582
|
-
|
|
520
|
+
newRow.toggleExpanded();
|
|
583
521
|
|
|
584
|
-
|
|
585
|
-
|
|
522
|
+
setScrollToIndex(getScrollTargetIndex(rows, parentRow, newRow));
|
|
523
|
+
},
|
|
524
|
+
[setScrollToIndex]
|
|
525
|
+
);
|
|
586
526
|
|
|
587
527
|
const shouldHighlightRow = useCallback(
|
|
588
528
|
(row: Row) => {
|
|
@@ -608,14 +548,6 @@ export const Table = React.memo(function Table({
|
|
|
608
548
|
];
|
|
609
549
|
}, [compareMode]);
|
|
610
550
|
|
|
611
|
-
const table = useMemo(() => {
|
|
612
|
-
if (loading || data == null) {
|
|
613
|
-
return null;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
return tableFromIPC(data);
|
|
617
|
-
}, [data, loading]);
|
|
618
|
-
|
|
619
551
|
const rows: DataRow[] = useMemo(() => {
|
|
620
552
|
if (table == null || table.numRows === 0) {
|
|
621
553
|
return [];
|
|
@@ -644,6 +576,13 @@ export const Table = React.memo(function Table({
|
|
|
644
576
|
|
|
645
577
|
return {
|
|
646
578
|
id: i,
|
|
579
|
+
color: getRowColor(
|
|
580
|
+
colorByColors,
|
|
581
|
+
mappingFileColumn,
|
|
582
|
+
i,
|
|
583
|
+
functionFileNameColumn,
|
|
584
|
+
colorBy as string
|
|
585
|
+
),
|
|
647
586
|
name: RowName(mappingFileColumn, locationAddressColumn, functionNameColumn, i),
|
|
648
587
|
flat,
|
|
649
588
|
flatDiff,
|
|
@@ -676,7 +615,7 @@ export const Table = React.memo(function Table({
|
|
|
676
615
|
}
|
|
677
616
|
|
|
678
617
|
return rows;
|
|
679
|
-
}, [table]);
|
|
618
|
+
}, [table, colorByColors, colorBy]);
|
|
680
619
|
|
|
681
620
|
if (loading) {
|
|
682
621
|
return (
|
|
@@ -734,85 +673,4 @@ export const Table = React.memo(function Table({
|
|
|
734
673
|
);
|
|
735
674
|
});
|
|
736
675
|
|
|
737
|
-
export const addPlusSign = (num: string): string => {
|
|
738
|
-
if (num.charAt(0) === '0' || num.charAt(0) === '-') {
|
|
739
|
-
return num;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
return `+${num}`;
|
|
743
|
-
};
|
|
744
|
-
|
|
745
|
-
export const RowName = (
|
|
746
|
-
mappingFileColumn: Vector | null,
|
|
747
|
-
locationAddressColumn: Vector | null,
|
|
748
|
-
functionNameColumn: Vector | null,
|
|
749
|
-
row: number
|
|
750
|
-
): string => {
|
|
751
|
-
if (mappingFileColumn === null) {
|
|
752
|
-
console.error('mapping_file column not found');
|
|
753
|
-
return '';
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
const mappingFile: string | null = mappingFileColumn?.get(row);
|
|
757
|
-
let mapping = '';
|
|
758
|
-
// Show the last item in the mapping file only if there are more than 1 mappings
|
|
759
|
-
if (mappingFile != null && mappingFileColumn.data.length > 1) {
|
|
760
|
-
mapping = `[${getLastItem(mappingFile) ?? ''}]`;
|
|
761
|
-
}
|
|
762
|
-
const functionName: string | null = functionNameColumn?.get(row) ?? '';
|
|
763
|
-
if (functionName !== null && functionName !== '') {
|
|
764
|
-
return `${mapping} ${functionName}`;
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
const address: bigint = locationAddressColumn?.get(row) ?? 0;
|
|
768
|
-
|
|
769
|
-
return hexifyAddress(address);
|
|
770
|
-
};
|
|
771
|
-
|
|
772
|
-
const getRowsCount = (rows: Array<RowType<Row>>): number => {
|
|
773
|
-
if (rows.length < 6) {
|
|
774
|
-
return 6;
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
return rows.length;
|
|
778
|
-
};
|
|
779
|
-
|
|
780
|
-
function getScrollTargetIndex(
|
|
781
|
-
rows: Array<RowType<Row>>,
|
|
782
|
-
parentRow: RowType<Row>,
|
|
783
|
-
newRow: RowType<Row>
|
|
784
|
-
): number {
|
|
785
|
-
const parentIndex = rows.indexOf(parentRow);
|
|
786
|
-
const newRowIndex = rows.indexOf(newRow);
|
|
787
|
-
let targetIndex = newRowIndex;
|
|
788
|
-
if (parentIndex > newRowIndex) {
|
|
789
|
-
// Adjusting the number of subs rows to scroll to the main row after expansion.
|
|
790
|
-
targetIndex -= getRowsCount(newRow.subRows);
|
|
791
|
-
}
|
|
792
|
-
if (parentIndex < newRowIndex) {
|
|
793
|
-
// If the parent row is above the new row, we need to adjust the number of subrows of the parent.
|
|
794
|
-
targetIndex += getRowsCount(parentRow.subRows);
|
|
795
|
-
}
|
|
796
|
-
if (targetIndex < 0) {
|
|
797
|
-
targetIndex = 0;
|
|
798
|
-
}
|
|
799
|
-
return targetIndex;
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
function isSubRow(row: Row): boolean {
|
|
803
|
-
return row.isTopSubRow === true || row.isBottomSubRow === true;
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
function isLastSubRow(row: RowType<Row>, rows: Array<RowType<Row>>): boolean {
|
|
807
|
-
const index = rows.indexOf(row);
|
|
808
|
-
const nextRow = rows[index + 1];
|
|
809
|
-
return nextRow == null || (!isSubRow(nextRow.original) && !nextRow.getIsExpanded());
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
function isFirstSubRow(row: RowType<Row>, rows: Array<RowType<Row>>): boolean {
|
|
813
|
-
const index = rows.indexOf(row);
|
|
814
|
-
const prevRow = rows[index - 1];
|
|
815
|
-
return prevRow == null || (!isSubRow(prevRow.original) && !prevRow.getIsExpanded());
|
|
816
|
-
}
|
|
817
|
-
|
|
818
676
|
export default Table;
|