@rsdoctor/components 1.5.18 → 1.6.0

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 (114) hide show
  1. package/dist/components/Alert/ecma-version-check_module.css +1 -1
  2. package/dist/components/Alert/ecma-version-check_module.css.map +1 -1
  3. package/dist/components/Alerts/bundle-alert.mjs +8 -6
  4. package/dist/components/Alerts/bundle-alert.mjs.map +1 -1
  5. package/dist/components/Alerts/bundle.mjs +1 -2
  6. package/dist/components/Alerts/bundle.mjs.map +1 -1
  7. package/dist/components/Alerts/collapse-cjs-require.mjs +6 -14
  8. package/dist/components/Alerts/collapse-cjs-require.mjs.map +1 -1
  9. package/dist/components/Alerts/collapse-cross-chunks.mjs +3 -8
  10. package/dist/components/Alerts/collapse-cross-chunks.mjs.map +1 -1
  11. package/dist/components/Alerts/collapse-esm-cjs.mjs +6 -10
  12. package/dist/components/Alerts/collapse-esm-cjs.mjs.map +1 -1
  13. package/dist/components/Alerts/collapse-module-mixed-chunks.mjs +5 -12
  14. package/dist/components/Alerts/collapse-module-mixed-chunks.mjs.map +1 -1
  15. package/dist/components/Alerts/collapse-side-effects-only-imports.mjs +5 -12
  16. package/dist/components/Alerts/collapse-side-effects-only-imports.mjs.map +1 -1
  17. package/dist/components/Alerts/collapse.mjs +3 -10
  18. package/dist/components/Alerts/collapse.mjs.map +1 -1
  19. package/dist/components/Alerts/collapse_module.css +1 -1
  20. package/dist/components/Alerts/collapse_module.css.map +1 -1
  21. package/dist/components/Alerts/index.module.mjs +7 -0
  22. package/dist/components/Alerts/index.module.mjs.map +1 -0
  23. package/dist/components/Alerts/index_module.css +9 -0
  24. package/dist/components/Alerts/index_module.css.map +1 -0
  25. package/dist/components/Alerts/list.mjs +0 -3
  26. package/dist/components/Alerts/list.mjs.map +1 -1
  27. package/dist/components/Card/size_module.css +0 -2
  28. package/dist/components/Card/size_module.css.map +1 -1
  29. package/dist/components/Charts/TimelineCharts/index.mjs +63 -39
  30. package/dist/components/Charts/TimelineCharts/index.mjs.map +1 -1
  31. package/dist/components/Charts/TreeMap.mjs +88 -101
  32. package/dist/components/Charts/TreeMap.mjs.map +1 -1
  33. package/dist/components/Charts/index.mjs +3 -1
  34. package/dist/components/Charts/index.mjs.map +1 -1
  35. package/dist/components/Charts/treemap_module.css +6 -5
  36. package/dist/components/Charts/treemap_module.css.map +1 -1
  37. package/dist/components/FileTree/index.css +0 -1
  38. package/dist/components/FileTree/index.css.map +1 -1
  39. package/dist/components/FileTree/index.mjs +3 -4
  40. package/dist/components/FileTree/index.mjs.map +1 -1
  41. package/dist/components/Keyword/style_module.css +0 -1
  42. package/dist/components/Keyword/style_module.css.map +1 -1
  43. package/dist/components/Layout/header.mjs +22 -6
  44. package/dist/components/Layout/header.mjs.map +1 -1
  45. package/dist/components/Layout/header.module.mjs +0 -1
  46. package/dist/components/Layout/header.module.mjs.map +1 -1
  47. package/dist/components/Layout/header_module.css +0 -6
  48. package/dist/components/Layout/header_module.css.map +1 -1
  49. package/dist/components/Layout/index.mjs +27 -8
  50. package/dist/components/Layout/index.mjs.map +1 -1
  51. package/dist/components/Layout/menus.mjs +3 -1
  52. package/dist/components/Layout/menus.mjs.map +1 -1
  53. package/dist/components/Layout/rsdoctor-title-logo-dark.mjs +2 -0
  54. package/dist/components/Loader/Analysis/files.mjs +16 -17
  55. package/dist/components/Loader/Analysis/files.mjs.map +1 -1
  56. package/dist/components/Loader/Analysis/style_module.css +13 -14
  57. package/dist/components/Loader/Analysis/style_module.css.map +1 -1
  58. package/dist/components/Loader/executions.mjs +5 -13
  59. package/dist/components/Loader/executions.mjs.map +1 -1
  60. package/dist/components/Overall/DataSummary.mjs +21 -20
  61. package/dist/components/Overall/DataSummary.mjs.map +1 -1
  62. package/dist/components/Overall/DataSummary.module.mjs +1 -12
  63. package/dist/components/Overall/DataSummary.module.mjs.map +1 -1
  64. package/dist/components/Overall/DataSummary_module.css +7 -72
  65. package/dist/components/Overall/DataSummary_module.css.map +1 -1
  66. package/dist/components/Overall/bundle_module.css +1 -4
  67. package/dist/components/Overall/bundle_module.css.map +1 -1
  68. package/dist/components/Overall/list_module.css +0 -2
  69. package/dist/components/Overall/list_module.css.map +1 -1
  70. package/dist/components/Overall/overview_module.css +1 -2
  71. package/dist/components/Overall/overview_module.css.map +1 -1
  72. package/dist/components/base/CodeViewer/index.d.ts +1 -1
  73. package/dist/components/base/CodeViewer/index.mjs +5 -3
  74. package/dist/components/base/CodeViewer/index.mjs.map +1 -1
  75. package/dist/components/base/CodeViewer/interface.d.ts +1 -2
  76. package/dist/components/base/DiffViewer/index.d.ts +1 -1
  77. package/dist/components/base/DiffViewer/index.mjs +4 -1
  78. package/dist/components/base/DiffViewer/index.mjs.map +1 -1
  79. package/dist/components/base/DiffViewer/interface.d.ts +1 -2
  80. package/dist/pages/BundleSize/components/asset_module.css +7 -5
  81. package/dist/pages/BundleSize/components/asset_module.css.map +1 -1
  82. package/dist/pages/BundleSize/components/card_module.css +2 -2
  83. package/dist/pages/BundleSize/components/card_module.css.map +1 -1
  84. package/dist/pages/BundleSize/components/cards.mjs +5 -6
  85. package/dist/pages/BundleSize/components/cards.mjs.map +1 -1
  86. package/dist/pages/BundleSize/components/index.mjs +11 -8
  87. package/dist/pages/BundleSize/components/index.mjs.map +1 -1
  88. package/dist/pages/BundleSize/components/index.module.mjs +1 -6
  89. package/dist/pages/BundleSize/components/index.module.mjs.map +1 -1
  90. package/dist/pages/BundleSize/components/index_module.css +0 -37
  91. package/dist/pages/BundleSize/components/index_module.css.map +1 -1
  92. package/dist/pages/BundleSize/components/search-modal.mjs +5 -5
  93. package/dist/pages/BundleSize/components/search-modal.mjs.map +1 -1
  94. package/dist/pages/BundleSize/components/search-modal.module.mjs +10 -0
  95. package/dist/pages/BundleSize/components/search-modal.module.mjs.map +1 -0
  96. package/dist/pages/BundleSize/components/search-modal_module.css +39 -0
  97. package/dist/pages/BundleSize/components/search-modal_module.css.map +1 -0
  98. package/dist/pages/BundleSize/components/tree-graph.mjs +2 -2
  99. package/dist/pages/BundleSize/components/tree-graph.mjs.map +1 -1
  100. package/dist/pages/ModuleAnalyze/components/fileTreeCom.css +6 -2
  101. package/dist/pages/ModuleAnalyze/components/fileTreeCom.css.map +1 -1
  102. package/dist/pages/ModuleAnalyze/index.css +4 -6
  103. package/dist/pages/ModuleAnalyze/index.css.map +1 -1
  104. package/dist/pages/ModuleAnalyze/index.mjs +3 -4
  105. package/dist/pages/ModuleAnalyze/index.mjs.map +1 -1
  106. package/dist/pages/WebpackLoaders/Analysis/index.mjs +3 -3
  107. package/dist/pages/WebpackLoaders/Analysis/index.mjs.map +1 -1
  108. package/dist/pages/WebpackLoaders/Overall/index.mjs +1 -1
  109. package/dist/pages/WebpackLoaders/Overall/index.mjs.map +1 -1
  110. package/dist/static/image/rsdoctor-title-logo-dark.png +0 -0
  111. package/dist/utils/hooks.d.ts +1 -0
  112. package/dist/utils/hooks.mjs +6 -1
  113. package/dist/utils/hooks.mjs.map +1 -1
  114. package/package.json +4 -4
@@ -7,7 +7,7 @@ import { TitleComponent, TooltipComponent } from "echarts/components";
7
7
  import { CanvasRenderer } from "echarts/renderers";
8
8
  import { Alert, Checkbox, Input, Radio } from "antd";
9
9
  import { FullscreenExitOutlined, FullscreenOutlined, LeftOutlined, RightOutlined, SearchOutlined } from "@ant-design/icons";
10
- import { formatSize } from "../../utils/index.mjs";
10
+ import { formatSize, useThemeToken } from "../../utils/index.mjs";
11
11
  import { SDK } from "@rsdoctor/types";
12
12
  import { ServerAPIProvider } from "../Manifest/index.mjs";
13
13
  import { ModuleAnalyzeComponent } from "../../pages/ModuleAnalyze/index.mjs";
@@ -76,11 +76,12 @@ function getLevelOption() {
76
76
  }
77
77
  ];
78
78
  }
79
- const TreeMap = /*#__PURE__*/ memo(({ treeData, sizeType, style, onChartClick, highlightNodeId, centerNodeId, rootPath })=>{
79
+ const TreeMap = /*#__PURE__*/ memo(({ treeData, sizeType, onChartClick, highlightNodeId, centerNodeId, rootPath })=>{
80
80
  const [option, setOption] = useState(null);
81
81
  const chartRef = react.useRef(null);
82
82
  const chartDataRef = react.useRef([]);
83
83
  const clickTimeoutRef = react.useRef(null);
84
+ const themeToken = useThemeToken();
84
85
  useEffect(()=>{
85
86
  if (!treeData) return;
86
87
  function convert(node, index = 0, level = 0, parentColor, siblingIndex = 0, siblingCount = 1, chunkPath) {
@@ -153,15 +154,16 @@ const TreeMap = /*#__PURE__*/ memo(({ treeData, sizeType, style, onChartClick, h
153
154
  }
154
155
  const data = treeData.map((item, index)=>convert(item, index, 0, void 0, index, treeData.length, void 0)).filter((item)=>('number' == typeof item.value ? item.value > 0 : false) || item.children && item.children.length > 0);
155
156
  chartDataRef.current = data;
157
+ const textColor = themeToken.colorText;
156
158
  setOption({
157
159
  color: TREE_COLORS,
158
160
  tooltip: {
159
161
  padding: 10,
160
- backgroundColor: '#fff',
161
- borderColor: '#eee',
162
+ backgroundColor: themeToken.colorBgElevated,
163
+ borderColor: themeToken.colorBorder,
162
164
  borderWidth: 1,
163
165
  textStyle: {
164
- color: 'rgba(0, 0, 0, 0.8)'
166
+ color: textColor
165
167
  },
166
168
  confine: true,
167
169
  extraCssText: 'max-width: 450px; word-wrap: break-word;',
@@ -197,7 +199,7 @@ const TreeMap = /*#__PURE__*/ memo(({ treeData, sizeType, style, onChartClick, h
197
199
  if (void 0 !== gzipSize && gzipSize > 0) rows.push(makeRow('Gzipped size', formatSize(gzipSize), '#1677ff'));
198
200
  return `
199
201
  <div style="font-family: sans-serif; font-size: 12px; line-height: 1.5;">
200
- <div style="margin-bottom: 6px; max-width: 400px; word-wrap: break-word; overflow-wrap: break-word; word-break: break-all; white-space: normal; color: rgba(0, 0, 0, 0.8);">${__rspack_external_echarts_core_d2845954.format.encodeHTML(path)}</div>
202
+ <div style="margin-bottom: 6px; max-width: 400px; word-wrap: break-word; overflow-wrap: break-word; word-break: break-all; white-space: normal; color: ${textColor};">${__rspack_external_echarts_core_d2845954.format.encodeHTML(path)}</div>
201
203
  ${rows.join('')}
202
204
  </div>
203
205
  `;
@@ -206,9 +208,6 @@ const TreeMap = /*#__PURE__*/ memo(({ treeData, sizeType, style, onChartClick, h
206
208
  series: [
207
209
  {
208
210
  type: 'treemap',
209
- itemStyle: {
210
- gapColor: '#ffffff'
211
- },
212
211
  label: {
213
212
  show: true,
214
213
  formatter: '{b}',
@@ -247,17 +246,17 @@ const TreeMap = /*#__PURE__*/ memo(({ treeData, sizeType, style, onChartClick, h
247
246
  color: '#999',
248
247
  borderColor: 'transparent',
249
248
  borderWidth: 0,
250
- borderRadius: 0
249
+ borderRadius: 0,
250
+ textStyle: {
251
+ fontFamily: 'sans-serif',
252
+ fontSize: 12,
253
+ color: 'white'
254
+ }
251
255
  },
252
256
  emphasis: {
253
257
  itemStyle: {
254
258
  color: '#333'
255
259
  }
256
- },
257
- textStyle: {
258
- fontFamily: 'sans-serif',
259
- fontSize: 12,
260
- color: '#666'
261
260
  }
262
261
  },
263
262
  roam: true,
@@ -270,7 +269,7 @@ const TreeMap = /*#__PURE__*/ memo(({ treeData, sizeType, style, onChartClick, h
270
269
  bottom: 30,
271
270
  left: 0,
272
271
  right: 0,
273
- zoomLimit: {
272
+ scaleLimit: {
274
273
  min: 0.5,
275
274
  max: 5
276
275
  }
@@ -281,7 +280,8 @@ const TreeMap = /*#__PURE__*/ memo(({ treeData, sizeType, style, onChartClick, h
281
280
  treeData,
282
281
  sizeType,
283
282
  highlightNodeId,
284
- rootPath
283
+ rootPath,
284
+ themeToken
285
285
  ]);
286
286
  useEffect(()=>{
287
287
  if (centerNodeId && chartRef.current && option) {
@@ -359,7 +359,6 @@ const TreeMap = /*#__PURE__*/ memo(({ treeData, sizeType, style, onChartClick, h
359
359
  }, []);
360
360
  return option ? /*#__PURE__*/ jsxs("div", {
361
361
  className: treemap_module["chart-container"],
362
- style: style,
363
362
  children: [
364
363
  /*#__PURE__*/ jsx(Alert, {
365
364
  message: "If parsed size lacks detailed module information, you can enable sourceMap when RSDOCTOR = true. This is because Rsdoctor relies on SourceMap to obtain Parsed Size. Rspack provides SourceMap information to Rsdoctor by default without affecting the build output.",
@@ -369,37 +368,42 @@ const TreeMap = /*#__PURE__*/ memo(({ treeData, sizeType, style, onChartClick, h
369
368
  marginBottom: 0
370
369
  }
371
370
  }),
372
- /*#__PURE__*/ jsx(core, {
373
- ref: chartRef,
374
- option: option,
375
- echarts: __rspack_external_echarts_core_d2845954,
376
- onEvents: {
377
- click: (params)=>{
378
- if (clickTimeoutRef.current) window.clearTimeout(clickTimeoutRef.current);
379
- clickTimeoutRef.current = window.setTimeout(()=>{
380
- if (chartRef.current) {
381
- const instance = chartRef.current.getEchartsInstance();
382
- const data = params?.data;
383
- if (instance && data?.id !== void 0) instance.dispatchAction({
384
- type: 'treemapZoomToNode',
385
- seriesIndex: 0,
386
- targetNodeId: String(data.id)
387
- });
371
+ /*#__PURE__*/ jsx("div", {
372
+ style: {
373
+ flex: 1
374
+ },
375
+ children: /*#__PURE__*/ jsx(core, {
376
+ ref: chartRef,
377
+ option: option,
378
+ echarts: __rspack_external_echarts_core_d2845954,
379
+ onEvents: {
380
+ click: (params)=>{
381
+ if (clickTimeoutRef.current) window.clearTimeout(clickTimeoutRef.current);
382
+ clickTimeoutRef.current = window.setTimeout(()=>{
383
+ if (chartRef.current) {
384
+ const instance = chartRef.current.getEchartsInstance();
385
+ const data = params?.data;
386
+ if (instance && data?.id !== void 0) instance.dispatchAction({
387
+ type: 'treemapZoomToNode',
388
+ seriesIndex: 0,
389
+ targetNodeId: String(data.id)
390
+ });
391
+ }
392
+ }, 180);
393
+ },
394
+ dblclick: (params)=>{
395
+ if (clickTimeoutRef.current) {
396
+ window.clearTimeout(clickTimeoutRef.current);
397
+ clickTimeoutRef.current = null;
388
398
  }
389
- }, 180);
390
- },
391
- dblclick: (params)=>{
392
- if (clickTimeoutRef.current) {
393
- window.clearTimeout(clickTimeoutRef.current);
394
- clickTimeoutRef.current = null;
399
+ onChartClick?.(params);
395
400
  }
396
- onChartClick?.(params);
401
+ },
402
+ style: {
403
+ width: '100%',
404
+ height: '100%'
397
405
  }
398
- },
399
- style: {
400
- width: '100%',
401
- height: '100%'
402
- }
406
+ })
403
407
  })
404
408
  ]
405
409
  }) : null;
@@ -459,42 +463,37 @@ const AssetTreemapWithFilterInner = ({ treeData, onChartClick, bundledSize = tru
459
463
  }, [
460
464
  onChartClick
461
465
  ]);
462
- const enterFullscreen = useCallback(()=>{
463
- if (containerRef.current) {
464
- const el = containerRef.current;
465
- if (el.requestFullscreen) el.requestFullscreen().then(()=>setIsFullscreen(true)).catch((err)=>console.error('Failed to enter fullscreen:', err));
466
- else if (el.webkitRequestFullscreen) try {
467
- el.webkitRequestFullscreen();
468
- setIsFullscreen(true);
469
- } catch (err) {
470
- console.error('Failed to enter fullscreen (webkit):', err);
471
- }
472
- else if (el.mozRequestFullScreen) try {
473
- el.mozRequestFullScreen();
474
- setIsFullscreen(true);
475
- } catch (err) {
476
- console.error('Failed to enter fullscreen (moz):', err);
477
- }
478
- else if (el.msRequestFullscreen) try {
479
- el.msRequestFullscreen();
480
- setIsFullscreen(true);
481
- } catch (err) {
482
- console.error('Failed to enter fullscreen (ms):', err);
483
- }
484
- else console.error('Fullscreen API is not supported in this browser.');
466
+ const enterFullscreen = ()=>{
467
+ if (!containerRef.current) return;
468
+ const el = containerRef.current;
469
+ if (el.requestFullscreen) el.requestFullscreen().then(()=>setIsFullscreen(true)).catch((err)=>console.error('Failed to enter fullscreen:', err));
470
+ else if (el.webkitRequestFullscreen) try {
471
+ el.webkitRequestFullscreen();
472
+ setIsFullscreen(true);
473
+ } catch (err) {
474
+ console.error('Failed to enter fullscreen (webkit):', err);
485
475
  }
486
- }, []);
487
- const exitFullscreen = useCallback(()=>{
476
+ else if (el.mozRequestFullScreen) try {
477
+ el.mozRequestFullScreen();
478
+ setIsFullscreen(true);
479
+ } catch (err) {
480
+ console.error('Failed to enter fullscreen (moz):', err);
481
+ }
482
+ else if (el.msRequestFullscreen) try {
483
+ el.msRequestFullscreen();
484
+ setIsFullscreen(true);
485
+ } catch (err) {
486
+ console.error('Failed to enter fullscreen (ms):', err);
487
+ }
488
+ else console.error('Fullscreen API is not supported in this browser.');
489
+ };
490
+ const exitFullscreen = ()=>{
488
491
  document.exitFullscreen().then(()=>setIsFullscreen(false)).catch((err)=>console.error('Failed to exit fullscreen:', err));
489
- }, []);
490
- const toggleFullscreen = useCallback(()=>{
492
+ };
493
+ const toggleFullscreen = ()=>{
491
494
  if (isFullscreen) exitFullscreen();
492
495
  else enterFullscreen();
493
- }, [
494
- isFullscreen,
495
- enterFullscreen,
496
- exitFullscreen
497
- ]);
496
+ };
498
497
  useEffect(()=>{
499
498
  const handleFullscreenChange = ()=>{
500
499
  setIsFullscreen(!!document.fullscreenElement);
@@ -539,48 +538,40 @@ const AssetTreemapWithFilterInner = ({ treeData, onChartClick, bundledSize = tru
539
538
  filteredTreeData,
540
539
  searchQuery
541
540
  ]);
542
- const handleSearchResultClick = useCallback((nodeId)=>{
541
+ const handleSearchResultClick = (nodeId)=>{
543
542
  setHighlightNodeId(nodeId);
544
543
  setCenterNodeId(nodeId);
545
- }, []);
546
- const removeRootPath = useCallback((filepath)=>{
544
+ };
545
+ const removeRootPath = (filepath)=>{
547
546
  if (!rootPath || !filepath) return filepath;
548
547
  const normalizedRoot = rootPath.replace(/\\/g, '/').replace(/\/$/, '');
549
548
  const normalizedPath = filepath.replace(/\\/g, '/');
550
549
  if (normalizedPath.startsWith(normalizedRoot + '/')) return normalizedPath.slice(normalizedRoot.length + 1);
551
550
  if (normalizedPath === normalizedRoot) return '';
552
551
  return filepath;
553
- }, [
554
- rootPath
555
- ]);
556
- const getSize = useCallback((node, type)=>{
552
+ };
553
+ const getSize = (node, type)=>{
557
554
  if ('stat' === type) return node.sourceSize || 0;
558
555
  if ('parsed' === type) return node.bundledSize || 0;
559
556
  if ('gzip' === type) return node.gzipSize || 0;
560
557
  if ('value' === type) return node.value || 0;
561
558
  if (node.value) return node.value;
562
559
  return 0;
563
- }, []);
564
- const calculateNodeTotalSize = useCallback((node, type)=>{
560
+ };
561
+ const calculateNodeTotalSize = (node, type)=>{
565
562
  let size = getSize(node, type);
566
563
  if (node.children && node.children.length > 0) {
567
564
  const childrenSize = node.children.reduce((sum, child)=>sum + calculateNodeTotalSize(child, type), 0);
568
565
  if (0 === size || !node.path && childrenSize > 0) size = childrenSize;
569
566
  }
570
567
  return size;
571
- }, [
572
- getSize
573
- ]);
574
- const getChunkSize = useCallback((name, type)=>{
568
+ };
569
+ const getChunkSize = (name, type)=>{
575
570
  const node = treeData.find((n)=>n.name === name);
576
571
  if (!node) return 0;
577
572
  const sizeTypeToUse = type || sizeType;
578
573
  return calculateNodeTotalSize(node, sizeTypeToUse);
579
- }, [
580
- treeData,
581
- sizeType,
582
- calculateNodeTotalSize
583
- ]);
574
+ };
584
575
  return /*#__PURE__*/ jsxs("div", {
585
576
  className: treemap_module.treemap,
586
577
  ref: containerRef,
@@ -770,11 +761,7 @@ const AssetTreemapWithFilterInner = ({ treeData, onChartClick, bundledSize = tru
770
761
  onChartClick: handleChartClick,
771
762
  highlightNodeId: highlightNodeId,
772
763
  centerNodeId: centerNodeId,
773
- rootPath: rootPath,
774
- style: {
775
- width: '100%',
776
- height: '100%'
777
- }
764
+ rootPath: rootPath
778
765
  }),
779
766
  moduleId ? /*#__PURE__*/ jsx(ServerAPIProvider, {
780
767
  api: SDK.ServerAPI.API.GetAllModuleGraph,
@@ -1 +1 @@
1
- {"version":3,"file":"components/Charts/TreeMap.mjs","sources":["../../../src/components/Charts/TreeMap.tsx"],"sourcesContent":["import React, { useEffect, useState, memo, useMemo, useCallback } from 'react';\nimport EChartsReactCore from 'echarts-for-react/esm/core';\nimport * as echarts from 'echarts/core';\nimport { TreemapChart, type TreemapSeriesOption } from 'echarts/charts';\nimport {\n TooltipComponent,\n TitleComponent,\n type TooltipComponentOption,\n type TitleComponentOption,\n} from 'echarts/components';\nimport { CanvasRenderer } from 'echarts/renderers';\nimport { Alert, Checkbox, Radio, Input } from 'antd';\nimport {\n LeftOutlined,\n RightOutlined,\n SearchOutlined,\n FullscreenOutlined,\n FullscreenExitOutlined,\n} from '@ant-design/icons';\nimport type { ComposeOption, EChartsType } from 'echarts/core';\nimport { formatSize } from 'src/utils';\nimport { SDK } from '@rsdoctor/types';\nimport { ServerAPIProvider } from 'src/components/Manifest';\nimport { ModuleAnalyzeComponent } from '../../pages/ModuleAnalyze';\nimport Styles from './treemap.module.scss';\nimport { TREE_COLORS } from './constants';\nimport { isJavaScriptAsset } from '../../utils/assets';\nimport type {\n CallbackDataParams,\n ECElementEvent,\n} from 'echarts/types/dist/shared';\n\ntype TreeMapOption = ComposeOption<\n TreemapSeriesOption | TooltipComponentOption | TitleComponentOption\n>;\n\ntype TreemapDataNode = NonNullable<TreemapSeriesOption['data']>[number] & {\n path?: string;\n sourceSize?: number;\n bundledSize?: number;\n gzipSize?: number;\n moduleId?: string | number;\n};\n\necharts.use([TreemapChart, TooltipComponent, TitleComponent, CanvasRenderer]);\n\nexport type TreeNode = {\n name: string;\n value?: number;\n children?: TreeNode[];\n path?: string;\n sourceSize?: number;\n bundledSize?: number;\n gzipSize?: number;\n id?: string | number;\n};\n\nexport type SizeType = 'stat' | 'parsed' | 'gzip' | 'value';\n\ninterface TreeMapProps {\n treeData: TreeNode[];\n sizeType: SizeType;\n style?: React.CSSProperties;\n onChartClick?: (params: ECElementEvent) => void;\n highlightNodeId?: number;\n centerNodeId?: number;\n rootPath?: string;\n}\n\nfunction hashString(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) + hash + str.charCodeAt(i);\n }\n return hash >>> 0;\n}\n\nfunction blendWithWhite(hex: string, ratio: number): string {\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n\n const blendedR = Math.round(r * ratio + 255 * (1 - ratio));\n const blendedG = Math.round(g * ratio + 255 * (1 - ratio));\n const blendedB = Math.round(b * ratio + 255 * (1 - ratio));\n\n return `#${blendedR.toString(16).padStart(2, '0')}${blendedG.toString(16).padStart(2, '0')}${blendedB.toString(16).padStart(2, '0')}`;\n}\n\nfunction getLuminance(hex: string): number {\n const r = parseInt(hex.slice(1, 3), 16) / 255;\n const g = parseInt(hex.slice(3, 5), 16) / 255;\n const b = parseInt(hex.slice(5, 7), 16) / 255;\n\n const [rs, gs, bs] = [r, g, b].map((val) => {\n return val <= 0.03928 ? val / 12.92 : Math.pow((val + 0.055) / 1.055, 2.4);\n });\n\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n}\n\nfunction isDarkColor(hex: string): boolean {\n return getLuminance(hex) < 0.4;\n}\n\nfunction getLevelOption() {\n return [\n {\n itemStyle: {\n borderWidth: 0,\n gapWidth: 4,\n gapColor: '#ffffff',\n },\n },\n {\n itemStyle: {\n borderColorAlpha: [1, 0.3],\n borderWidth: 5,\n gapWidth: 4,\n gapColor: '#ffffff',\n },\n upperLabel: {\n show: true,\n color: '#ffffff',\n fontSize: 12,\n height: 30,\n },\n },\n ];\n}\n\nexport const TreeMap: React.FC<TreeMapProps> = memo(\n ({\n treeData,\n sizeType,\n style,\n onChartClick,\n highlightNodeId,\n centerNodeId,\n rootPath,\n }) => {\n const [option, setOption] = useState<TreeMapOption | null>(null);\n const chartRef = React.useRef<EChartsReactCore | null>(null);\n const chartDataRef = React.useRef<TreemapDataNode[]>([]);\n const clickTimeoutRef = React.useRef<number | null>(null);\n\n useEffect(() => {\n if (!treeData) return;\n function convert(\n node: TreeNode,\n index = 0,\n level = 0,\n parentColor?: string,\n siblingIndex = 0,\n siblingCount = 1,\n chunkPath?: string,\n ): TreemapDataNode {\n const baseColor =\n parentColor || TREE_COLORS[index % TREE_COLORS.length];\n\n // For level 0 (chunk level), use the chunk's path/name as chunkPath\n const currentChunkPath =\n level === 0 ? node.path || node.name || '' : chunkPath || '';\n\n const children = node.children?.map((c, childIndex) =>\n convert(\n c,\n index,\n level + 1,\n baseColor,\n childIndex,\n node.children?.length || 0,\n currentChunkPath,\n ),\n );\n\n let val = 0;\n if (sizeType === 'stat') val = node.sourceSize || 0;\n else if (sizeType === 'parsed') val = node.bundledSize || 0;\n else if (sizeType === 'gzip') val = node.gzipSize || 0;\n else if (sizeType === 'value') val = node.value || 0;\n\n // Include chunk path in nodeId for non-root nodes to ensure uniqueness across chunks\n const nodeIdString =\n level === 0\n ? node.path || node.name || ''\n : `${currentChunkPath}::${node.path || node.name || ''}`;\n const nodeId = hashString(nodeIdString);\n const isHighlighted = highlightNodeId === nodeId;\n\n const baseColorRatio =\n level === 0 ? 1 : Math.max(0.35, 1 - level * 0.15);\n const baseBorderRatio =\n level === 0 ? 1 : Math.max(0.4, 1 - level * 0.15);\n\n const siblingGradientRange = 0.15;\n const siblingRatio =\n siblingCount > 1\n ? 1 - (siblingIndex / (siblingCount - 1)) * siblingGradientRange\n : 1;\n\n const colorRatio = baseColorRatio * siblingRatio;\n const borderRatio = baseBorderRatio * siblingRatio;\n\n const nodeColor = isHighlighted\n ? '#fff5f5'\n : level === 0\n ? blendWithWhite(baseColor, 0.8)\n : blendWithWhite(baseColor, colorRatio);\n\n const nodeBorderColor = isHighlighted\n ? '#ff4d4f'\n : level === 0\n ? baseColor\n : blendWithWhite(baseColor, borderRatio);\n\n const isDark = isDarkColor(nodeColor);\n const textColor = isDark ? '#ffffff' : '#000000';\n const textBorderColor = isDark\n ? 'rgba(255, 255, 255, 0.2)'\n : 'rgba(0, 0, 0, 0.1)';\n\n const result: TreemapDataNode = {\n id: nodeId,\n name: node.name,\n value: val,\n path: node.path || node.name,\n sourceSize:\n node.sourceSize ?? (sizeType === 'stat' ? val : undefined),\n bundledSize:\n node.bundledSize ?? (sizeType === 'parsed' ? val : undefined),\n gzipSize: node.gzipSize ?? (sizeType === 'gzip' ? val : undefined),\n moduleId: node.id,\n itemStyle: {\n borderWidth: isHighlighted ? 4 : 1,\n color: nodeColor,\n borderColor: nodeBorderColor,\n ...(level === 0 && { gapWidth: 2 }),\n },\n label: {\n show: true,\n color: textColor,\n textBorderColor: textBorderColor,\n textBorderWidth: 1,\n },\n upperLabel:\n level === 0\n ? undefined\n : {\n show: true,\n color: textColor,\n },\n };\n\n if (children && children.length > 0) {\n result.children = children;\n }\n\n if (isHighlighted) {\n result.emphasis = {\n itemStyle: {\n borderColor: '#ff4d4f',\n borderWidth: 4,\n color: '#fff5f5',\n },\n };\n } else {\n // Keep the same color on hover/click to prevent color change\n result.emphasis = {\n itemStyle: {\n color: nodeColor,\n borderColor: nodeBorderColor,\n borderWidth: isHighlighted ? 4 : 1,\n },\n };\n }\n\n return result;\n }\n\n const data = treeData\n .map((item, index) =>\n convert(item, index, 0, undefined, index, treeData.length, undefined),\n )\n .filter(\n (item) =>\n (typeof item.value === 'number' ? item.value > 0 : false) ||\n (item.children && item.children.length > 0),\n );\n\n chartDataRef.current = data;\n\n setOption({\n color: TREE_COLORS,\n tooltip: {\n padding: 10,\n backgroundColor: '#fff',\n borderColor: '#eee',\n borderWidth: 1,\n textStyle: {\n color: 'rgba(0, 0, 0, 0.8)',\n },\n confine: true,\n extraCssText: 'max-width: 450px; word-wrap: break-word;',\n position: function (pos, _params, _dom, _rect, size) {\n const obj: { top: number; left?: number; right?: number } = {\n top: pos[1] + 10,\n };\n if (pos[0] < size.viewSize[0] / 2) {\n obj.left = pos[0] + 10;\n } else {\n obj.right = size.viewSize[0] - pos[0] + 10;\n }\n return obj;\n } as TooltipComponentOption['position'],\n formatter: function (\n info: CallbackDataParams & { data?: TreemapDataNode },\n ) {\n const node = info.data || {};\n let path =\n typeof node.path === 'string'\n ? node.path\n : typeof node.name === 'string'\n ? node.name\n : String(node.name ?? '');\n\n if (rootPath && path) {\n const normalizedRoot = rootPath\n .replace(/\\\\/g, '/')\n .replace(/\\/$/, '');\n const normalizedPath = path.replace(/\\\\/g, '/');\n if (normalizedPath.startsWith(normalizedRoot + '/')) {\n path = normalizedPath.slice(normalizedRoot.length + 1);\n } else if (normalizedPath === normalizedRoot) {\n path = '';\n }\n }\n\n const sourceSize =\n typeof node.sourceSize === 'number' && node.sourceSize > 0\n ? node.sourceSize\n : typeof node.value === 'number' &&\n node.value > 0 &&\n sizeType === 'stat'\n ? node.value\n : undefined;\n const bundledSize =\n typeof node.bundledSize === 'number' && node.bundledSize > 0\n ? node.bundledSize\n : undefined;\n const gzipSize =\n typeof node.gzipSize === 'number' && node.gzipSize > 0\n ? node.gzipSize\n : undefined;\n\n function makeRow(label: string, value: string, color: string) {\n return `<div class=\"${Styles['tooltip-row']}\">\n <span class=\"${Styles['tooltip-label']}\" style=\"color: ${color};\">${label}</span>\n <span style=\"color: ${color};\">${value}</span>\n </div>`;\n }\n\n const rows = [];\n if (sourceSize !== undefined && sourceSize > 0) {\n rows.push(\n makeRow('Stat size', formatSize(sourceSize), '#52c41a'),\n );\n }\n if (bundledSize !== undefined && bundledSize > 0) {\n rows.push(\n makeRow('Parsed size', formatSize(bundledSize), '#d96420'),\n );\n }\n if (gzipSize !== undefined && gzipSize > 0) {\n rows.push(\n makeRow('Gzipped size', formatSize(gzipSize), '#1677ff'),\n );\n }\n\n return `\n <div style=\"font-family: sans-serif; font-size: 12px; line-height: 1.5;\">\n <div style=\"margin-bottom: 6px; max-width: 400px; word-wrap: break-word; overflow-wrap: break-word; word-break: break-all; white-space: normal; color: rgba(0, 0, 0, 0.8);\">${echarts.format.encodeHTML(path)}</div>\n ${rows.join('')}\n </div>\n `;\n },\n } as TooltipComponentOption,\n series: [\n {\n type: 'treemap',\n itemStyle: {\n gapColor: '#ffffff',\n },\n label: {\n show: true,\n formatter: '{b}',\n fontSize: 12,\n position: 'inside',\n fontWeight: 'normal',\n textBorderWidth: 1,\n padding: [4, 8, 4, 8],\n },\n upperLabel: {\n show: true,\n height: 30,\n fontSize: 12,\n fontWeight: 'normal',\n padding: [0, 0, 0, 4],\n },\n levels: getLevelOption(),\n data: data,\n breadcrumb: {\n show: true,\n left: 'center',\n top: 'bottom',\n height: 22,\n emptyItemWidth: 25,\n itemStyle: {\n color: '#999',\n borderColor: 'transparent',\n borderWidth: 0,\n borderRadius: 0,\n },\n emphasis: {\n itemStyle: {\n color: '#333',\n },\n },\n textStyle: {\n fontFamily: 'sans-serif',\n fontSize: 12,\n color: '#666',\n },\n },\n roam: true,\n nodeClick: false,\n zoomToNodeRatio: 0.7,\n animationDurationUpdate: 500,\n width: '100%',\n height: '100%',\n top: -10,\n bottom: 30,\n left: 0,\n right: 0,\n zoomLimit: {\n min: 0.5,\n max: 5,\n },\n } as TreemapSeriesOption,\n ],\n });\n }, [treeData, sizeType, highlightNodeId, rootPath]);\n\n useEffect(() => {\n if (centerNodeId && chartRef.current && option) {\n const chartInstance =\n chartRef.current.getEchartsInstance() as unknown as EChartsType;\n if (chartInstance) {\n const findNodeInfo = (\n data: TreemapDataNode[],\n targetId: number,\n path: string[] = [],\n ): { name: string; path: string[] } | null => {\n for (const item of data) {\n const itemName =\n typeof item.name === 'string'\n ? item.name\n : String(item.name ?? '');\n const currentPath = [...path, itemName];\n if (item.id === targetId) {\n return { name: itemName, path: currentPath };\n }\n if (item.children) {\n const found = findNodeInfo(\n item.children,\n targetId,\n currentPath,\n );\n if (found) return found;\n }\n }\n return null;\n };\n\n setTimeout(() => {\n const nodeInfo = findNodeInfo(chartDataRef.current, centerNodeId);\n if (!nodeInfo) return;\n const nodeName = nodeInfo.name;\n\n try {\n chartInstance.dispatchAction({\n type: 'highlight',\n seriesIndex: 0,\n name: nodeName,\n });\n } catch (e) {\n console.error('Failed to highlight node with name:', nodeName, e);\n }\n\n const zoomStrategies: Array<() => void> = [\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n targetNodeId: String(centerNodeId),\n }),\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeName,\n }),\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeInfo.path.join('/'),\n }),\n () =>\n nodeInfo.path.length > 0 &&\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeInfo.path[nodeInfo.path.length - 1],\n }),\n ];\n\n for (const strategy of zoomStrategies) {\n try {\n strategy();\n return;\n } catch (e) {\n console.error(\n 'Failed to zoom to node with id:',\n centerNodeId,\n e,\n );\n }\n }\n\n console.warn('Failed to zoom to node with id:', centerNodeId);\n }, 200);\n }\n }\n }, [centerNodeId, option]);\n\n useEffect(() => {\n return () => {\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n }\n };\n }, []);\n\n return option ? (\n <div className={Styles['chart-container']} style={style}>\n <Alert\n message=\"If parsed size lacks detailed module information, you can enable sourceMap when RSDOCTOR = true. This is because Rsdoctor relies on SourceMap to obtain Parsed Size. Rspack provides SourceMap information to Rsdoctor by default without affecting the build output.\"\n type=\"info\"\n showIcon\n style={{ marginBottom: 0 }}\n />\n <EChartsReactCore\n ref={chartRef}\n option={option}\n echarts={echarts}\n onEvents={{\n click: (params: ECElementEvent) => {\n // Delay to differentiate from double-click; only zoom on single click\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n }\n clickTimeoutRef.current = window.setTimeout(() => {\n if (chartRef.current) {\n const instance =\n chartRef.current.getEchartsInstance() as unknown as EChartsType;\n const data = params?.data as TreemapDataNode | undefined;\n if (instance && data?.id !== undefined) {\n instance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n targetNodeId: String(data.id),\n });\n }\n }\n }, 180);\n },\n dblclick: (params: ECElementEvent) => {\n // Double click: cancel pending single-click action and trigger analyze\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n clickTimeoutRef.current = null;\n }\n onChartClick?.(params);\n },\n }}\n style={{\n width: '100%',\n height: '100%',\n }}\n />\n </div>\n ) : null;\n },\n);\n\nexport const AssetTreemapWithFilter: React.FC<{\n treeData: TreeNode[];\n onChartClick?: (params: ECElementEvent) => void;\n bundledSize?: boolean;\n}> = ({ treeData, onChartClick, bundledSize = true }) => {\n return (\n <ServerAPIProvider api={SDK.ServerAPI.API.GetProjectInfo}>\n {(projectInfo) => {\n return (\n <AssetTreemapWithFilterInner\n treeData={treeData}\n onChartClick={onChartClick}\n bundledSize={bundledSize}\n rootPath={projectInfo.root}\n />\n );\n }}\n </ServerAPIProvider>\n );\n};\n\nconst AssetTreemapWithFilterInner: React.FC<{\n treeData: TreeNode[];\n onChartClick?: (params: ECElementEvent) => void;\n bundledSize?: boolean;\n rootPath: string;\n}> = ({ treeData, onChartClick, bundledSize = true, rootPath }) => {\n const assetNames = useMemo(\n () => treeData.map((item) => item.name),\n [treeData],\n );\n\n const [checkedAssets, setCheckedAssets] = useState<string[]>(assetNames);\n const [collapsed, setCollapsed] = useState(false);\n const [sizeType, setSizeType] = useState<SizeType>(\n bundledSize ? 'parsed' : 'stat',\n );\n const [searchQuery, setSearchQuery] = useState('');\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [highlightNodeId, setHighlightNodeId] = useState<number | undefined>();\n const [centerNodeId, setCenterNodeId] = useState<number | undefined>();\n const [moduleId, setModuleId] = useState<string | number>('');\n const [showAnalyze, setShowAnalyze] = useState(false);\n const [chunkSearchQuery, setChunkSearchQuery] = useState('');\n const [showOnlyJavaScriptAssets, setShowOnlyJavaScriptAssets] =\n useState(false);\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n const visibleAssetNames = useMemo(() => {\n if (!showOnlyJavaScriptAssets) {\n return assetNames;\n }\n\n return assetNames.filter(isJavaScriptAsset);\n }, [assetNames, showOnlyJavaScriptAssets]);\n\n const visibleAssetNamesKey = useMemo(\n () => visibleAssetNames.join('\\0'),\n [visibleAssetNames],\n );\n const previousVisibleAssetNamesKeyRef = React.useRef<string | undefined>(\n undefined,\n );\n\n useEffect(() => {\n if (previousVisibleAssetNamesKeyRef.current === visibleAssetNamesKey) {\n return;\n }\n\n previousVisibleAssetNamesKeyRef.current = visibleAssetNamesKey;\n setCheckedAssets(visibleAssetNames);\n }, [visibleAssetNames, visibleAssetNamesKey]);\n\n const handleChartClick = useCallback(\n (params: ECElementEvent) => {\n onChartClick?.(params);\n const data = params.data as TreemapDataNode | undefined;\n const moduleId = data?.moduleId;\n if (moduleId !== undefined) {\n setModuleId(moduleId);\n setShowAnalyze(true);\n }\n },\n [onChartClick],\n );\n\n const enterFullscreen = useCallback(() => {\n if (containerRef.current) {\n const el = containerRef.current as HTMLElement & {\n webkitRequestFullscreen?: () => void;\n mozRequestFullScreen?: () => void;\n msRequestFullscreen?: () => void;\n };\n if (el.requestFullscreen) {\n el.requestFullscreen()\n .then(() => setIsFullscreen(true))\n .catch((err: unknown) =>\n console.error('Failed to enter fullscreen:', err),\n );\n } else if (el.webkitRequestFullscreen) {\n try {\n el.webkitRequestFullscreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (webkit):', err);\n }\n } else if (el.mozRequestFullScreen) {\n try {\n el.mozRequestFullScreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (moz):', err);\n }\n } else if (el.msRequestFullscreen) {\n try {\n el.msRequestFullscreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (ms):', err);\n }\n } else {\n console.error('Fullscreen API is not supported in this browser.');\n }\n }\n }, []);\n\n const exitFullscreen = useCallback(() => {\n document\n .exitFullscreen()\n .then(() => setIsFullscreen(false))\n .catch((err) => console.error('Failed to exit fullscreen:', err));\n }, []);\n\n const toggleFullscreen = useCallback(() => {\n if (isFullscreen) {\n exitFullscreen();\n } else {\n enterFullscreen();\n }\n }, [isFullscreen, enterFullscreen, exitFullscreen]);\n\n useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen(!!document.fullscreenElement);\n };\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => {\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\n };\n }, []);\n\n const filteredTreeData = useMemo(() => {\n let filtered = treeData.filter(\n (item) =>\n visibleAssetNames.includes(item.name) &&\n checkedAssets.includes(item.name),\n );\n\n if (chunkSearchQuery.trim()) {\n const searchLower = chunkSearchQuery.toLowerCase();\n filtered = filtered.filter((item) =>\n item.name.toLowerCase().includes(searchLower),\n );\n }\n\n return filtered;\n }, [treeData, checkedAssets, chunkSearchQuery, visibleAssetNames]);\n\n const searchResults = useMemo(() => {\n if (!searchQuery.trim()) return [];\n\n const regex = new RegExp(searchQuery, 'i');\n const results: Array<{ path: string; nodeId: number }> = [];\n\n const collectMatchingPaths = (node: TreeNode, chunkPath?: string) => {\n // For chunk level (root of filteredTreeData), use its path/name as chunkPath\n const currentChunkPath = chunkPath || node.path || node.name || '';\n\n if (node.path && regex.test(node.path)) {\n // Use the same nodeId calculation as in convert function\n const nodeIdString = chunkPath\n ? `${chunkPath}::${node.path}`\n : node.path;\n const nodeId = hashString(nodeIdString);\n results.push({ path: node.path, nodeId });\n }\n if (node.children) {\n node.children.forEach((child) =>\n collectMatchingPaths(child, currentChunkPath),\n );\n }\n };\n\n filteredTreeData.forEach((chunk) => collectMatchingPaths(chunk));\n return results;\n }, [filteredTreeData, searchQuery]);\n\n const handleSearchResultClick = useCallback((nodeId: number) => {\n setHighlightNodeId(nodeId);\n setCenterNodeId(nodeId);\n }, []);\n\n const removeRootPath = useCallback(\n (filepath: string): string => {\n if (!rootPath || !filepath) return filepath;\n const normalizedRoot = rootPath.replace(/\\\\/g, '/').replace(/\\/$/, '');\n const normalizedPath = filepath.replace(/\\\\/g, '/');\n\n if (normalizedPath.startsWith(normalizedRoot + '/')) {\n return normalizedPath.slice(normalizedRoot.length + 1);\n } else if (normalizedPath === normalizedRoot) {\n return '';\n }\n return filepath;\n },\n [rootPath],\n );\n\n const getSize = useCallback((node: TreeNode, type?: SizeType) => {\n if (type === 'stat') return node.sourceSize || 0;\n if (type === 'parsed') return node.bundledSize || 0;\n if (type === 'gzip') return node.gzipSize || 0;\n if (type === 'value') return node.value || 0;\n if (node.value) return node.value;\n return 0;\n }, []);\n\n const calculateNodeTotalSize = useCallback(\n (node: TreeNode, type: SizeType): number => {\n let size = getSize(node, type);\n\n if (node.children && node.children.length > 0) {\n const childrenSize = node.children.reduce(\n (sum, child) => sum + calculateNodeTotalSize(child, type),\n 0,\n );\n if (size === 0 || (!node.path && childrenSize > 0)) {\n size = childrenSize;\n }\n }\n\n return size;\n },\n [getSize],\n );\n\n const getChunkSize = useCallback(\n (name: string, type?: SizeType) => {\n const node = treeData.find((n) => n.name === name);\n if (!node) return 0;\n const sizeTypeToUse = type || sizeType;\n return calculateNodeTotalSize(node, sizeTypeToUse);\n },\n [treeData, sizeType, calculateNodeTotalSize],\n );\n\n return (\n <div className={Styles.treemap} ref={containerRef}>\n <button\n className={Styles['fullscreen-button']}\n onClick={toggleFullscreen}\n title={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n >\n {isFullscreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}\n </button>\n\n <div className={`${Styles.sidebar} ${collapsed ? Styles.collapsed : ''}`}>\n <div\n className={`${Styles['sidebar-toggle']} ${collapsed ? Styles.collapsed : ''}`}\n onClick={() => setCollapsed(!collapsed)}\n >\n {collapsed ? <RightOutlined /> : <LeftOutlined />}\n </div>\n <div className={Styles['sidebar-content']}>\n <div>\n <h4>Treemap sizes</h4>\n <Radio.Group\n value={sizeType}\n onChange={(e) => setSizeType(e.target.value)}\n size=\"small\"\n buttonStyle=\"solid\"\n >\n <Radio.Button value=\"stat\">Stat</Radio.Button>\n <Radio.Button value=\"parsed\">Parsed</Radio.Button>\n <Radio.Button value=\"gzip\">Gzipped</Radio.Button>\n </Radio.Group>\n </div>\n\n <div>\n <h4>Show chunks</h4>\n <Input\n placeholder=\"Search chunks\"\n value={chunkSearchQuery}\n onChange={(e) => setChunkSearchQuery(e.target.value)}\n suffix={<SearchOutlined style={{ color: '#ccc' }} />}\n allowClear\n size=\"small\"\n style={{ marginBottom: 8 }}\n />\n <Checkbox\n indeterminate={\n checkedAssets.length > 0 &&\n checkedAssets.length < visibleAssetNames.length\n }\n checked={\n visibleAssetNames.length > 0 &&\n checkedAssets.length === visibleAssetNames.length\n }\n onChange={(e) =>\n setCheckedAssets(e.target.checked ? visibleAssetNames : [])\n }\n className={Styles['all-none-checkbox']}\n >\n All\n </Checkbox>\n <Checkbox\n checked={showOnlyJavaScriptAssets}\n onChange={(e) => {\n setShowOnlyJavaScriptAssets(e.target.checked);\n }}\n className={Styles['all-none-checkbox']}\n >\n JS only\n </Checkbox>\n <div\n className={Styles['chunk-list']}\n style={{ maxHeight: 180, overflowY: 'auto' }}\n >\n {visibleAssetNames\n .filter((name) =>\n name.toLowerCase().includes(chunkSearchQuery.toLowerCase()),\n )\n .map((name) => (\n <div\n key={name}\n className={Styles['chunk-item']}\n style={{ height: 15, lineHeight: '15px' }}\n >\n <Checkbox\n checked={checkedAssets.includes(name)}\n onChange={(e) => {\n if (e.target.checked) {\n setCheckedAssets([...checkedAssets, name]);\n } else {\n setCheckedAssets(\n checkedAssets.filter((a) => a !== name),\n );\n }\n }}\n >\n <span title={name}>{name}</span>\n </Checkbox>\n <span className={Styles['size-tag']}>\n {formatSize(getChunkSize(name, sizeType))}\n </span>\n </div>\n ))}\n </div>\n </div>\n\n <div>\n <h4>Search modules</h4>\n <Input\n placeholder=\"Enter regexp\"\n value={searchQuery}\n onChange={(e) => {\n setSearchQuery(e.target.value);\n setHighlightNodeId(undefined);\n setCenterNodeId(undefined);\n }}\n suffix={<SearchOutlined style={{ color: '#ccc' }} />}\n allowClear\n size=\"small\"\n />\n {searchQuery.trim() && searchResults.length > 0 && (\n <div className={Styles['search-results']}>\n <div className={Styles['search-results-header']}>\n Found {searchResults.length} file\n {searchResults.length > 1 ? 's' : ''}\n </div>\n <div className={Styles['search-results-list']}>\n {searchResults.map((result, index) => {\n const displayPath = removeRootPath(result.path);\n return (\n <div\n key={index}\n className={Styles['search-result-item']}\n onClick={() => handleSearchResultClick(result.nodeId)}\n title={result.path}\n >\n {displayPath || result.path}\n </div>\n );\n })}\n </div>\n </div>\n )}\n {searchQuery.trim() && searchResults.length === 0 && (\n <div className={Styles['search-results-empty']}>\n No files found matching \"{searchQuery}\"\n </div>\n )}\n </div>\n </div>\n </div>\n\n <div className={Styles['chart-wrapper']}>\n <TreeMap\n treeData={filteredTreeData}\n sizeType={sizeType}\n onChartClick={handleChartClick}\n highlightNodeId={highlightNodeId}\n centerNodeId={centerNodeId}\n rootPath={rootPath}\n style={{ width: '100%', height: '100%' }}\n />\n {moduleId ? (\n <ServerAPIProvider\n api={SDK.ServerAPI.API.GetAllModuleGraph}\n body={{}}\n >\n {(modules) => (\n <ModuleAnalyzeComponent\n cwd={rootPath}\n moduleId={moduleId}\n modules={modules}\n show={showAnalyze}\n setShow={setShowAnalyze}\n />\n )}\n </ServerAPIProvider>\n ) : null}\n </div>\n </div>\n );\n};\n"],"names":["echarts","TreemapChart","TooltipComponent","TitleComponent","CanvasRenderer","hashString","str","hash","i","blendWithWhite","hex","ratio","r","parseInt","g","b","blendedR","Math","blendedG","blendedB","getLuminance","rs","gs","bs","val","isDarkColor","getLevelOption","TreeMap","memo","treeData","sizeType","style","onChartClick","highlightNodeId","centerNodeId","rootPath","option","setOption","useState","chartRef","React","chartDataRef","clickTimeoutRef","useEffect","convert","node","index","level","parentColor","siblingIndex","siblingCount","chunkPath","baseColor","TREE_COLORS","currentChunkPath","children","c","childIndex","nodeIdString","nodeId","isHighlighted","baseColorRatio","baseBorderRatio","siblingGradientRange","siblingRatio","colorRatio","borderRatio","nodeColor","nodeBorderColor","isDark","textColor","textBorderColor","result","undefined","data","item","pos","_params","_dom","_rect","size","obj","info","path","String","normalizedRoot","normalizedPath","sourceSize","bundledSize","gzipSize","makeRow","label","value","color","Styles","rows","formatSize","chartInstance","findNodeInfo","targetId","itemName","currentPath","found","setTimeout","nodeInfo","nodeName","e","console","zoomStrategies","strategy","window","Alert","EChartsReactCore","params","instance","AssetTreemapWithFilter","ServerAPIProvider","SDK","projectInfo","AssetTreemapWithFilterInner","assetNames","useMemo","checkedAssets","setCheckedAssets","collapsed","setCollapsed","setSizeType","searchQuery","setSearchQuery","isFullscreen","setIsFullscreen","setHighlightNodeId","setCenterNodeId","moduleId","setModuleId","showAnalyze","setShowAnalyze","chunkSearchQuery","setChunkSearchQuery","showOnlyJavaScriptAssets","setShowOnlyJavaScriptAssets","containerRef","visibleAssetNames","isJavaScriptAsset","visibleAssetNamesKey","previousVisibleAssetNamesKeyRef","handleChartClick","useCallback","enterFullscreen","el","err","exitFullscreen","document","toggleFullscreen","handleFullscreenChange","filteredTreeData","filtered","searchLower","searchResults","regex","RegExp","results","collectMatchingPaths","child","chunk","handleSearchResultClick","removeRootPath","filepath","getSize","type","calculateNodeTotalSize","childrenSize","sum","getChunkSize","name","n","sizeTypeToUse","FullscreenExitOutlined","FullscreenOutlined","RightOutlined","LeftOutlined","Radio","Input","SearchOutlined","Checkbox","a","displayPath","modules","ModuleAnalyzeComponent"],"mappings":"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"}
1
+ {"version":3,"file":"components/Charts/TreeMap.mjs","sources":["../../../src/components/Charts/TreeMap.tsx"],"sourcesContent":["import React, { useEffect, useState, memo, useMemo, useCallback } from 'react';\nimport EChartsReactCore from 'echarts-for-react/esm/core';\nimport * as echarts from 'echarts/core';\nimport { TreemapChart, type TreemapSeriesOption } from 'echarts/charts';\nimport {\n TooltipComponent,\n TitleComponent,\n type TooltipComponentOption,\n type TitleComponentOption,\n} from 'echarts/components';\nimport { CanvasRenderer } from 'echarts/renderers';\nimport { Alert, Checkbox, Radio, Input } from 'antd';\nimport {\n LeftOutlined,\n RightOutlined,\n SearchOutlined,\n FullscreenOutlined,\n FullscreenExitOutlined,\n} from '@ant-design/icons';\nimport type { ComposeOption, EChartsType } from 'echarts/core';\nimport { formatSize, useThemeToken } from 'src/utils';\nimport { SDK } from '@rsdoctor/types';\nimport { ServerAPIProvider } from 'src/components/Manifest';\nimport { ModuleAnalyzeComponent } from '../../pages/ModuleAnalyze';\nimport Styles from './treemap.module.scss';\nimport { TREE_COLORS } from './constants';\nimport { isJavaScriptAsset } from '../../utils/assets';\nimport type {\n CallbackDataParams,\n ECElementEvent,\n} from 'echarts/types/dist/shared';\n\ntype TreeMapOption = ComposeOption<\n TreemapSeriesOption | TooltipComponentOption | TitleComponentOption\n>;\n\ntype TreemapDataNode = NonNullable<TreemapSeriesOption['data']>[number] & {\n path?: string;\n sourceSize?: number;\n bundledSize?: number;\n gzipSize?: number;\n moduleId?: string | number;\n};\n\necharts.use([TreemapChart, TooltipComponent, TitleComponent, CanvasRenderer]);\n\nexport type TreeNode = {\n name: string;\n value?: number;\n children?: TreeNode[];\n path?: string;\n sourceSize?: number;\n bundledSize?: number;\n gzipSize?: number;\n id?: string | number;\n};\n\nexport type SizeType = 'stat' | 'parsed' | 'gzip' | 'value';\n\ninterface TreeMapProps {\n treeData: TreeNode[];\n sizeType: SizeType;\n style?: React.CSSProperties;\n onChartClick?: (params: ECElementEvent) => void;\n highlightNodeId?: number;\n centerNodeId?: number;\n rootPath?: string;\n}\n\nfunction hashString(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) + hash + str.charCodeAt(i);\n }\n return hash >>> 0;\n}\n\nfunction blendWithWhite(hex: string, ratio: number): string {\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n\n const blendedR = Math.round(r * ratio + 255 * (1 - ratio));\n const blendedG = Math.round(g * ratio + 255 * (1 - ratio));\n const blendedB = Math.round(b * ratio + 255 * (1 - ratio));\n\n return `#${blendedR.toString(16).padStart(2, '0')}${blendedG.toString(16).padStart(2, '0')}${blendedB.toString(16).padStart(2, '0')}`;\n}\n\nfunction getLuminance(hex: string): number {\n const r = parseInt(hex.slice(1, 3), 16) / 255;\n const g = parseInt(hex.slice(3, 5), 16) / 255;\n const b = parseInt(hex.slice(5, 7), 16) / 255;\n\n const [rs, gs, bs] = [r, g, b].map((val) => {\n return val <= 0.03928 ? val / 12.92 : Math.pow((val + 0.055) / 1.055, 2.4);\n });\n\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n}\n\nfunction isDarkColor(hex: string): boolean {\n return getLuminance(hex) < 0.4;\n}\n\nfunction getLevelOption() {\n return [\n {\n itemStyle: {\n borderWidth: 0,\n gapWidth: 4,\n gapColor: '#ffffff',\n },\n },\n {\n itemStyle: {\n borderColorAlpha: [1, 0.3],\n borderWidth: 5,\n gapWidth: 4,\n gapColor: '#ffffff',\n },\n upperLabel: {\n show: true,\n color: '#ffffff',\n fontSize: 12,\n height: 30,\n },\n },\n ];\n}\n\nexport const TreeMap: React.FC<TreeMapProps> = memo(\n ({\n treeData,\n sizeType,\n onChartClick,\n highlightNodeId,\n centerNodeId,\n rootPath,\n }) => {\n const [option, setOption] = useState<TreeMapOption | null>(null);\n const chartRef = React.useRef<EChartsReactCore | null>(null);\n const chartDataRef = React.useRef<TreemapDataNode[]>([]);\n const clickTimeoutRef = React.useRef<number | null>(null);\n const themeToken = useThemeToken();\n\n useEffect(() => {\n if (!treeData) return;\n function convert(\n node: TreeNode,\n index = 0,\n level = 0,\n parentColor?: string,\n siblingIndex = 0,\n siblingCount = 1,\n chunkPath?: string,\n ): TreemapDataNode {\n const baseColor =\n parentColor || TREE_COLORS[index % TREE_COLORS.length];\n\n // For level 0 (chunk level), use the chunk's path/name as chunkPath\n const currentChunkPath =\n level === 0 ? node.path || node.name || '' : chunkPath || '';\n\n const children = node.children?.map((c, childIndex) =>\n convert(\n c,\n index,\n level + 1,\n baseColor,\n childIndex,\n node.children?.length || 0,\n currentChunkPath,\n ),\n );\n\n let val = 0;\n if (sizeType === 'stat') val = node.sourceSize || 0;\n else if (sizeType === 'parsed') val = node.bundledSize || 0;\n else if (sizeType === 'gzip') val = node.gzipSize || 0;\n else if (sizeType === 'value') val = node.value || 0;\n\n // Include chunk path in nodeId for non-root nodes to ensure uniqueness across chunks\n const nodeIdString =\n level === 0\n ? node.path || node.name || ''\n : `${currentChunkPath}::${node.path || node.name || ''}`;\n const nodeId = hashString(nodeIdString);\n const isHighlighted = highlightNodeId === nodeId;\n\n const baseColorRatio =\n level === 0 ? 1 : Math.max(0.35, 1 - level * 0.15);\n const baseBorderRatio =\n level === 0 ? 1 : Math.max(0.4, 1 - level * 0.15);\n\n const siblingGradientRange = 0.15;\n const siblingRatio =\n siblingCount > 1\n ? 1 - (siblingIndex / (siblingCount - 1)) * siblingGradientRange\n : 1;\n\n const colorRatio = baseColorRatio * siblingRatio;\n const borderRatio = baseBorderRatio * siblingRatio;\n\n const nodeColor = isHighlighted\n ? '#fff5f5'\n : level === 0\n ? blendWithWhite(baseColor, 0.8)\n : blendWithWhite(baseColor, colorRatio);\n\n const nodeBorderColor = isHighlighted\n ? '#ff4d4f'\n : level === 0\n ? baseColor\n : blendWithWhite(baseColor, borderRatio);\n\n const isDark = isDarkColor(nodeColor);\n const textColor = isDark ? '#ffffff' : '#000000';\n const textBorderColor = isDark\n ? 'rgba(255, 255, 255, 0.2)'\n : 'rgba(0, 0, 0, 0.1)';\n\n const result: TreemapDataNode = {\n id: nodeId,\n name: node.name,\n value: val,\n path: node.path || node.name,\n sourceSize:\n node.sourceSize ?? (sizeType === 'stat' ? val : undefined),\n bundledSize:\n node.bundledSize ?? (sizeType === 'parsed' ? val : undefined),\n gzipSize: node.gzipSize ?? (sizeType === 'gzip' ? val : undefined),\n moduleId: node.id,\n itemStyle: {\n borderWidth: isHighlighted ? 4 : 1,\n color: nodeColor,\n borderColor: nodeBorderColor,\n ...(level === 0 && { gapWidth: 2 }),\n },\n label: {\n show: true,\n color: textColor,\n textBorderColor: textBorderColor,\n textBorderWidth: 1,\n },\n upperLabel:\n level === 0\n ? undefined\n : {\n show: true,\n color: textColor,\n },\n };\n\n if (children && children.length > 0) {\n result.children = children;\n }\n\n if (isHighlighted) {\n result.emphasis = {\n itemStyle: {\n borderColor: '#ff4d4f',\n borderWidth: 4,\n color: '#fff5f5',\n },\n };\n } else {\n // Keep the same color on hover/click to prevent color change\n result.emphasis = {\n itemStyle: {\n color: nodeColor,\n borderColor: nodeBorderColor,\n borderWidth: isHighlighted ? 4 : 1,\n },\n };\n }\n\n return result;\n }\n\n const data = treeData\n .map((item, index) =>\n convert(item, index, 0, undefined, index, treeData.length, undefined),\n )\n .filter(\n (item) =>\n (typeof item.value === 'number' ? item.value > 0 : false) ||\n (item.children && item.children.length > 0),\n );\n\n chartDataRef.current = data;\n\n const textColor = themeToken.colorText;\n setOption({\n color: TREE_COLORS,\n tooltip: {\n padding: 10,\n backgroundColor: themeToken.colorBgElevated,\n borderColor: themeToken.colorBorder,\n borderWidth: 1,\n textStyle: {\n color: textColor,\n },\n confine: true,\n extraCssText: 'max-width: 450px; word-wrap: break-word;',\n position: function (pos, _params, _dom, _rect, size) {\n const obj: { top: number; left?: number; right?: number } = {\n top: pos[1] + 10,\n };\n if (pos[0] < size.viewSize[0] / 2) {\n obj.left = pos[0] + 10;\n } else {\n obj.right = size.viewSize[0] - pos[0] + 10;\n }\n return obj;\n },\n formatter: function (info) {\n const node =\n (info as CallbackDataParams & { data?: TreemapDataNode }).data ||\n {};\n let path =\n typeof node.path === 'string'\n ? node.path\n : typeof node.name === 'string'\n ? node.name\n : String(node.name ?? '');\n\n if (rootPath && path) {\n const normalizedRoot = rootPath\n .replace(/\\\\/g, '/')\n .replace(/\\/$/, '');\n const normalizedPath = path.replace(/\\\\/g, '/');\n if (normalizedPath.startsWith(normalizedRoot + '/')) {\n path = normalizedPath.slice(normalizedRoot.length + 1);\n } else if (normalizedPath === normalizedRoot) {\n path = '';\n }\n }\n\n const sourceSize =\n typeof node.sourceSize === 'number' && node.sourceSize > 0\n ? node.sourceSize\n : typeof node.value === 'number' &&\n node.value > 0 &&\n sizeType === 'stat'\n ? node.value\n : undefined;\n const bundledSize =\n typeof node.bundledSize === 'number' && node.bundledSize > 0\n ? node.bundledSize\n : undefined;\n const gzipSize =\n typeof node.gzipSize === 'number' && node.gzipSize > 0\n ? node.gzipSize\n : undefined;\n\n function makeRow(label: string, value: string, color: string) {\n return `<div class=\"${Styles['tooltip-row']}\">\n <span class=\"${Styles['tooltip-label']}\" style=\"color: ${color};\">${label}</span>\n <span style=\"color: ${color};\">${value}</span>\n </div>`;\n }\n\n const rows = [];\n if (sourceSize !== undefined && sourceSize > 0) {\n rows.push(\n makeRow('Stat size', formatSize(sourceSize), '#52c41a'),\n );\n }\n if (bundledSize !== undefined && bundledSize > 0) {\n rows.push(\n makeRow('Parsed size', formatSize(bundledSize), '#d96420'),\n );\n }\n if (gzipSize !== undefined && gzipSize > 0) {\n rows.push(\n makeRow('Gzipped size', formatSize(gzipSize), '#1677ff'),\n );\n }\n\n return `\n <div style=\"font-family: sans-serif; font-size: 12px; line-height: 1.5;\">\n <div style=\"margin-bottom: 6px; max-width: 400px; word-wrap: break-word; overflow-wrap: break-word; word-break: break-all; white-space: normal; color: ${textColor};\">${echarts.format.encodeHTML(path)}</div>\n ${rows.join('')}\n </div>\n `;\n },\n },\n series: [\n {\n type: 'treemap',\n label: {\n show: true,\n formatter: '{b}',\n fontSize: 12,\n position: 'inside',\n fontWeight: 'normal',\n textBorderWidth: 1,\n padding: [4, 8, 4, 8],\n },\n upperLabel: {\n show: true,\n height: 30,\n fontSize: 12,\n fontWeight: 'normal',\n padding: [0, 0, 0, 4],\n },\n levels: getLevelOption(),\n data: data,\n breadcrumb: {\n show: true,\n left: 'center',\n top: 'bottom',\n height: 22,\n emptyItemWidth: 25,\n itemStyle: {\n color: '#999',\n borderColor: 'transparent',\n borderWidth: 0,\n borderRadius: 0,\n textStyle: {\n fontFamily: 'sans-serif',\n fontSize: 12,\n color: 'white',\n },\n },\n emphasis: {\n itemStyle: {\n color: '#333',\n },\n },\n },\n roam: true,\n nodeClick: false,\n zoomToNodeRatio: 0.7,\n animationDurationUpdate: 500,\n width: '100%',\n height: '100%',\n top: -10,\n bottom: 30,\n left: 0,\n right: 0,\n scaleLimit: {\n min: 0.5,\n max: 5,\n },\n },\n ],\n });\n }, [treeData, sizeType, highlightNodeId, rootPath, themeToken]);\n\n useEffect(() => {\n if (centerNodeId && chartRef.current && option) {\n const chartInstance =\n chartRef.current.getEchartsInstance() as unknown as EChartsType;\n if (chartInstance) {\n const findNodeInfo = (\n data: TreemapDataNode[],\n targetId: number,\n path: string[] = [],\n ): { name: string; path: string[] } | null => {\n for (const item of data) {\n const itemName =\n typeof item.name === 'string'\n ? item.name\n : String(item.name ?? '');\n const currentPath = [...path, itemName];\n if (item.id === targetId) {\n return { name: itemName, path: currentPath };\n }\n if (item.children) {\n const found = findNodeInfo(\n item.children,\n targetId,\n currentPath,\n );\n if (found) return found;\n }\n }\n return null;\n };\n\n setTimeout(() => {\n const nodeInfo = findNodeInfo(chartDataRef.current, centerNodeId);\n if (!nodeInfo) return;\n const nodeName = nodeInfo.name;\n\n try {\n chartInstance.dispatchAction({\n type: 'highlight',\n seriesIndex: 0,\n name: nodeName,\n });\n } catch (e) {\n console.error('Failed to highlight node with name:', nodeName, e);\n }\n\n const zoomStrategies: Array<() => void> = [\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n targetNodeId: String(centerNodeId),\n }),\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeName,\n }),\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeInfo.path.join('/'),\n }),\n () =>\n nodeInfo.path.length > 0 &&\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeInfo.path[nodeInfo.path.length - 1],\n }),\n ];\n\n for (const strategy of zoomStrategies) {\n try {\n strategy();\n return;\n } catch (e) {\n console.error(\n 'Failed to zoom to node with id:',\n centerNodeId,\n e,\n );\n }\n }\n\n console.warn('Failed to zoom to node with id:', centerNodeId);\n }, 200);\n }\n }\n }, [centerNodeId, option]);\n\n useEffect(() => {\n return () => {\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n }\n };\n }, []);\n\n return option ? (\n <div className={Styles['chart-container']}>\n <Alert\n message=\"If parsed size lacks detailed module information, you can enable sourceMap when RSDOCTOR = true. This is because Rsdoctor relies on SourceMap to obtain Parsed Size. Rspack provides SourceMap information to Rsdoctor by default without affecting the build output.\"\n type=\"info\"\n showIcon\n style={{ marginBottom: 0 }}\n />\n <div\n style={{\n flex: 1,\n }}\n >\n <EChartsReactCore\n ref={chartRef}\n option={option}\n echarts={echarts}\n onEvents={{\n click: (params: ECElementEvent) => {\n // Delay to differentiate from double-click; only zoom on single click\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n }\n clickTimeoutRef.current = window.setTimeout(() => {\n if (chartRef.current) {\n const instance =\n chartRef.current.getEchartsInstance() as unknown as EChartsType;\n const data = params?.data as TreemapDataNode | undefined;\n if (instance && data?.id !== undefined) {\n instance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n targetNodeId: String(data.id),\n });\n }\n }\n }, 180);\n },\n dblclick: (params: ECElementEvent) => {\n // Double click: cancel pending single-click action and trigger analyze\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n clickTimeoutRef.current = null;\n }\n onChartClick?.(params);\n },\n }}\n style={{\n width: '100%',\n height: '100%',\n }}\n />\n </div>\n </div>\n ) : null;\n },\n);\n\nexport const AssetTreemapWithFilter: React.FC<{\n treeData: TreeNode[];\n onChartClick?: (params: ECElementEvent) => void;\n bundledSize?: boolean;\n}> = ({ treeData, onChartClick, bundledSize = true }) => {\n return (\n <ServerAPIProvider api={SDK.ServerAPI.API.GetProjectInfo}>\n {(projectInfo) => {\n return (\n <AssetTreemapWithFilterInner\n treeData={treeData}\n onChartClick={onChartClick}\n bundledSize={bundledSize}\n rootPath={projectInfo.root}\n />\n );\n }}\n </ServerAPIProvider>\n );\n};\n\nconst AssetTreemapWithFilterInner: React.FC<{\n treeData: TreeNode[];\n onChartClick?: (params: ECElementEvent) => void;\n bundledSize?: boolean;\n rootPath: string;\n}> = ({ treeData, onChartClick, bundledSize = true, rootPath }) => {\n const assetNames = useMemo(\n () => treeData.map((item) => item.name),\n [treeData],\n );\n\n const [checkedAssets, setCheckedAssets] = useState<string[]>(assetNames);\n const [collapsed, setCollapsed] = useState(false);\n const [sizeType, setSizeType] = useState<SizeType>(\n bundledSize ? 'parsed' : 'stat',\n );\n const [searchQuery, setSearchQuery] = useState('');\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [highlightNodeId, setHighlightNodeId] = useState<number | undefined>();\n const [centerNodeId, setCenterNodeId] = useState<number | undefined>();\n const [moduleId, setModuleId] = useState<string | number>('');\n const [showAnalyze, setShowAnalyze] = useState(false);\n const [chunkSearchQuery, setChunkSearchQuery] = useState('');\n const [showOnlyJavaScriptAssets, setShowOnlyJavaScriptAssets] =\n useState(false);\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n const visibleAssetNames = useMemo(() => {\n if (!showOnlyJavaScriptAssets) {\n return assetNames;\n }\n\n return assetNames.filter(isJavaScriptAsset);\n }, [assetNames, showOnlyJavaScriptAssets]);\n\n const visibleAssetNamesKey = useMemo(\n () => visibleAssetNames.join('\\0'),\n [visibleAssetNames],\n );\n const previousVisibleAssetNamesKeyRef = React.useRef<string | undefined>(\n undefined,\n );\n\n useEffect(() => {\n if (previousVisibleAssetNamesKeyRef.current === visibleAssetNamesKey) {\n return;\n }\n\n previousVisibleAssetNamesKeyRef.current = visibleAssetNamesKey;\n setCheckedAssets(visibleAssetNames);\n }, [visibleAssetNames, visibleAssetNamesKey]);\n\n const handleChartClick = useCallback(\n (params: ECElementEvent) => {\n onChartClick?.(params);\n const data = params.data as TreemapDataNode | undefined;\n const moduleId = data?.moduleId;\n if (moduleId !== undefined) {\n setModuleId(moduleId);\n setShowAnalyze(true);\n }\n },\n [onChartClick],\n );\n\n const enterFullscreen = () => {\n if (!containerRef.current) return;\n const el = containerRef.current as HTMLElement & {\n webkitRequestFullscreen?: () => void;\n mozRequestFullScreen?: () => void;\n msRequestFullscreen?: () => void;\n };\n if (el.requestFullscreen) {\n el.requestFullscreen()\n .then(() => setIsFullscreen(true))\n .catch((err: unknown) =>\n console.error('Failed to enter fullscreen:', err),\n );\n } else if (el.webkitRequestFullscreen) {\n try {\n el.webkitRequestFullscreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (webkit):', err);\n }\n } else if (el.mozRequestFullScreen) {\n try {\n el.mozRequestFullScreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (moz):', err);\n }\n } else if (el.msRequestFullscreen) {\n try {\n el.msRequestFullscreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (ms):', err);\n }\n } else {\n console.error('Fullscreen API is not supported in this browser.');\n }\n };\n\n const exitFullscreen = () => {\n document\n .exitFullscreen()\n .then(() => setIsFullscreen(false))\n .catch((err) => console.error('Failed to exit fullscreen:', err));\n };\n\n const toggleFullscreen = () => {\n if (isFullscreen) {\n exitFullscreen();\n } else {\n enterFullscreen();\n }\n };\n\n useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen(!!document.fullscreenElement);\n };\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => {\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\n };\n }, []);\n\n const filteredTreeData = useMemo(() => {\n let filtered = treeData.filter(\n (item) =>\n visibleAssetNames.includes(item.name) &&\n checkedAssets.includes(item.name),\n );\n\n if (chunkSearchQuery.trim()) {\n const searchLower = chunkSearchQuery.toLowerCase();\n filtered = filtered.filter((item) =>\n item.name.toLowerCase().includes(searchLower),\n );\n }\n\n return filtered;\n }, [treeData, checkedAssets, chunkSearchQuery, visibleAssetNames]);\n\n const searchResults = useMemo(() => {\n if (!searchQuery.trim()) return [];\n\n const regex = new RegExp(searchQuery, 'i');\n const results: Array<{ path: string; nodeId: number }> = [];\n\n const collectMatchingPaths = (node: TreeNode, chunkPath?: string) => {\n // For chunk level (root of filteredTreeData), use its path/name as chunkPath\n const currentChunkPath = chunkPath || node.path || node.name || '';\n\n if (node.path && regex.test(node.path)) {\n // Use the same nodeId calculation as in convert function\n const nodeIdString = chunkPath\n ? `${chunkPath}::${node.path}`\n : node.path;\n const nodeId = hashString(nodeIdString);\n results.push({ path: node.path, nodeId });\n }\n if (node.children) {\n node.children.forEach((child) =>\n collectMatchingPaths(child, currentChunkPath),\n );\n }\n };\n\n filteredTreeData.forEach((chunk) => collectMatchingPaths(chunk));\n return results;\n }, [filteredTreeData, searchQuery]);\n\n const handleSearchResultClick = (nodeId: number) => {\n setHighlightNodeId(nodeId);\n setCenterNodeId(nodeId);\n };\n\n const removeRootPath = (filepath: string): string => {\n if (!rootPath || !filepath) return filepath;\n const normalizedRoot = rootPath.replace(/\\\\/g, '/').replace(/\\/$/, '');\n const normalizedPath = filepath.replace(/\\\\/g, '/');\n\n if (normalizedPath.startsWith(normalizedRoot + '/')) {\n return normalizedPath.slice(normalizedRoot.length + 1);\n } else if (normalizedPath === normalizedRoot) {\n return '';\n }\n return filepath;\n };\n\n const getSize = (node: TreeNode, type?: SizeType) => {\n if (type === 'stat') return node.sourceSize || 0;\n if (type === 'parsed') return node.bundledSize || 0;\n if (type === 'gzip') return node.gzipSize || 0;\n if (type === 'value') return node.value || 0;\n if (node.value) return node.value;\n return 0;\n };\n\n const calculateNodeTotalSize = (node: TreeNode, type: SizeType): number => {\n let size = getSize(node, type);\n\n if (node.children && node.children.length > 0) {\n const childrenSize = node.children.reduce(\n (sum, child) => sum + calculateNodeTotalSize(child, type),\n 0,\n );\n if (size === 0 || (!node.path && childrenSize > 0)) {\n size = childrenSize;\n }\n }\n\n return size;\n };\n\n const getChunkSize = (name: string, type?: SizeType) => {\n const node = treeData.find((n) => n.name === name);\n if (!node) return 0;\n const sizeTypeToUse = type || sizeType;\n return calculateNodeTotalSize(node, sizeTypeToUse);\n };\n\n return (\n <div className={Styles.treemap} ref={containerRef}>\n <button\n className={Styles['fullscreen-button']}\n onClick={toggleFullscreen}\n title={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n >\n {isFullscreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}\n </button>\n\n <div className={`${Styles.sidebar} ${collapsed ? Styles.collapsed : ''}`}>\n <div\n className={`${Styles['sidebar-toggle']} ${collapsed ? Styles.collapsed : ''}`}\n onClick={() => setCollapsed(!collapsed)}\n >\n {collapsed ? <RightOutlined /> : <LeftOutlined />}\n </div>\n <div className={Styles['sidebar-content']}>\n <div>\n <h4>Treemap sizes</h4>\n <Radio.Group\n value={sizeType}\n onChange={(e) => setSizeType(e.target.value)}\n size=\"small\"\n buttonStyle=\"solid\"\n >\n <Radio.Button value=\"stat\">Stat</Radio.Button>\n <Radio.Button value=\"parsed\">Parsed</Radio.Button>\n <Radio.Button value=\"gzip\">Gzipped</Radio.Button>\n </Radio.Group>\n </div>\n\n <div>\n <h4>Show chunks</h4>\n <Input\n placeholder=\"Search chunks\"\n value={chunkSearchQuery}\n onChange={(e) => setChunkSearchQuery(e.target.value)}\n suffix={<SearchOutlined style={{ color: '#ccc' }} />}\n allowClear\n size=\"small\"\n style={{ marginBottom: 8 }}\n />\n <Checkbox\n indeterminate={\n checkedAssets.length > 0 &&\n checkedAssets.length < visibleAssetNames.length\n }\n checked={\n visibleAssetNames.length > 0 &&\n checkedAssets.length === visibleAssetNames.length\n }\n onChange={(e) =>\n setCheckedAssets(e.target.checked ? visibleAssetNames : [])\n }\n className={Styles['all-none-checkbox']}\n >\n All\n </Checkbox>\n <Checkbox\n checked={showOnlyJavaScriptAssets}\n onChange={(e) => {\n setShowOnlyJavaScriptAssets(e.target.checked);\n }}\n className={Styles['all-none-checkbox']}\n >\n JS only\n </Checkbox>\n <div\n className={Styles['chunk-list']}\n style={{ maxHeight: 180, overflowY: 'auto' }}\n >\n {visibleAssetNames\n .filter((name) =>\n name.toLowerCase().includes(chunkSearchQuery.toLowerCase()),\n )\n .map((name) => (\n <div\n key={name}\n className={Styles['chunk-item']}\n style={{ height: 15, lineHeight: '15px' }}\n >\n <Checkbox\n checked={checkedAssets.includes(name)}\n onChange={(e) => {\n if (e.target.checked) {\n setCheckedAssets([...checkedAssets, name]);\n } else {\n setCheckedAssets(\n checkedAssets.filter((a) => a !== name),\n );\n }\n }}\n >\n <span title={name}>{name}</span>\n </Checkbox>\n <span className={Styles['size-tag']}>\n {formatSize(getChunkSize(name, sizeType))}\n </span>\n </div>\n ))}\n </div>\n </div>\n\n <div>\n <h4>Search modules</h4>\n <Input\n placeholder=\"Enter regexp\"\n value={searchQuery}\n onChange={(e) => {\n setSearchQuery(e.target.value);\n setHighlightNodeId(undefined);\n setCenterNodeId(undefined);\n }}\n suffix={<SearchOutlined style={{ color: '#ccc' }} />}\n allowClear\n size=\"small\"\n />\n {searchQuery.trim() && searchResults.length > 0 && (\n <div className={Styles['search-results']}>\n <div className={Styles['search-results-header']}>\n Found {searchResults.length} file\n {searchResults.length > 1 ? 's' : ''}\n </div>\n <div className={Styles['search-results-list']}>\n {searchResults.map((result, index) => {\n const displayPath = removeRootPath(result.path);\n return (\n <div\n key={index}\n className={Styles['search-result-item']}\n onClick={() => handleSearchResultClick(result.nodeId)}\n title={result.path}\n >\n {displayPath || result.path}\n </div>\n );\n })}\n </div>\n </div>\n )}\n {searchQuery.trim() && searchResults.length === 0 && (\n <div className={Styles['search-results-empty']}>\n No files found matching \"{searchQuery}\"\n </div>\n )}\n </div>\n </div>\n </div>\n\n <div className={Styles['chart-wrapper']}>\n <TreeMap\n treeData={filteredTreeData}\n sizeType={sizeType}\n onChartClick={handleChartClick}\n highlightNodeId={highlightNodeId}\n centerNodeId={centerNodeId}\n rootPath={rootPath}\n />\n {moduleId ? (\n <ServerAPIProvider\n api={SDK.ServerAPI.API.GetAllModuleGraph}\n body={{}}\n >\n {(modules) => (\n <ModuleAnalyzeComponent\n cwd={rootPath}\n moduleId={moduleId}\n modules={modules}\n show={showAnalyze}\n setShow={setShowAnalyze}\n />\n )}\n </ServerAPIProvider>\n ) : null}\n </div>\n </div>\n );\n};\n"],"names":["echarts","TreemapChart","TooltipComponent","TitleComponent","CanvasRenderer","hashString","str","hash","i","blendWithWhite","hex","ratio","r","parseInt","g","b","blendedR","Math","blendedG","blendedB","getLuminance","rs","gs","bs","val","isDarkColor","getLevelOption","TreeMap","memo","treeData","sizeType","onChartClick","highlightNodeId","centerNodeId","rootPath","option","setOption","useState","chartRef","React","chartDataRef","clickTimeoutRef","themeToken","useThemeToken","useEffect","convert","node","index","level","parentColor","siblingIndex","siblingCount","chunkPath","baseColor","TREE_COLORS","currentChunkPath","children","c","childIndex","nodeIdString","nodeId","isHighlighted","baseColorRatio","baseBorderRatio","siblingGradientRange","siblingRatio","colorRatio","borderRatio","nodeColor","nodeBorderColor","isDark","textColor","textBorderColor","result","undefined","data","item","pos","_params","_dom","_rect","size","obj","info","path","String","normalizedRoot","normalizedPath","sourceSize","bundledSize","gzipSize","makeRow","label","value","color","Styles","rows","formatSize","chartInstance","findNodeInfo","targetId","itemName","currentPath","found","setTimeout","nodeInfo","nodeName","e","console","zoomStrategies","strategy","window","Alert","EChartsReactCore","params","instance","AssetTreemapWithFilter","ServerAPIProvider","SDK","projectInfo","AssetTreemapWithFilterInner","assetNames","useMemo","checkedAssets","setCheckedAssets","collapsed","setCollapsed","setSizeType","searchQuery","setSearchQuery","isFullscreen","setIsFullscreen","setHighlightNodeId","setCenterNodeId","moduleId","setModuleId","showAnalyze","setShowAnalyze","chunkSearchQuery","setChunkSearchQuery","showOnlyJavaScriptAssets","setShowOnlyJavaScriptAssets","containerRef","visibleAssetNames","isJavaScriptAsset","visibleAssetNamesKey","previousVisibleAssetNamesKeyRef","handleChartClick","useCallback","enterFullscreen","el","err","exitFullscreen","document","toggleFullscreen","handleFullscreenChange","filteredTreeData","filtered","searchLower","searchResults","regex","RegExp","results","collectMatchingPaths","child","chunk","handleSearchResultClick","removeRootPath","filepath","getSize","type","calculateNodeTotalSize","childrenSize","sum","getChunkSize","name","n","sizeTypeToUse","FullscreenExitOutlined","FullscreenOutlined","RightOutlined","LeftOutlined","Radio","Input","SearchOutlined","Checkbox","a","displayPath","modules","ModuleAnalyzeComponent"],"mappings":"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"}
@@ -6,6 +6,7 @@ import { ServerAPIProvider, withServerAPI } from "../Manifest/index.mjs";
6
6
  import { LoaderExecutionsChart } from "./loader.mjs";
7
7
  import { filterLoader } from "../../utils/loader.mjs";
8
8
  import { Space } from "antd";
9
+ import { useTheme } from "../../utils/index.mjs";
9
10
  const LoaderChartBase = ({ project })=>{
10
11
  const { root: cwd } = project;
11
12
  const [store, setStore] = useState({
@@ -14,6 +15,7 @@ const LoaderChartBase = ({ project })=>{
14
15
  layer: ''
15
16
  });
16
17
  const [dimension] = useState(0);
18
+ const { theme } = useTheme();
17
19
  return /*#__PURE__*/ jsxs(Space, {
18
20
  direction: "vertical",
19
21
  style: {
@@ -34,7 +36,7 @@ const LoaderChartBase = ({ project })=>{
34
36
  return 0 === dimension ? /*#__PURE__*/ jsx(LoaderExecutionsChart, {
35
37
  loaders: loaders,
36
38
  cwd: cwd
37
- }) : /*#__PURE__*/ jsx(Fragment, {});
39
+ }, theme) : /*#__PURE__*/ jsx(Fragment, {});
38
40
  }
39
41
  })
40
42
  ]