@kylincloud/flamegraph 0.35.14 → 0.35.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kylincloud/flamegraph",
3
- "version": "0.35.14",
3
+ "version": "0.35.15",
4
4
  "description": "KylinCloud flamegraph renderer (Pyroscope-based)",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.node.cjs.js",
@@ -26,6 +26,20 @@
26
26
  "LICENSE",
27
27
  "package.json"
28
28
  ],
29
+ "scripts": {
30
+ "clean": "rm -rf dist",
31
+ "build": "pnpm run clean && pnpm run build:types && pnpm run build:js && pnpm run build:assets",
32
+ "build:types": "tsc -p tsconfig.build.json --emitDeclarationOnly",
33
+ "build:js": "rollup -c",
34
+ "build:assets": "cp src/logo-v3-small.svg dist/logo-v3-small.svg || true",
35
+ "type-check": "tsc -p tsconfig.build.json --noEmit",
36
+ "dev:types": "tsc -p tsconfig.build.json --emitDeclarationOnly --watch",
37
+ "dev:js": "rollup -c -w",
38
+ "dev": "pnpm run dev:js",
39
+ "lint": "eslint ./ --cache --fix",
40
+ "release": "bash -c 'source .env && export GITLAB_TOKEN=\"glpat-$RELEASE_TOKEN\" && release-it'",
41
+ "publish": "npm login --registry=https://registry.npmjs.org/ && pnpm publish --access public --registry=https://registry.npmjs.org/"
42
+ },
29
43
  "peerDependencies": {
30
44
  "graphviz-react": "^1.2.5",
31
45
  "react": ">=16.14.0",
@@ -75,18 +89,5 @@
75
89
  "sass": "^1.94.2",
76
90
  "tslib": "^2.8.1",
77
91
  "typescript": "5.4.5"
78
- },
79
- "scripts": {
80
- "clean": "rm -rf dist",
81
- "build": "pnpm run clean && pnpm run build:types && pnpm run build:js && pnpm run build:assets",
82
- "build:types": "tsc -p tsconfig.build.json --emitDeclarationOnly",
83
- "build:js": "rollup -c",
84
- "build:assets": "cp src/logo-v3-small.svg dist/logo-v3-small.svg || true",
85
- "type-check": "tsc -p tsconfig.build.json --noEmit",
86
- "dev:types": "tsc -p tsconfig.build.json --emitDeclarationOnly --watch",
87
- "dev:js": "rollup -c -w",
88
- "dev": "pnpm run dev:js",
89
- "lint": "eslint ./ --cache --fix",
90
- "release": "bash -c 'source .env && export GITLAB_TOKEN=\"glpat-$RELEASE_TOKEN\" && release-it'"
91
92
  }
92
- }
93
+ }
@@ -1,5 +1,5 @@
1
1
  // src/ProfilerTable.tsx
2
- import React, { useRef, RefObject, CSSProperties } from 'react';
2
+ import React, { useRef, RefObject } from 'react';
3
3
  import type Color from 'color';
4
4
  import cl from 'classnames';
5
5
  import type { Maybe } from 'true-myth';
@@ -15,7 +15,6 @@ import TableTooltip from './Tooltip/TableTooltip';
15
15
  import { getFormatter, ratioToPercent, diffPercent } from './format/format';
16
16
  import {
17
17
  colorBasedOnPackageName,
18
- defaultColor,
19
18
  getPackageNameFromStackTrace,
20
19
  } from './FlameGraph/FlameGraphComponent/color';
21
20
  import { fitIntoTableCell, FitModes } from './fitMode/fitMode';
@@ -200,7 +199,6 @@ interface GetTableBodyRowsProps
200
199
  extends Omit<ProfilerTableProps, 'tableBodyRef'> {
201
200
  sortBy: string;
202
201
  sortByDirection: string;
203
- isDoubles: boolean;
204
202
  messages: FlamegraphMessages;
205
203
  }
206
204
 
@@ -208,7 +206,6 @@ const getTableBody = ({
208
206
  flamebearer,
209
207
  sortBy,
210
208
  sortByDirection,
211
- isDoubles,
212
209
  fitMode,
213
210
  handleTableItemClick,
214
211
  highlightQuery,
@@ -280,9 +277,8 @@ const getTableBody = ({
280
277
  return false;
281
278
  };
282
279
 
283
- const nameCell = (x: { name: string }, style: CSSProperties) => (
280
+ const nameCell = (x: { name: string }) => (
284
281
  <button className="table-item-button">
285
- <span className="color-reference" style={style} />
286
282
  <div className="symbol-name" style={fitIntoTableCell(fitMode)}>
287
283
  {x.name}
288
284
  </div>
@@ -291,14 +287,13 @@ const getTableBody = ({
291
287
 
292
288
  const getSingleRow = (
293
289
  x: SingleCell & { name: string },
294
- color: InstanceType<typeof Color>,
295
- style: CSSProperties
290
+ color: InstanceType<typeof Color>
296
291
  ): BodyRow => ({
297
292
  'data-row': `${x.type};${x.name};${x.self};${x.total}`,
298
293
  isRowSelected: isRowSelected(x.name),
299
294
  onClick: () => handleTableItemClick(x),
300
295
  cells: [
301
- { value: nameCell(x, style) },
296
+ { value: nameCell(x) },
302
297
  {
303
298
  value: formatter.format(x.self, sampleRate),
304
299
  style: backgroundImageStyle(x.self, maxSelf, color),
@@ -311,8 +306,7 @@ const getTableBody = ({
311
306
  });
312
307
 
313
308
  const getDoubleRow = (
314
- x: DoubleCell & { name: string },
315
- style: CSSProperties
309
+ x: DoubleCell & { name: string }
316
310
  ): BodyRow => {
317
311
  const leftPercent = ratioToPercent(x.totalLeft / x.leftTicks);
318
312
  const rghtPercent = ratioToPercent(x.totalRght / x.rightTicks);
@@ -334,9 +328,9 @@ const getTableBody = ({
334
328
  // this function has been removed
335
329
  diffValue = messages.diffRemoved;
336
330
  } else if (totalDiff > 0) {
337
- diffValue = `(+${totalDiff.toFixed(2)}%)`;
331
+ diffValue = `+${totalDiff.toFixed(2)}%`;
338
332
  } else if (totalDiff < 0) {
339
- diffValue = `(${totalDiff.toFixed(2)}%)`;
333
+ diffValue = `${totalDiff.toFixed(2)}%`;
340
334
  }
341
335
 
342
336
  return {
@@ -344,7 +338,7 @@ const getTableBody = ({
344
338
  isRowSelected: isRowSelected(x.name),
345
339
  onClick: () => handleTableItemClick(x),
346
340
  cells: [
347
- { value: nameCell(x, style) },
341
+ { value: nameCell(x) },
348
342
  { value: `${leftPercent} %` },
349
343
  { value: `${rghtPercent} %` },
350
344
  {
@@ -366,19 +360,14 @@ const getTableBody = ({
366
360
  return isMatch(highlightQuery, x.name);
367
361
  })
368
362
  .map((x) => {
369
- const pn = getPackageNameFromStackTrace(spyName, x.name);
370
- const color = isDoubles
371
- ? defaultColor
372
- : colorBasedOnPackageName(palette, pn);
373
- const style = {
374
- backgroundColor: color.rgb().toString(),
375
- };
376
-
377
363
  if (x.type === 'double') {
378
- return getDoubleRow(x as DoubleCell & { name: string }, style);
364
+ return getDoubleRow(x as DoubleCell & { name: string });
379
365
  }
380
366
 
381
- return getSingleRow(x as SingleCell & { name: string }, color, style);
367
+ const pn = getPackageNameFromStackTrace(spyName, x.name);
368
+ const color = colorBasedOnPackageName(palette, pn);
369
+
370
+ return getSingleRow(x as SingleCell & { name: string }, color);
382
371
  });
383
372
 
384
373
  return rows.length > 0
@@ -468,7 +457,6 @@ function Table({
468
457
  flamebearer,
469
458
  sortBy: tableSortProps.sortBy,
470
459
  sortByDirection: tableSortProps.sortByDirection,
471
- isDoubles,
472
460
  fitMode,
473
461
  handleTableItemClick,
474
462
  highlightQuery,
@@ -1,4 +1,10 @@
1
- import React, { useCallback, RefObject, Dispatch, SetStateAction } from 'react';
1
+ // src/Tooltip/FlamegraphTooltip.tsx
2
+ import React, {
3
+ useCallback,
4
+ RefObject,
5
+ Dispatch,
6
+ SetStateAction,
7
+ } from 'react';
2
8
  import { Maybe } from 'true-myth';
3
9
  import type { Unwrapped } from 'true-myth/maybe';
4
10
  import { Units } from '../models/units';
@@ -15,6 +21,10 @@ import {
15
21
  } from '../FlameGraph/FlameGraphComponent/colorPalette';
16
22
 
17
23
  import { Tooltip, TooltipData } from './Tooltip';
24
+ import {
25
+ useFlamegraphI18n,
26
+ type FlamegraphMessages,
27
+ } from '../i18n';
18
28
 
19
29
  type xyToDataSingle = (
20
30
  x: number,
@@ -43,14 +53,14 @@ export type FlamegraphTooltipProps = {
43
53
 
44
54
  palette: FlamegraphPalette;
45
55
  } & (
46
- | { format: 'single'; xyToData: xyToDataSingle }
47
- | {
56
+ | { format: 'single'; xyToData: xyToDataSingle }
57
+ | {
48
58
  format: 'double';
49
59
  leftTicks: number;
50
60
  rightTicks: number;
51
61
  xyToData: xyToDataDouble;
52
62
  }
53
- );
63
+ );
54
64
 
55
65
  export default function FlamegraphTooltip(props: FlamegraphTooltipProps) {
56
66
  const {
@@ -64,6 +74,7 @@ export default function FlamegraphTooltip(props: FlamegraphTooltipProps) {
64
74
  rightTicks,
65
75
  palette,
66
76
  } = props;
77
+ const i18n = useFlamegraphI18n();
67
78
 
68
79
  const setTooltipContent = useCallback(
69
80
  (
@@ -87,8 +98,7 @@ export default function FlamegraphTooltip(props: FlamegraphTooltipProps) {
87
98
 
88
99
  let data: Unwrapped<typeof opt>;
89
100
 
90
- // waiting on
91
- // https://github.com/true-myth/true-myth/issues/279
101
+ // true-myth Maybe 解包
92
102
  if (opt.isJust) {
93
103
  data = opt.value;
94
104
  } else {
@@ -96,13 +106,14 @@ export default function FlamegraphTooltip(props: FlamegraphTooltipProps) {
96
106
  return;
97
107
  }
98
108
 
99
- // set the content for tooltip
100
109
  switch (data.format) {
101
110
  case 'single': {
102
111
  const newLeftContent: TooltipData = {
103
112
  percent: formatPercent(data.total / numTicks),
104
113
  samples:
105
- units === 'trace_samples' ? '' : numberWithCommas(data.total),
114
+ units === 'trace_samples'
115
+ ? ''
116
+ : numberWithCommas(data.total),
106
117
  units,
107
118
  formattedValue: formatter.format(data.total, sampleRate),
108
119
  tooltipType: 'flamegraph',
@@ -139,7 +150,8 @@ export default function FlamegraphTooltip(props: FlamegraphTooltipProps) {
139
150
  title: data.name,
140
151
  units,
141
152
  },
142
- palette
153
+ palette,
154
+ i18n
143
155
  );
144
156
 
145
157
  setContent({
@@ -150,10 +162,10 @@ export default function FlamegraphTooltip(props: FlamegraphTooltipProps) {
150
162
  break;
151
163
  }
152
164
  default:
153
- throw new Error(`Unsupported format:'`);
165
+ throw new Error(`Unsupported format: '${(data as any).format}'`);
154
166
  }
155
167
  },
156
- [numTicks, sampleRate, units, leftTicks, rightTicks, palette]
168
+ [numTicks, sampleRate, units, leftTicks, rightTicks, palette, xyToData, format, i18n]
157
169
  );
158
170
 
159
171
  return (
@@ -161,6 +173,7 @@ export default function FlamegraphTooltip(props: FlamegraphTooltipProps) {
161
173
  dataSourceRef={canvasRef}
162
174
  clickInfoSide="right"
163
175
  setTooltipContent={setTooltipContent}
176
+ palette={palette}
164
177
  />
165
178
  );
166
179
  }
@@ -189,7 +202,8 @@ export function formatDouble(
189
202
  title: string;
190
203
  units: Units;
191
204
  },
192
- palette: FlamegraphPalette = DefaultPalette
205
+ palette: FlamegraphPalette = DefaultPalette,
206
+ i18n?: FlamegraphMessages
193
207
  ): {
194
208
  tooltipData: TooltipData[];
195
209
  title: {
@@ -231,17 +245,20 @@ export function formatDouble(
231
245
  tooltipDiffColor = palette.goodColor.rgb().string();
232
246
  }
233
247
 
248
+ // 这里同时处理:
249
+ // - new / removed 走 i18n,带安全兜底
250
+ // - 百分比 diff 不再带括号,直接 "+12.34%" / "-5.67%"
234
251
  let tooltipDiffText = '';
235
252
  if (!totalLeft) {
236
- // this is a new function
237
- tooltipDiffText = '(new)';
253
+ // 新函数
254
+ tooltipDiffText = i18n?.diffNew ?? '新增';
238
255
  } else if (!totalRight) {
239
- // this function has been removed
240
- tooltipDiffText = '(removed)';
256
+ // 被移除的函数
257
+ tooltipDiffText = i18n?.diffRemoved ?? '移除';
241
258
  } else if (totalDiff > 0) {
242
- tooltipDiffText = `(+${totalDiff.toFixed(2)}%)`;
259
+ tooltipDiffText = `+${totalDiff.toFixed(2)}%`;
243
260
  } else if (totalDiff < 0) {
244
- tooltipDiffText = `(${totalDiff.toFixed(2)}%)`;
261
+ tooltipDiffText = `${totalDiff.toFixed(2)}%`;
245
262
  }
246
263
 
247
264
  return {
@@ -1,10 +1,17 @@
1
- import React, { useCallback, RefObject, Dispatch, SetStateAction } from 'react';
1
+ // src/Tooltip/TableTooltip.tsx
2
+ import React, {
3
+ useCallback,
4
+ RefObject,
5
+ Dispatch,
6
+ SetStateAction,
7
+ } from 'react';
2
8
  import { Units } from '../models/units';
3
9
 
4
10
  import type { FlamegraphPalette } from '../FlameGraph/FlameGraphComponent/colorPalette';
5
11
  import { Tooltip, TooltipData } from './Tooltip';
6
12
  import { formatDouble } from './FlamegraphTooltip';
7
13
  import { getFormatter } from '../format/format';
14
+ import { useFlamegraphI18n } from '../i18n';
8
15
 
9
16
  export interface TableTooltipProps {
10
17
  tableBodyRef: RefObject<HTMLTableSectionElement>;
@@ -23,6 +30,7 @@ export default function TableTooltip({
23
30
  }: TableTooltipProps) {
24
31
  const formatter = getFormatter(numTicks, sampleRate, units);
25
32
  const totalFlamebearer = formatter.format(numTicks, sampleRate);
33
+ const i18n = useFlamegraphI18n();
26
34
 
27
35
  const setTooltipContent = useCallback(
28
36
  (
@@ -58,11 +66,12 @@ export default function TableTooltip({
58
66
  parseInt(self, 10),
59
67
  sampleRate
60
68
  );
61
- const totalFormated = formatter.format(
69
+ const totalFormatted = formatter.format(
62
70
  parseInt(total, 10),
63
71
  sampleRate
64
72
  );
65
- // todo: i think it will be good to decrease number of calculations here
73
+
74
+ // 保持原有百分比计算逻辑
66
75
  const totalFlamebearerSplitted = totalFlamebearer.split(' ');
67
76
  const totalFlamebearerNoUnitsValue =
68
77
  totalFlamebearerSplitted[0] === '<'
@@ -73,7 +82,7 @@ export default function TableTooltip({
73
82
  const selfNoUnitsValue =
74
83
  selfSplitted[0] === '<' ? selfSplitted[1] : selfSplitted[0];
75
84
 
76
- const totalSplitted = totalFormated.split(' ');
85
+ const totalSplitted = totalFormatted.split(' ');
77
86
  const totalNoUnitsValue =
78
87
  totalSplitted[0] === '<' ? totalSplitted[1] : totalSplitted[0];
79
88
 
@@ -84,7 +93,7 @@ export default function TableTooltip({
84
93
  parseFloat(totalFlamebearerNoUnitsValue)) *
85
94
  100
86
95
  ).toFixed(2)}%)`,
87
- total: `${totalFormated}(${(
96
+ total: `${totalFormatted}(${(
88
97
  (parseFloat(totalNoUnitsValue) /
89
98
  parseFloat(totalFlamebearerNoUnitsValue)) *
90
99
  100
@@ -117,7 +126,8 @@ export default function TableTooltip({
117
126
  title: functionName,
118
127
  units,
119
128
  },
120
- palette
129
+ palette,
130
+ i18n
121
131
  );
122
132
 
123
133
  setContent({
@@ -131,7 +141,7 @@ export default function TableTooltip({
131
141
  break;
132
142
  }
133
143
  },
134
- [tableBodyRef, numTicks, formatter, sampleRate]
144
+ [formatter, sampleRate, units, totalFlamebearer, palette, i18n]
135
145
  );
136
146
 
137
147
  return (
@@ -140,6 +150,7 @@ export default function TableTooltip({
140
150
  shouldShowTitle={false}
141
151
  clickInfoSide="left"
142
152
  setTooltipContent={setTooltipContent}
153
+ palette={palette}
143
154
  />
144
155
  );
145
156
  }