@parca/profile 0.19.112 → 0.19.114

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 (146) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/GraphTooltipArrow/Content.d.ts +2 -2
  3. package/dist/GraphTooltipArrow/Content.d.ts.map +1 -1
  4. package/dist/GraphTooltipArrow/DockedGraphTooltip/index.d.ts +2 -2
  5. package/dist/GraphTooltipArrow/DockedGraphTooltip/index.d.ts.map +1 -1
  6. package/dist/GraphTooltipArrow/useGraphTooltip/index.d.ts +2 -2
  7. package/dist/GraphTooltipArrow/useGraphTooltip/index.d.ts.map +1 -1
  8. package/dist/GraphTooltipArrow/useGraphTooltipMetaInfo/index.d.ts +2 -2
  9. package/dist/GraphTooltipArrow/useGraphTooltipMetaInfo/index.d.ts.map +1 -1
  10. package/dist/ProfileExplorer/ProfileExplorerSingle.d.ts.map +1 -1
  11. package/dist/ProfileExplorer/ProfileExplorerSingle.js +9 -3
  12. package/dist/ProfileFlameChart/SamplesStrips/SamplesGraph/index.d.ts +31 -0
  13. package/dist/ProfileFlameChart/SamplesStrips/SamplesGraph/index.d.ts.map +1 -0
  14. package/dist/{MetricsGraphStrips/AreaGraph → ProfileFlameChart/SamplesStrips/SamplesGraph}/index.js +32 -60
  15. package/dist/{MetricsGraphStrips/MetricsGraphStrips.stories.d.ts → ProfileFlameChart/SamplesStrips/SamplesStrips.stories.d.ts} +4 -3
  16. package/dist/ProfileFlameChart/SamplesStrips/SamplesStrips.stories.d.ts.map +1 -0
  17. package/dist/{MetricsGraphStrips/MetricsGraphStrips.stories.js → ProfileFlameChart/SamplesStrips/SamplesStrips.stories.js} +5 -4
  18. package/dist/{MetricsGraphStrips → ProfileFlameChart/SamplesStrips}/index.d.ts +5 -4
  19. package/dist/ProfileFlameChart/SamplesStrips/index.d.ts.map +1 -0
  20. package/dist/ProfileFlameChart/SamplesStrips/index.js +141 -0
  21. package/dist/ProfileFlameChart/index.d.ts +20 -0
  22. package/dist/ProfileFlameChart/index.d.ts.map +1 -0
  23. package/dist/ProfileFlameChart/index.js +155 -0
  24. package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.d.ts +2 -2
  25. package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.d.ts.map +1 -1
  26. package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenuWrapper.d.ts +2 -2
  27. package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenuWrapper.d.ts.map +1 -1
  28. package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.d.ts +2 -2
  29. package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.d.ts.map +1 -1
  30. package/dist/ProfileFlameGraph/FlameGraphArrow/TooltipContext.d.ts +3 -3
  31. package/dist/ProfileFlameGraph/FlameGraphArrow/TooltipContext.d.ts.map +1 -1
  32. package/dist/ProfileFlameGraph/FlameGraphArrow/index.d.ts.map +1 -1
  33. package/dist/ProfileFlameGraph/FlameGraphArrow/index.js +3 -2
  34. package/dist/ProfileFlameGraph/FlameGraphArrow/useMappingList.d.ts +1 -1
  35. package/dist/ProfileFlameGraph/FlameGraphArrow/useMappingList.d.ts.map +1 -1
  36. package/dist/ProfileFlameGraph/FlameGraphArrow/useMappingList.js +16 -16
  37. package/dist/ProfileFlameGraph/FlameGraphArrow/useVisibleNodes.d.ts +2 -2
  38. package/dist/ProfileFlameGraph/FlameGraphArrow/useVisibleNodes.d.ts.map +1 -1
  39. package/dist/ProfileFlameGraph/FlameGraphArrow/utils.d.ts +5 -5
  40. package/dist/ProfileFlameGraph/FlameGraphArrow/utils.d.ts.map +1 -1
  41. package/dist/ProfileFlameGraph/index.d.ts.map +1 -1
  42. package/dist/ProfileFlameGraph/index.js +0 -1
  43. package/dist/ProfileMetricsGraph/hooks/useQueryRange.d.ts +2 -1
  44. package/dist/ProfileMetricsGraph/hooks/useQueryRange.d.ts.map +1 -1
  45. package/dist/ProfileMetricsGraph/hooks/useQueryRange.js +11 -21
  46. package/dist/ProfileMetricsGraph/index.d.ts.map +1 -1
  47. package/dist/ProfileMetricsGraph/index.js +13 -3
  48. package/dist/ProfileSelector/index.d.ts.map +1 -1
  49. package/dist/ProfileSelector/index.js +4 -0
  50. package/dist/ProfileView/components/ActionButtons/GroupByDropdown.d.ts +1 -0
  51. package/dist/ProfileView/components/ActionButtons/GroupByDropdown.d.ts.map +1 -1
  52. package/dist/ProfileView/components/ActionButtons/GroupByDropdown.js +2 -2
  53. package/dist/ProfileView/components/DashboardItems/index.d.ts +5 -4
  54. package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
  55. package/dist/ProfileView/components/DashboardItems/index.js +4 -3
  56. package/dist/ProfileView/components/GroupByLabelsDropdown/index.d.ts +2 -1
  57. package/dist/ProfileView/components/GroupByLabelsDropdown/index.d.ts.map +1 -1
  58. package/dist/ProfileView/components/GroupByLabelsDropdown/index.js +2 -2
  59. package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.js +1 -1
  60. package/dist/ProfileView/components/Toolbars/index.d.ts +2 -0
  61. package/dist/ProfileView/components/Toolbars/index.d.ts.map +1 -1
  62. package/dist/ProfileView/components/Toolbars/index.js +4 -2
  63. package/dist/ProfileView/hooks/useAutoSelectDimension.d.ts +16 -0
  64. package/dist/ProfileView/hooks/useAutoSelectDimension.d.ts.map +1 -0
  65. package/dist/ProfileView/hooks/useAutoSelectDimension.js +75 -0
  66. package/dist/ProfileView/hooks/useProfileMetadata.d.ts +2 -2
  67. package/dist/ProfileView/hooks/useProfileMetadata.d.ts.map +1 -1
  68. package/dist/ProfileView/hooks/useProfileMetadata.js +6 -2
  69. package/dist/ProfileView/hooks/useVisualizationState.d.ts +2 -0
  70. package/dist/ProfileView/hooks/useVisualizationState.d.ts.map +1 -1
  71. package/dist/ProfileView/hooks/useVisualizationState.js +8 -0
  72. package/dist/ProfileView/index.d.ts +1 -1
  73. package/dist/ProfileView/index.d.ts.map +1 -1
  74. package/dist/ProfileView/index.js +7 -4
  75. package/dist/ProfileView/types/visualization.d.ts +15 -3
  76. package/dist/ProfileView/types/visualization.d.ts.map +1 -1
  77. package/dist/ProfileViewWithData.d.ts +2 -1
  78. package/dist/ProfileViewWithData.d.ts.map +1 -1
  79. package/dist/ProfileViewWithData.js +41 -29
  80. package/dist/Sandwich/components/CallersSection.d.ts.map +1 -1
  81. package/dist/Sandwich/components/CallersSection.js +5 -2
  82. package/dist/Sandwich/utils/processRowData.d.ts +1 -1
  83. package/dist/Sandwich/utils/processRowData.d.ts.map +1 -1
  84. package/dist/SourceView/index.js +3 -3
  85. package/dist/Table/index.d.ts.map +1 -1
  86. package/dist/Table/index.js +3 -2
  87. package/dist/Table/utils/functions.d.ts +3 -3
  88. package/dist/Table/utils/functions.d.ts.map +1 -1
  89. package/dist/Table/utils/functions.js +3 -3
  90. package/dist/index.d.ts +1 -0
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +4 -0
  93. package/dist/styles.css +1 -1
  94. package/dist/utils.d.ts +6 -0
  95. package/dist/utils.d.ts.map +1 -1
  96. package/dist/utils.js +8 -0
  97. package/package.json +9 -8
  98. package/src/GraphTooltipArrow/Content.tsx +3 -3
  99. package/src/GraphTooltipArrow/DockedGraphTooltip/index.tsx +2 -2
  100. package/src/GraphTooltipArrow/useGraphTooltip/index.ts +2 -2
  101. package/src/GraphTooltipArrow/useGraphTooltipMetaInfo/index.ts +2 -2
  102. package/src/ProfileExplorer/ProfileExplorerSingle.tsx +14 -3
  103. package/src/{MetricsGraphStrips/AreaGraph → ProfileFlameChart/SamplesStrips/SamplesGraph}/index.tsx +77 -81
  104. package/src/{MetricsGraphStrips/MetricsGraphStrips.stories.tsx → ProfileFlameChart/SamplesStrips/SamplesStrips.stories.tsx} +7 -6
  105. package/src/ProfileFlameChart/SamplesStrips/index.tsx +301 -0
  106. package/src/ProfileFlameChart/index.tsx +305 -0
  107. package/src/ProfileFlameGraph/FlameGraphArrow/ContextMenu.tsx +2 -2
  108. package/src/ProfileFlameGraph/FlameGraphArrow/ContextMenuWrapper.tsx +2 -2
  109. package/src/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.tsx +2 -2
  110. package/src/ProfileFlameGraph/FlameGraphArrow/TooltipContext.tsx +3 -3
  111. package/src/ProfileFlameGraph/FlameGraphArrow/index.tsx +4 -3
  112. package/src/ProfileFlameGraph/FlameGraphArrow/useMappingList.ts +19 -19
  113. package/src/ProfileFlameGraph/FlameGraphArrow/useVisibleNodes.ts +4 -6
  114. package/src/ProfileFlameGraph/FlameGraphArrow/utils.ts +6 -10
  115. package/src/ProfileFlameGraph/index.tsx +0 -1
  116. package/src/ProfileMetricsGraph/hooks/useQueryRange.ts +18 -26
  117. package/src/ProfileMetricsGraph/index.tsx +24 -2
  118. package/src/ProfileSelector/index.tsx +11 -0
  119. package/src/ProfileView/components/ActionButtons/GroupByDropdown.tsx +3 -0
  120. package/src/ProfileView/components/DashboardItems/index.tsx +19 -17
  121. package/src/ProfileView/components/GroupByLabelsDropdown/index.tsx +4 -2
  122. package/src/ProfileView/components/Toolbars/MultiLevelDropdown.tsx +1 -1
  123. package/src/ProfileView/components/Toolbars/index.tsx +18 -1
  124. package/src/ProfileView/hooks/useAutoSelectDimension.ts +90 -0
  125. package/src/ProfileView/hooks/useProfileMetadata.ts +8 -4
  126. package/src/ProfileView/hooks/useVisualizationState.ts +17 -0
  127. package/src/ProfileView/index.tsx +16 -2
  128. package/src/ProfileView/types/visualization.ts +17 -3
  129. package/src/ProfileViewWithData.tsx +80 -37
  130. package/src/Sandwich/components/CallersSection.tsx +6 -3
  131. package/src/Sandwich/utils/processRowData.ts +1 -1
  132. package/src/SourceView/index.tsx +3 -3
  133. package/src/Table/index.tsx +3 -3
  134. package/src/Table/utils/functions.ts +9 -9
  135. package/src/index.tsx +4 -0
  136. package/src/utils.ts +9 -0
  137. package/dist/MetricsGraphStrips/AreaGraph/Tooltip.d.ts +0 -10
  138. package/dist/MetricsGraphStrips/AreaGraph/Tooltip.d.ts.map +0 -1
  139. package/dist/MetricsGraphStrips/AreaGraph/Tooltip.js +0 -44
  140. package/dist/MetricsGraphStrips/AreaGraph/index.d.ts +0 -21
  141. package/dist/MetricsGraphStrips/AreaGraph/index.d.ts.map +0 -1
  142. package/dist/MetricsGraphStrips/MetricsGraphStrips.stories.d.ts.map +0 -1
  143. package/dist/MetricsGraphStrips/index.d.ts.map +0 -1
  144. package/dist/MetricsGraphStrips/index.js +0 -70
  145. package/src/MetricsGraphStrips/AreaGraph/Tooltip.tsx +0 -83
  146. package/src/MetricsGraphStrips/index.tsx +0 -142
package/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.19.114](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.113...@parca/profile@0.19.114) (2026-02-06)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
10
+ ## [0.19.113](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.112...@parca/profile@0.19.113) (2026-01-29)
11
+
12
+ **Note:** Version bump only for package @parca/profile
13
+
6
14
  ## [0.19.112](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.111...@parca/profile@0.19.112) (2026-01-15)
7
15
 
8
16
  **Note:** Version bump only for package @parca/profile
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { Table } from 'apache-arrow';
2
+ import { Table } from '@uwdata/flechette';
3
3
  import { ProfileType } from '@parca/parser';
4
4
  interface GraphTooltipArrowContentProps {
5
- table: Table<any>;
5
+ table: Table;
6
6
  profileType?: ProfileType;
7
7
  unit?: string;
8
8
  total: bigint;
@@ -1 +1 @@
1
- {"version":3,"file":"Content.d.ts","sourceRoot":"","sources":["../../src/GraphTooltipArrow/Content.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAGnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAQ1C,UAAU,6BAA6B;IACrC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAMD,QAAA,MAAM,wBAAwB,GAAI,sFAS/B,6BAA6B,KAAG,KAAK,CAAC,GAAG,CAAC,OA+E5C,CAAC;AAqFF,eAAe,wBAAwB,CAAC"}
1
+ {"version":3,"file":"Content.d.ts","sourceRoot":"","sources":["../../src/GraphTooltipArrow/Content.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAGxC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAQ1C,UAAU,6BAA6B;IACrC,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAMD,QAAA,MAAM,wBAAwB,GAAI,sFAS/B,6BAA6B,KAAG,KAAK,CAAC,GAAG,CAAC,OA+E5C,CAAC;AAqFF,eAAe,wBAAwB,CAAC"}
@@ -1,7 +1,7 @@
1
- import { Table } from 'apache-arrow';
1
+ import { Table } from '@uwdata/flechette';
2
2
  import { ProfileType } from '@parca/parser';
3
3
  interface Props {
4
- table: Table<any>;
4
+ table: Table;
5
5
  total: bigint;
6
6
  totalUnfiltered: bigint;
7
7
  row: number | null;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/GraphTooltipArrow/DockedGraphTooltip/index.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAKnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAO1C,UAAU,KAAK;IACb,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;CAC1B;AAuBD,eAAO,MAAM,kBAAkB,GAAI,6EAQhC,KAAK,KAAG,GAAG,CAAC,OAuGd,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/GraphTooltipArrow/DockedGraphTooltip/index.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAKxC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAO1C,UAAU,KAAK;IACb,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;CAC1B;AAuBD,eAAO,MAAM,kBAAkB,GAAI,6EAQhC,KAAK,KAAG,GAAG,CAAC,OAuGd,CAAC"}
@@ -1,7 +1,7 @@
1
- import { Table } from 'apache-arrow';
1
+ import { Table } from '@uwdata/flechette';
2
2
  import { ProfileType } from '@parca/parser';
3
3
  interface Props {
4
- table: Table<any>;
4
+ table: Table;
5
5
  profileType?: ProfileType;
6
6
  unit?: string;
7
7
  total: bigint;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/GraphTooltipArrow/useGraphTooltip/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAW1C,UAAU,KAAK;IACb,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,eAAe,GAAI,6EAQ7B,KAAK,KAAG,gBAAgB,GAAG,IA4C7B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/GraphTooltipArrow/useGraphTooltip/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAExC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAW1C,UAAU,KAAK;IACb,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,eAAe,GAAI,6EAQ7B,KAAK,KAAG,gBAAgB,GAAG,IA4C7B,CAAC"}
@@ -1,6 +1,6 @@
1
- import { Table } from 'apache-arrow';
1
+ import { Table } from '@uwdata/flechette';
2
2
  interface Props {
3
- table: Table<any>;
3
+ table: Table;
4
4
  row: number;
5
5
  }
6
6
  interface GraphTooltipMetaInfoData {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/GraphTooltipArrow/useGraphTooltipMetaInfo/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAqBnC,UAAU,KAAK;IACb,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,wBAAwB;IAChC,UAAU,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,eAAO,MAAM,uBAAuB,GAAI,gBAAc,KAAK,KAAG,wBA8F7D,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/GraphTooltipArrow/useGraphTooltipMetaInfo/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAqBxC,UAAU,KAAK;IACb,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,wBAAwB;IAChC,UAAU,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,eAAO,MAAM,uBAAuB,GAAI,gBAAc,KAAK,KAAG,wBA8F7D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProfileExplorerSingle.d.ts","sourceRoot":"","sources":["../../src/ProfileExplorer/ProfileExplorerSingle.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAMvD,UAAU,0BAA0B;IAClC,WAAW,EAAE,kBAAkB,CAAC;IAChC,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAED,QAAA,MAAM,qBAAqB,GAAI,8BAG5B,0BAA0B,KAAG,GAAG,CAAC,OAwBnC,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"ProfileExplorerSingle.d.ts","sourceRoot":"","sources":["../../src/ProfileExplorer/ProfileExplorerSingle.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAMvD,UAAU,0BAA0B;IAClC,WAAW,EAAE,kBAAkB,CAAC;IAChC,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAED,QAAA,MAAM,qBAAqB,GAAI,8BAG5B,0BAA0B,KAAG,GAAG,CAAC,OAmCnC,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
@@ -11,13 +11,19 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
11
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
- import { useState } from 'react';
14
+ import { useCallback, useState } from 'react';
15
15
  import { ProfileViewWithData } from '..';
16
16
  import ProfileSelector from '../ProfileSelector';
17
17
  import { useQueryState } from '../hooks/useQueryState';
18
18
  const ProfileExplorerSingle = ({ queryClient, navigateTo, }) => {
19
19
  const [showMetricsGraph, setShowMetricsGraph] = useState(true);
20
- const { profileSource } = useQueryState({ suffix: '_a' });
21
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "relative", children: _jsx(ProfileSelector, { queryClient: queryClient, closeProfile: () => { }, comparing: false, enforcedProfileName: '', navigateTo: navigateTo, suffix: "_a", showMetricsGraph: showMetricsGraph, setDisplayHideMetricsGraphButton: setShowMetricsGraph }) }), profileSource != null && (_jsx(ProfileViewWithData, { queryClient: queryClient, profileSource: profileSource }))] }));
20
+ const { profileSource, setDraftTimeRange, commitDraft } = useQueryState({ suffix: '_a' });
21
+ const handleSwitchToOneMinute = useCallback(() => {
22
+ const now = Date.now();
23
+ const from = now - 60000; // 1 minute ago
24
+ setDraftTimeRange(from, now, 'relative:minute|1');
25
+ commitDraft({ from, to: now, timeSelection: 'relative:minute|1' });
26
+ }, [setDraftTimeRange, commitDraft]);
27
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "relative", children: _jsx(ProfileSelector, { queryClient: queryClient, closeProfile: () => { }, comparing: false, enforcedProfileName: '', navigateTo: navigateTo, suffix: "_a", showMetricsGraph: showMetricsGraph, setDisplayHideMetricsGraphButton: setShowMetricsGraph }) }), profileSource != null && (_jsx(ProfileViewWithData, { queryClient: queryClient, profileSource: profileSource, onSwitchToOneMinute: handleSwitchToOneMinute }))] }));
22
28
  };
23
29
  export default ProfileExplorerSingle;
@@ -0,0 +1,31 @@
1
+ import { NumberDuo } from '../../../utils';
2
+ export interface DataPoint {
3
+ timestamp: number;
4
+ value: number;
5
+ sampleCount?: number;
6
+ }
7
+ interface DragState {
8
+ stripIndex: number;
9
+ startX: number;
10
+ currentX: number;
11
+ }
12
+ interface Props {
13
+ width: number;
14
+ height: number;
15
+ marginLeft?: number;
16
+ marginRight?: number;
17
+ marginTop?: number;
18
+ marginBottom?: number;
19
+ fill?: string;
20
+ data: DataPoint[];
21
+ selectionBounds?: NumberDuo | undefined;
22
+ setSelectionBounds: (newBounds: NumberDuo | undefined) => void;
23
+ stepMs: number;
24
+ onDragStart?: (startX: number) => void;
25
+ dragState?: DragState;
26
+ isAnyDragActive?: boolean;
27
+ timeBounds?: NumberDuo;
28
+ }
29
+ export declare const SamplesGraph: ({ data, height, width, marginLeft, marginRight, marginBottom, marginTop, fill, selectionBounds, setSelectionBounds, stepMs, onDragStart, dragState, isAnyDragActive, timeBounds, }: Props) => JSX.Element;
30
+ export {};
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileFlameChart/SamplesStrips/SamplesGraph/index.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAEzC,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,SAAS;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IACxC,kBAAkB,EAAE,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB;AAwJD,eAAO,MAAM,YAAY,GAAI,oLAgB1B,KAAK,KAAG,GAAG,CAAC,OAkId,CAAC"}
@@ -15,7 +15,6 @@ import { useEffect, useMemo, useRef, useState } from 'react';
15
15
  import { Icon } from '@iconify/react';
16
16
  import cx from 'classnames';
17
17
  import * as d3 from 'd3';
18
- import { Tooltip } from './Tooltip';
19
18
  const DraggingWindow = ({ dragStart, currentX, }) => {
20
19
  const start = useMemo(() => Math.min(dragStart ?? 0, currentX ?? 0), [dragStart, currentX]);
21
20
  const width = useMemo(() => Math.abs((dragStart ?? 0) - (currentX ?? 0)), [dragStart, currentX]);
@@ -100,26 +99,22 @@ const ZoomWindow = ({ zoomWindow, onZoomWindowChange, setIsHoveringDragHandle, }
100
99
  setIsHoveringDragHandle(false);
101
100
  }, children: _jsx(Icon, { icon: "si:drag-handle-line", className: "rotate-90", fontSize: 16 }) })] }) }));
102
101
  };
103
- export const AreaGraph = ({ data, height, width, marginLeft = 0, marginRight = 0, marginBottom = 0, marginTop = 0, fill = 'gray', selectionBounds, setSelectionBounds, valueBounds, }) => {
102
+ export const SamplesGraph = ({ data, height, width, marginLeft = 0, marginRight = 0, marginBottom = 0, marginTop = 0, fill = 'gray', selectionBounds, setSelectionBounds, stepMs, onDragStart, dragState, isAnyDragActive = false, timeBounds, }) => {
104
103
  const [mousePosition, setMousePosition] = useState(undefined);
105
- const [dragStart, setDragStart] = useState(undefined);
106
104
  const [isHoveringDragHandle, setIsHoveringDragHandle] = useState(false);
107
- const [hoverData, setHoverData] = useState(null);
108
- const [isMouseOverGraph, setIsMouseOverGraph] = useState(false);
109
- const isDragging = dragStart !== undefined;
110
- // Declare the x (horizontal position) scale.
111
- const x = d3.scaleUtc(d3.extent(data, d => d.timestamp), [
112
- marginLeft,
113
- width - marginRight,
114
- ]);
115
- // Declare the y (vertical position) scale.
116
- const y = d3.scaleLinear([valueBounds[0], valueBounds[1]], [height - marginBottom, marginTop]);
117
- const area = d3
118
- .area()
119
- .curve(d3.curveMonotoneX)
120
- .x(d => x(d.timestamp))
121
- .y0(y(0))
122
- .y1(d => y(d.value));
105
+ // use the bounds from props if provided, else compute from data
106
+ const xDomain = timeBounds ?? d3.extent(data, d => d.timestamp);
107
+ const x = d3.scaleUtc(xDomain, [marginLeft, width - marginRight]);
108
+ // Calculate sample count range for opacity scaling
109
+ const sampleCounts = data.map(d => Number(d.sampleCount ?? 1));
110
+ const maxSampleCount = Math.max(...sampleCounts);
111
+ const minSampleCount = Math.min(...sampleCounts);
112
+ // Create opacity scale: more samples = higher opacity
113
+ const opacityScale = d3
114
+ .scaleLinear()
115
+ .domain([minSampleCount, maxSampleCount])
116
+ .range([0.5, 1.0])
117
+ .clamp(true);
123
118
  const zoomWindow = useMemo(() => {
124
119
  if (selectionBounds === undefined) {
125
120
  return undefined;
@@ -130,67 +125,44 @@ export const AreaGraph = ({ data, height, width, marginLeft = 0, marginRight = 0
130
125
  const setSelectionBoundsWithScaling = ([startPx, endPx]) => {
131
126
  setSelectionBounds([x.invert(startPx).getTime(), x.invert(endPx).getTime()]);
132
127
  };
133
- return (_jsxs("div", { style: { height, width }, onMouseMove: e => {
128
+ return (_jsxs("div", { style: { height, width }, className: "relative", onMouseMove: e => {
129
+ // Only track hover position when no drag is active anywhere
130
+ if (isAnyDragActive)
131
+ return;
134
132
  const [xPos, yPos] = d3.pointer(e);
135
133
  if (xPos >= marginLeft &&
136
134
  xPos <= width - marginRight &&
137
135
  yPos >= marginTop &&
138
136
  yPos <= height - marginBottom) {
139
137
  setMousePosition([xPos, yPos]);
140
- // Find the closest data point
141
- if (!isHoveringDragHandle && !isDragging) {
142
- const xDate = x.invert(xPos);
143
- const bisect = d3.bisector((d) => d.timestamp).left;
144
- const index = bisect(data, xDate.getTime());
145
- const dataPoint = data[index];
146
- if (dataPoint !== undefined) {
147
- setHoverData(dataPoint);
148
- }
149
- }
150
138
  }
151
139
  else {
152
140
  setMousePosition(undefined);
153
- setHoverData(null);
154
141
  }
155
- }, onMouseEnter: () => {
156
- setIsMouseOverGraph(true);
157
142
  }, onMouseLeave: () => {
158
- setIsMouseOverGraph(false);
143
+ // Only clear hover position, drag is managed by parent
159
144
  setMousePosition(undefined);
160
- setDragStart(undefined);
161
- setHoverData(null);
162
145
  }, onMouseDown: e => {
163
146
  // only left mouse button
164
147
  if (e.button !== 0) {
165
148
  return;
166
149
  }
167
- // X/Y coordinate array relative to svg
150
+ // X/Y coordinate array relative to element
168
151
  const rel = d3.pointer(e);
169
152
  const xCoordinate = rel[0];
170
- const xCoordinateWithoutMargin = xCoordinate - marginLeft;
171
- if (xCoordinateWithoutMargin >= 0) {
172
- setDragStart(xCoordinateWithoutMargin);
153
+ if (xCoordinate >= 0 && onDragStart !== undefined) {
154
+ onDragStart(xCoordinate);
173
155
  }
174
156
  e.stopPropagation();
175
157
  e.preventDefault();
176
- }, onMouseUp: e => {
177
- if (dragStart === undefined) {
178
- return;
179
- }
180
- const rel = d3.pointer(e);
181
- const xCoordinate = rel[0];
182
- const xCoordinateWithoutMargin = xCoordinate - marginLeft;
183
- if (xCoordinateWithoutMargin >= 0 && dragStart !== xCoordinateWithoutMargin) {
184
- const start = Math.min(dragStart, xCoordinateWithoutMargin);
185
- const end = Math.max(dragStart, xCoordinateWithoutMargin);
186
- setSelectionBoundsWithScaling([start, end]);
187
- }
188
- setDragStart(undefined);
189
- }, className: "relative", children: [_jsx("div", { style: { height, width: 2, left: mousePosition?.[0] ?? -1 }, className: cx('bg-gray-700/75 dark:bg-gray-200/75 absolute top-0', {
190
- hidden: mousePosition === undefined || isDragging || isHoveringDragHandle,
191
- }) }), _jsx(DraggingWindow, { dragStart: dragStart, currentX: mousePosition?.[0] }), _jsx(ZoomWindow, { zoomWindow: zoomWindow, width: width, onZoomWindowChange: setSelectionBoundsWithScaling, setIsHoveringDragHandle: setIsHoveringDragHandle }), mousePosition !== undefined &&
192
- hoverData !== null &&
193
- !isDragging &&
194
- !isHoveringDragHandle &&
195
- isMouseOverGraph && (_jsx(Tooltip, { x: mousePosition[0], y: mousePosition[1], timestamp: hoverData.timestamp, value: hoverData.value, containerWidth: width })), _jsx("svg", { style: { width: '100%', height: '100%' }, children: _jsx("path", { fill: fill, d: area(data), className: "opacity-80" }) })] }));
158
+ }, children: [_jsx("div", { style: { height, width: 2, left: mousePosition?.[0] ?? -1 }, className: cx('bg-gray-700/75 dark:bg-gray-200/75 absolute top-0', {
159
+ hidden: mousePosition === undefined || isAnyDragActive || isHoveringDragHandle,
160
+ }) }), _jsx(DraggingWindow, { dragStart: dragState?.startX, currentX: dragState?.currentX }), _jsx(ZoomWindow, { zoomWindow: zoomWindow, width: width, onZoomWindowChange: setSelectionBoundsWithScaling, setIsHoveringDragHandle: setIsHoveringDragHandle }), _jsxs("svg", { style: { width: '100%', height: '100%' }, children: [_jsx("rect", { x: marginLeft, y: 0, width: width - marginLeft - marginRight, height: height, fill: fill, fillOpacity: 0.1 }), _jsx("g", { children: data.map((d, i) => {
161
+ const xPosition = x(d.timestamp);
162
+ // Use stepMs for bucket width
163
+ const rectWidth = x(d.timestamp + stepMs) - xPosition;
164
+ // Calculate opacity based on sample count
165
+ const opacity = opacityScale(Number(d.sampleCount ?? 1));
166
+ return (_jsx("rect", { x: xPosition, y: 0, width: rectWidth, height: height, fill: fill, fillOpacity: opacity }, i));
167
+ }) })] })] }));
196
168
  };
@@ -1,6 +1,6 @@
1
1
  import { Meta } from '@storybook/react';
2
- import { NumberDuo } from '../utils';
3
- import { DataPoint } from './AreaGraph';
2
+ import { NumberDuo } from '../../utils';
3
+ import { DataPoint } from './SamplesGraph';
4
4
  declare const meta: Meta;
5
5
  export default meta;
6
6
  export declare const ThreeCPUStrips: {
@@ -18,7 +18,8 @@ export declare const ThreeCPUStrips: {
18
18
  };
19
19
  onSelectedTimeframe: (index: number, bounds: NumberDuo) => void;
20
20
  bounds: number[];
21
+ stepMs: number;
21
22
  };
22
23
  render: (args: any) => JSX.Element;
23
24
  };
24
- //# sourceMappingURL=MetricsGraphStrips.stories.d.ts.map
25
+ //# sourceMappingURL=SamplesStrips.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SamplesStrips.stories.d.ts","sourceRoot":"","sources":["../../../src/ProfileFlameChart/SamplesStrips/SamplesStrips.stories.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAC;AAEtC,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAqBzC,QAAA,MAAM,IAAI,EAAE,IAGX,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,eAAO,MAAM,cAAc;;;;;;;;;;;;;qCAKM,MAAM,UAAU,SAAS,KAAG,IAAI;;;;mBAM9B,GAAG,KAAG,GAAG,CAAC,OAAO;CAUnD,CAAC"}
@@ -13,7 +13,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
13
13
  // limitations under the License.
14
14
  // eslint-disable-next-line import/named
15
15
  import { useArgs } from '@storybook/preview-api';
16
- import { MetricsGraphStrips } from './index';
16
+ import { SamplesStrip } from './index';
17
17
  function seededRandom(seed) {
18
18
  return () => {
19
19
  seed = (seed * 16807) % 2147483647;
@@ -31,8 +31,8 @@ for (let i = 0; i < 200; i++) {
31
31
  }
32
32
  }
33
33
  const meta = {
34
- title: 'components/MetricsGraphStrips',
35
- component: MetricsGraphStrips,
34
+ title: 'components/SamplesStrip',
35
+ component: SamplesStrip,
36
36
  };
37
37
  export default meta;
38
38
  export const ThreeCPUStrips = {
@@ -44,6 +44,7 @@ export const ThreeCPUStrips = {
44
44
  console.log('onSelectedTimeframe', index, bounds);
45
45
  },
46
46
  bounds: [mockData[0][0].timestamp, mockData[0][mockData[0].length - 1].timestamp],
47
+ stepMs: 100,
47
48
  },
48
49
  render: function Component(args) {
49
50
  const [, setArgs] = useArgs();
@@ -51,6 +52,6 @@ export const ThreeCPUStrips = {
51
52
  args.onSelectedTimeframe(index, bounds);
52
53
  setArgs({ ...args, selectedTimeframe: { index, bounds } });
53
54
  };
54
- return _jsx(MetricsGraphStrips, { ...args, onSelectedTimeframe: onSelectedTimeframe });
55
+ return _jsx(SamplesStrip, { ...args, onSelectedTimeframe: onSelectedTimeframe });
55
56
  },
56
57
  };
@@ -1,6 +1,7 @@
1
1
  import { LabelSet } from '@parca/client';
2
- import { NumberDuo } from '../utils';
3
- import { DataPoint } from './AreaGraph';
2
+ import { NumberDuo } from '../../utils';
3
+ import { DataPoint } from './SamplesGraph';
4
+ export type { DataPoint } from './SamplesGraph';
4
5
  interface Props {
5
6
  cpus: LabelSet[];
6
7
  data: DataPoint[][];
@@ -11,8 +12,8 @@ interface Props {
11
12
  onSelectedTimeframe: (labels: LabelSet, bounds: NumberDuo | undefined) => void;
12
13
  width?: number;
13
14
  bounds: NumberDuo;
15
+ stepMs: number;
14
16
  }
15
17
  export declare const labelSetToString: (labelSet?: LabelSet) => string;
16
- export declare const MetricsGraphStrips: ({ cpus, data, selectedTimeframe, onSelectedTimeframe, width, bounds, }: Props) => JSX.Element;
17
- export {};
18
+ export declare const SamplesStrip: ({ cpus, data, selectedTimeframe, onSelectedTimeframe, width, bounds, stepMs, }: Props) => JSX.Element;
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ProfileFlameChart/SamplesStrips/index.tsx"],"names":[],"mappings":"AAqBA,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAGvC,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,SAAS,EAAe,MAAM,gBAAgB,CAAC;AAEvD,YAAY,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAQ9C,UAAU,KAAK;IACb,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC;IACpB,iBAAiB,CAAC,EAAE;QAClB,MAAM,EAAE,QAAQ,CAAC;QACjB,MAAM,EAAE,SAAS,CAAC;KACnB,CAAC;IACF,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,gBAAgB,GAAI,WAAW,QAAQ,KAAG,MAoBtD,CAAC;AA6FF,eAAO,MAAM,YAAY,GAAI,gFAQ1B,KAAK,KAAG,GAAG,CAAC,OAmId,CAAC"}
@@ -0,0 +1,141 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Copyright 2022 The Parca Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { useMemo, useRef, useState } from 'react';
15
+ import { Icon } from '@iconify/react';
16
+ import cx from 'classnames';
17
+ import * as d3 from 'd3';
18
+ import isEqual from 'fast-deep-equal';
19
+ import { useIntersectionObserver } from 'usehooks-ts';
20
+ import { TimelineGuide } from '../../TimelineGuide';
21
+ import { SamplesGraph } from './SamplesGraph';
22
+ export const labelSetToString = (labelSet) => {
23
+ if (labelSet === undefined) {
24
+ return '{}';
25
+ }
26
+ let str = '{';
27
+ let isFirst = true;
28
+ for (const label of labelSet.labels) {
29
+ if (!isFirst) {
30
+ str += ', ';
31
+ }
32
+ else {
33
+ isFirst = false;
34
+ }
35
+ str += `${label.name}: ${label.value}`;
36
+ }
37
+ str += '}';
38
+ return str;
39
+ };
40
+ const STRIP_HEIGHT = 24;
41
+ const getTimelineGuideHeight = (cpusCount, collapsedCount) => {
42
+ return (STRIP_HEIGHT + 4) * (cpusCount - collapsedCount) + 20 * collapsedCount + 24 - 6;
43
+ };
44
+ const stickyPx = 0;
45
+ const SamplesGraphContainer = ({ isSelected, isCollapsed, cpu, width, onToggleCollapse, data, selectionBounds, setSelectionBounds, color, stepMs, onDragStart, dragState, stripIndex, isAnyDragActive, timeBounds, }) => {
46
+ const labelStr = labelSetToString(cpu);
47
+ const { isIntersecting, ref } = useIntersectionObserver({
48
+ rootMargin: `${stickyPx}px 0px 0px 0px`,
49
+ });
50
+ const isSticky = useMemo(() => {
51
+ return isSelected && isIntersecting;
52
+ }, [isSelected, isIntersecting]);
53
+ return (_jsxs("div", { className: cx('min-h-5', {
54
+ relative: !isSelected,
55
+ 'sticky z-30 bg-white dark:bg-black bg-opacity-75': isSelected,
56
+ '!bg-opacity-100': isSticky,
57
+ }), style: { width: width ?? 1468, top: isSelected ? stickyPx : undefined }, ref: ref, children: [_jsxs("div", { className: "text-xs absolute top-0 left-0 flex gap-[2px] items-center bg-white/50 dark:bg-black/50 px-1 rounded-sm cursor-pointer", style: {
58
+ zIndex: 15,
59
+ }, onClick: onToggleCollapse, children: [_jsx(Icon, { icon: isCollapsed ? 'bxs:right-arrow' : 'bxs:down-arrow' }), labelStr] }), !isCollapsed ? (_jsx(SamplesGraph, { data: data, height: STRIP_HEIGHT, width: width ?? 1468, fill: color(labelStr), selectionBounds: selectionBounds, setSelectionBounds: setSelectionBounds, stepMs: stepMs, onDragStart: (startX) => onDragStart(stripIndex, startX), dragState: dragState?.stripIndex === stripIndex ? dragState : undefined, isAnyDragActive: isAnyDragActive, timeBounds: timeBounds })) : null] }, labelStr));
60
+ };
61
+ export const SamplesStrip = ({ cpus, data, selectedTimeframe, onSelectedTimeframe, width, bounds, stepMs, }) => {
62
+ const [collapsedLabels, setCollapsedLabels] = useState(new Set());
63
+ const [dragState, setDragState] = useState(undefined);
64
+ const containerRef = useRef(null);
65
+ const isDragging = dragState !== undefined;
66
+ // Sort cpus and data by label string for consistent ordering across reloads
67
+ const sortedItems = useMemo(() => {
68
+ const items = cpus.map((cpu, i) => ({
69
+ cpu,
70
+ data: data[i],
71
+ label: labelSetToString(cpu),
72
+ }));
73
+ return items.sort((a, b) => a.label.localeCompare(b.label));
74
+ }, [cpus, data]);
75
+ // Deterministic color: hash the label string so the same label always gets the same color
76
+ // regardless of render order.
77
+ const color = useMemo(() => {
78
+ const palette = d3.schemeObservable10;
79
+ const hashStr = (s) => {
80
+ let h = 0;
81
+ for (let i = 0; i < s.length; i++) {
82
+ h = (Math.imul(31, h) + s.charCodeAt(i)) | 0;
83
+ }
84
+ return Math.abs(h);
85
+ };
86
+ return (label) => palette[hashStr(label) % palette.length];
87
+ }, []);
88
+ const handleDragStart = (stripIndex, startX) => {
89
+ setDragState({ stripIndex, startX, currentX: startX });
90
+ };
91
+ const handleMouseMove = (e) => {
92
+ if (dragState === undefined || containerRef.current === null)
93
+ return;
94
+ const rect = containerRef.current.getBoundingClientRect();
95
+ const x = e.clientX - rect.left;
96
+ // Clamp to container bounds
97
+ const clampedX = Math.max(0, Math.min(x, width ?? rect.width));
98
+ setDragState({ ...dragState, currentX: clampedX });
99
+ };
100
+ const handleMouseUp = (e) => {
101
+ if (dragState === undefined || containerRef.current === null)
102
+ return;
103
+ const rect = containerRef.current.getBoundingClientRect();
104
+ const x = e.clientX - rect.left;
105
+ const clampedX = Math.max(0, Math.min(x, width ?? rect.width));
106
+ const { stripIndex, startX } = dragState;
107
+ if (startX !== clampedX) {
108
+ const start = Math.min(startX, clampedX);
109
+ const end = Math.max(startX, clampedX);
110
+ // Convert pixel positions to timestamps
111
+ const innerWidth = width ?? rect.width;
112
+ const startTs = bounds[0] + (start / innerWidth) * (bounds[1] - bounds[0]);
113
+ const endTs = bounds[0] + (end / innerWidth) * (bounds[1] - bounds[0]);
114
+ // Use sortedItems to get the correct cpu for the strip index
115
+ onSelectedTimeframe(sortedItems[stripIndex].cpu, [startTs, endTs]);
116
+ }
117
+ setDragState(undefined);
118
+ };
119
+ const handleMouseLeave = () => {
120
+ setDragState(undefined);
121
+ };
122
+ if (data.length === 0) {
123
+ return (_jsx("span", { className: "flex justify-center my-10", children: "There is no data matching your filter criteria, please try changing the filter." }));
124
+ }
125
+ return (_jsxs("div", { ref: containerRef, className: cx('flex flex-col gap-1 relative my-0', { 'cursor-ew-resize': isDragging }), style: { width: width ?? '100%' }, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseLeave: handleMouseLeave, children: [_jsx(TimelineGuide, { bounds: [BigInt(0), BigInt(bounds[1] - bounds[0])], width: width ?? 1468, height: getTimelineGuideHeight(sortedItems.length, collapsedLabels.size), margin: 1 }), sortedItems.map((item, i) => {
126
+ const isCollapsed = collapsedLabels.has(item.label);
127
+ const isSelected = isEqual(item.cpu, selectedTimeframe?.labels);
128
+ return (_jsx(SamplesGraphContainer, { isSelected: isSelected, isCollapsed: isCollapsed, cpu: item.cpu, width: width, data: item.data, onToggleCollapse: () => {
129
+ const newCollapsedLabels = new Set(collapsedLabels);
130
+ if (collapsedLabels.has(item.label)) {
131
+ newCollapsedLabels.delete(item.label);
132
+ }
133
+ else {
134
+ newCollapsedLabels.add(item.label);
135
+ }
136
+ setCollapsedLabels(newCollapsedLabels);
137
+ }, selectionBounds: isSelected ? selectedTimeframe?.bounds : undefined, setSelectionBounds: newBounds => {
138
+ onSelectedTimeframe(item.cpu, newBounds);
139
+ }, color: color, stepMs: stepMs, onDragStart: handleDragStart, dragState: dragState, stripIndex: i, isAnyDragActive: isDragging, timeBounds: bounds }, item.label));
140
+ })] }));
141
+ };
@@ -0,0 +1,20 @@
1
+ import { QueryServiceClient } from '@parca/client';
2
+ import { ProfileType } from '@parca/parser';
3
+ import { ProfileSource } from '../ProfileSource';
4
+ import type { SamplesData } from '../ProfileView/types/visualization';
5
+ interface ProfileFlameChartProps {
6
+ samplesData?: SamplesData;
7
+ queryClient: QueryServiceClient;
8
+ profileSource: ProfileSource;
9
+ width: number;
10
+ total: bigint;
11
+ filtered: bigint;
12
+ profileType?: ProfileType;
13
+ isHalfScreen: boolean;
14
+ metadataMappingFiles?: string[];
15
+ metadataLoading?: boolean;
16
+ onSwitchToOneMinute?: () => void;
17
+ }
18
+ export declare const ProfileFlameChart: ({ samplesData, queryClient, profileSource, width, total, filtered, profileType, isHalfScreen, metadataMappingFiles, metadataLoading, onSwitchToOneMinute, }: ProfileFlameChartProps) => JSX.Element;
19
+ export default ProfileFlameChart;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileFlameChart/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAoC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAQpF,OAAO,EAAwB,WAAW,EAAQ,MAAM,eAAe,CAAC;AAIxE,OAAO,EAAsB,aAAa,EAAC,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oCAAoC,CAAC;AA4CpE,UAAU,sBAAsB;IAC9B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;CAClC;AA+BD,eAAO,MAAM,iBAAiB,GAAI,6JAY/B,sBAAsB,KAAG,GAAG,CAAC,OA+K/B,CAAC;AAEF,eAAe,iBAAiB,CAAC"}