@rsdoctor/components 1.3.12 → 1.3.13-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Charts/TreeMap.d.ts +5 -1
- package/dist/components/Charts/TreeMap.mjs +538 -212
- package/dist/components/Charts/TreeMap.mjs.map +1 -1
- package/dist/components/Charts/constants.d.ts +1 -10
- package/dist/components/Charts/constants.mjs +13 -60
- package/dist/components/Charts/constants.mjs.map +1 -1
- package/dist/components/Charts/treemap.module.mjs +32 -4
- package/dist/components/Charts/treemap.module.mjs.map +1 -1
- package/dist/components/Charts/treemap_module.css +193 -39
- package/dist/components/Charts/treemap_module.css.map +1 -1
- package/dist/pages/ModuleAnalyze/components/fileTreeCom.mjs +37 -14
- package/dist/pages/ModuleAnalyze/components/fileTreeCom.mjs.map +1 -1
- package/dist/pages/ModuleAnalyze/fileTree.d.ts +3 -0
- package/dist/pages/ModuleAnalyze/fileTree.mjs +80 -35
- package/dist/pages/ModuleAnalyze/fileTree.mjs.map +1 -1
- package/dist/pages/ModuleAnalyze/index.css +47 -0
- package/dist/pages/ModuleAnalyze/index.css.map +1 -1
- package/dist/pages/ModuleAnalyze/index.d.ts +1 -2
- package/dist/pages/ModuleAnalyze/index.mjs +69 -65
- package/dist/pages/ModuleAnalyze/index.mjs.map +1 -1
- package/dist/pages/ModuleAnalyze/utils/hooks.mjs +6 -5
- package/dist/pages/ModuleAnalyze/utils/hooks.mjs.map +1 -1
- package/package.json +4 -4
|
@@ -1,53 +1,70 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import react, { memo, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import react, { memo, useCallback, useEffect, useMemo, useState } from "react";
|
|
3
3
|
import core from "echarts-for-react/esm/core";
|
|
4
4
|
import { TreemapChart } from "echarts/charts";
|
|
5
5
|
import { TooltipComponent } from "echarts/components";
|
|
6
6
|
import { CanvasRenderer } from "echarts/renderers";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
7
|
+
import { Checkbox, Input, Radio } from "antd";
|
|
8
|
+
import { FullscreenExitOutlined, FullscreenOutlined, LeftOutlined, RightOutlined, SearchOutlined } from "@ant-design/icons";
|
|
9
|
+
import { formatSize } from "../../utils/index.mjs";
|
|
10
|
+
import { SDK } from "@rsdoctor/types";
|
|
11
|
+
import { ServerAPIProvider } from "../Manifest/index.mjs";
|
|
12
12
|
import treemap_module from "./treemap.module.mjs";
|
|
13
|
+
import { TREE_COLORS } from "./constants.mjs";
|
|
13
14
|
import * as __WEBPACK_EXTERNAL_MODULE_echarts_core_d2845954__ from "echarts/core";
|
|
15
|
+
__WEBPACK_EXTERNAL_MODULE_echarts_core_d2845954__.use([
|
|
16
|
+
TreemapChart,
|
|
17
|
+
TooltipComponent,
|
|
18
|
+
CanvasRenderer
|
|
19
|
+
]);
|
|
14
20
|
function hashString(str) {
|
|
15
21
|
let hash = 5381;
|
|
16
22
|
for(let i = 0; i < str.length; i++)hash = (hash << 5) + hash + str.charCodeAt(i);
|
|
17
23
|
return hash >>> 0;
|
|
18
24
|
}
|
|
25
|
+
function blendWithWhite(hex, ratio) {
|
|
26
|
+
const r = parseInt(hex.slice(1, 3), 16);
|
|
27
|
+
const g = parseInt(hex.slice(3, 5), 16);
|
|
28
|
+
const b = parseInt(hex.slice(5, 7), 16);
|
|
29
|
+
const blendedR = Math.round(r * ratio + 255 * (1 - ratio));
|
|
30
|
+
const blendedG = Math.round(g * ratio + 255 * (1 - ratio));
|
|
31
|
+
const blendedB = Math.round(b * ratio + 255 * (1 - ratio));
|
|
32
|
+
return `#${blendedR.toString(16).padStart(2, '0')}${blendedG.toString(16).padStart(2, '0')}${blendedB.toString(16).padStart(2, '0')}`;
|
|
33
|
+
}
|
|
19
34
|
function getLevelOption() {
|
|
20
35
|
return [
|
|
21
36
|
{
|
|
22
37
|
itemStyle: {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
borderWidth: 5,
|
|
26
|
-
gapWidth: 5
|
|
27
|
-
},
|
|
28
|
-
emphasis: {
|
|
29
|
-
itemStyle: {
|
|
30
|
-
borderColor: '#a29f9f'
|
|
31
|
-
}
|
|
38
|
+
borderWidth: 0,
|
|
39
|
+
gapWidth: 2
|
|
32
40
|
}
|
|
33
41
|
},
|
|
34
42
|
{
|
|
35
|
-
colorSaturation: [
|
|
36
|
-
0.25,
|
|
37
|
-
0.5
|
|
38
|
-
],
|
|
39
43
|
itemStyle: {
|
|
44
|
+
borderColorAlpha: [
|
|
45
|
+
1,
|
|
46
|
+
0.3
|
|
47
|
+
],
|
|
40
48
|
borderWidth: 5,
|
|
41
|
-
gapWidth:
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
gapWidth: 1
|
|
50
|
+
},
|
|
51
|
+
upperLabel: {
|
|
52
|
+
show: true,
|
|
53
|
+
color: '#555555',
|
|
54
|
+
height: 30
|
|
55
|
+
},
|
|
56
|
+
emphasis: {
|
|
57
|
+
itemStyle: {
|
|
58
|
+
borderColor: '#ccc'
|
|
59
|
+
}
|
|
44
60
|
}
|
|
45
61
|
}
|
|
46
62
|
];
|
|
47
63
|
}
|
|
48
|
-
const TreeMapInner = /*#__PURE__*/ memo(({ treeData,
|
|
64
|
+
const TreeMapInner = /*#__PURE__*/ memo(({ treeData, sizeType, style, onChartClick, forwardedRef, highlightNodeId, centerNodeId, rootPath })=>{
|
|
49
65
|
const [option, setOption] = useState(null);
|
|
50
66
|
const chartRef = react.useRef(null);
|
|
67
|
+
const chartDataRef = react.useRef([]);
|
|
51
68
|
useEffect(()=>{
|
|
52
69
|
if (forwardedRef && chartRef.current) if ('function' == typeof forwardedRef) forwardedRef(chartRef.current);
|
|
53
70
|
else forwardedRef.current = chartRef.current;
|
|
@@ -55,115 +72,284 @@ const TreeMapInner = /*#__PURE__*/ memo(({ treeData, valueKey = 'sourceSize', st
|
|
|
55
72
|
forwardedRef,
|
|
56
73
|
chartRef.current
|
|
57
74
|
]);
|
|
58
|
-
useEffect(()=>{
|
|
59
|
-
__WEBPACK_EXTERNAL_MODULE_echarts_core_d2845954__.use([
|
|
60
|
-
TreemapChart,
|
|
61
|
-
TooltipComponent,
|
|
62
|
-
CanvasRenderer
|
|
63
|
-
]);
|
|
64
|
-
}, []);
|
|
65
75
|
useEffect(()=>{
|
|
66
76
|
if (!treeData) return;
|
|
67
|
-
function convert(node,
|
|
68
|
-
const
|
|
69
|
-
const children = node.children?.map((c,
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
function convert(node, index = 0, level = 0, parentColor, siblingIndex = 0, siblingCount = 1) {
|
|
78
|
+
const baseColor = parentColor || TREE_COLORS[index % TREE_COLORS.length];
|
|
79
|
+
const children = node.children?.map((c, childIndex)=>convert(c, index, level + 1, baseColor, childIndex, node.children?.length || 0));
|
|
80
|
+
let val = 0;
|
|
81
|
+
if ('stat' === sizeType) val = node.sourceSize || 0;
|
|
82
|
+
else if ('parsed' === sizeType) val = node.bundledSize || 0;
|
|
83
|
+
else if ('gzip' === sizeType) val = node.gzipSize || 0;
|
|
84
|
+
else if ('value' === sizeType) val = node.value || 0;
|
|
85
|
+
if (!val && node.value) val = node.value;
|
|
86
|
+
const nodeId = node.path ? hashString(node.path) : hashString(node.name || '');
|
|
87
|
+
const isHighlighted = highlightNodeId === nodeId;
|
|
88
|
+
const baseColorRatio = 0 === level ? 1 : Math.max(0.2, 1 - 0.2 * level);
|
|
89
|
+
const baseBorderRatio = 0 === level ? 1 : Math.max(0.3, 1 - 0.25 * level);
|
|
90
|
+
const siblingGradientRange = 0.15;
|
|
91
|
+
const siblingRatio = siblingCount > 1 ? 1 - siblingIndex / (siblingCount - 1) * siblingGradientRange : 1;
|
|
92
|
+
const colorRatio = baseColorRatio * siblingRatio;
|
|
93
|
+
const borderRatio = baseBorderRatio * siblingRatio;
|
|
94
|
+
const nodeColor = isHighlighted ? '#fff5f5' : 0 === level ? blendWithWhite(baseColor, 0.8) : blendWithWhite(baseColor, colorRatio);
|
|
95
|
+
const nodeBorderColor = isHighlighted ? '#ff4d4f' : 0 === level ? baseColor : blendWithWhite(baseColor, borderRatio);
|
|
96
|
+
const result = {
|
|
97
|
+
id: nodeId,
|
|
72
98
|
name: node.name,
|
|
73
|
-
value:
|
|
74
|
-
path: node.path,
|
|
75
|
-
sourceSize: node.sourceSize ??
|
|
76
|
-
bundledSize: node.bundledSize,
|
|
77
|
-
gzipSize: node.gzipSize,
|
|
78
|
-
children: children && children.length > 0 ? children : void 0,
|
|
99
|
+
value: val,
|
|
100
|
+
path: node.path || node.name,
|
|
101
|
+
sourceSize: node.sourceSize ?? ('stat' === sizeType ? val : 0),
|
|
102
|
+
bundledSize: node.bundledSize ?? ('parsed' === sizeType ? val : 0),
|
|
103
|
+
gzipSize: node.gzipSize ?? ('gzip' === sizeType ? val : 0),
|
|
79
104
|
itemStyle: {
|
|
80
|
-
borderWidth:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
level
|
|
105
|
+
borderWidth: isHighlighted ? 4 : 1,
|
|
106
|
+
color: nodeColor,
|
|
107
|
+
borderColor: nodeBorderColor,
|
|
108
|
+
...0 === level && {
|
|
109
|
+
gapWidth: 2
|
|
110
|
+
}
|
|
111
|
+
}
|
|
88
112
|
};
|
|
113
|
+
if (children && children.length > 0) result.children = children;
|
|
114
|
+
if (isHighlighted) result.emphasis = {
|
|
115
|
+
itemStyle: {
|
|
116
|
+
borderColor: '#ff4d4f',
|
|
117
|
+
borderWidth: 4,
|
|
118
|
+
color: '#fff5f5'
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
return result;
|
|
89
122
|
}
|
|
90
|
-
const data = treeData.map((item, index)=>
|
|
91
|
-
|
|
92
|
-
return convert(item, group, 0);
|
|
93
|
-
});
|
|
123
|
+
const data = treeData.map((item, index)=>convert(item, index, 0, void 0, index, treeData.length)).filter((item)=>item.value > 0 || item.children && item.children.length > 0);
|
|
124
|
+
chartDataRef.current = data;
|
|
94
125
|
setOption({
|
|
126
|
+
color: TREE_COLORS,
|
|
95
127
|
title: {
|
|
96
|
-
text: '
|
|
97
|
-
left: 'center'
|
|
128
|
+
text: 'Rsdoctor TreeMap',
|
|
129
|
+
left: 'center',
|
|
130
|
+
top: 10,
|
|
131
|
+
textStyle: {
|
|
132
|
+
fontSize: 16,
|
|
133
|
+
fontWeight: 'bold',
|
|
134
|
+
color: 'rgba(0, 0, 0, 0.8)'
|
|
135
|
+
}
|
|
98
136
|
},
|
|
99
137
|
tooltip: {
|
|
100
|
-
|
|
138
|
+
padding: 10,
|
|
139
|
+
backgroundColor: '#fff',
|
|
140
|
+
borderColor: '#eee',
|
|
141
|
+
borderWidth: 1,
|
|
142
|
+
textStyle: {
|
|
143
|
+
color: 'rgba(0, 0, 0, 0.8)'
|
|
144
|
+
},
|
|
145
|
+
confine: true,
|
|
146
|
+
extraCssText: 'max-width: 450px; word-wrap: break-word;',
|
|
147
|
+
position: function(pos, _params, _dom, _rect, size) {
|
|
148
|
+
var obj = {
|
|
149
|
+
top: pos[1] + 10
|
|
150
|
+
};
|
|
151
|
+
if (pos[0] < size.viewSize[0] / 2) obj.left = pos[0] + 10;
|
|
152
|
+
else obj.right = size.viewSize[0] - pos[0] + 10;
|
|
153
|
+
return obj;
|
|
154
|
+
},
|
|
101
155
|
formatter: function(info) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
var level = node.level;
|
|
111
|
-
function makeRow(label, value, valueColor) {
|
|
112
|
-
return `<div class="${treemap_module["tooltip-row"]}"><span class="${treemap_module["tooltip-label"]}">${label}</span><span${valueColor ? ` style="color: ${valueColor}"` : ''}>${value}</span></div>`;
|
|
156
|
+
const node = info.data || {};
|
|
157
|
+
const name = node.name;
|
|
158
|
+
let path = node.path || name;
|
|
159
|
+
if (rootPath && path) {
|
|
160
|
+
const normalizedRoot = rootPath.replace(/\\/g, '/').replace(/\/$/, '');
|
|
161
|
+
const normalizedPath = path.replace(/\\/g, '/');
|
|
162
|
+
if (normalizedPath.startsWith(normalizedRoot + '/')) path = normalizedPath.slice(normalizedRoot.length + 1);
|
|
163
|
+
else if (normalizedPath === normalizedRoot) path = '';
|
|
113
164
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
]
|
|
165
|
+
const sourceSize = node.sourceSize || node.value;
|
|
166
|
+
const bundledSize = node.bundledSize;
|
|
167
|
+
const gzipSize = node.gzipSize;
|
|
168
|
+
function makeRow(label, value, color) {
|
|
169
|
+
return `<div class="${treemap_module["tooltip-row"]}">
|
|
170
|
+
<span class="${treemap_module["tooltip-label"]}" style="color: ${color};">${label}</span>
|
|
171
|
+
<span style="color: ${color};">${value}</span>
|
|
172
|
+
</div>`;
|
|
173
|
+
}
|
|
174
|
+
const rows = [];
|
|
175
|
+
if (void 0 !== sourceSize) rows.push(makeRow('Stat size', formatSize(sourceSize), '#52c41a'));
|
|
176
|
+
if (void 0 !== bundledSize) rows.push(makeRow('Parsed size', formatSize(bundledSize), '#fadb14'));
|
|
177
|
+
if (void 0 !== gzipSize) rows.push(makeRow('Gzipped size', formatSize(gzipSize), '#1677ff'));
|
|
178
|
+
return `
|
|
179
|
+
<div style="font-family: sans-serif; font-size: 12px; line-height: 1.5;">
|
|
180
|
+
<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);">${__WEBPACK_EXTERNAL_MODULE_echarts_core_d2845954__.format.encodeHTML(path)}</div>
|
|
181
|
+
${rows.join('')}
|
|
182
|
+
</div>
|
|
183
|
+
`;
|
|
120
184
|
}
|
|
121
185
|
},
|
|
122
186
|
series: [
|
|
123
187
|
{
|
|
124
|
-
name: 'Bundle Tree Map',
|
|
125
|
-
id: 'bundle-treemap',
|
|
126
188
|
type: 'treemap',
|
|
127
|
-
visibleMin: 300,
|
|
128
|
-
left: 10,
|
|
129
|
-
right: 10,
|
|
130
|
-
top: 10,
|
|
131
|
-
bottom: 10,
|
|
132
189
|
label: {
|
|
133
190
|
show: true,
|
|
134
191
|
formatter: '{b}',
|
|
135
|
-
|
|
192
|
+
fontSize: 12,
|
|
193
|
+
color: '#000',
|
|
194
|
+
position: 'inside',
|
|
195
|
+
fontWeight: 'normal',
|
|
196
|
+
textBorderColor: '#fff',
|
|
197
|
+
textBorderWidth: 2,
|
|
198
|
+
padding: [
|
|
199
|
+
4,
|
|
200
|
+
8,
|
|
201
|
+
4,
|
|
202
|
+
8
|
|
203
|
+
]
|
|
136
204
|
},
|
|
137
205
|
upperLabel: {
|
|
138
206
|
show: true,
|
|
139
|
-
height: 30
|
|
207
|
+
height: 30,
|
|
208
|
+
color: '#000',
|
|
209
|
+
fontSize: 12,
|
|
210
|
+
fontWeight: 'normal',
|
|
211
|
+
padding: [
|
|
212
|
+
0,
|
|
213
|
+
0,
|
|
214
|
+
0,
|
|
215
|
+
4
|
|
216
|
+
]
|
|
140
217
|
},
|
|
141
218
|
levels: getLevelOption(),
|
|
142
|
-
data: data
|
|
219
|
+
data: data,
|
|
220
|
+
breadcrumb: {
|
|
221
|
+
show: true,
|
|
222
|
+
left: 'center',
|
|
223
|
+
top: 'bottom',
|
|
224
|
+
height: 22,
|
|
225
|
+
emptyItemWidth: 25,
|
|
226
|
+
itemStyle: {
|
|
227
|
+
color: '#999',
|
|
228
|
+
borderColor: 'transparent',
|
|
229
|
+
borderWidth: 0,
|
|
230
|
+
borderRadius: 0
|
|
231
|
+
},
|
|
232
|
+
emphasis: {
|
|
233
|
+
itemStyle: {
|
|
234
|
+
color: '#333'
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
textStyle: {
|
|
238
|
+
fontFamily: 'sans-serif',
|
|
239
|
+
fontSize: 12,
|
|
240
|
+
color: '#666'
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
roam: true,
|
|
244
|
+
nodeClick: false,
|
|
245
|
+
zoomToNodeRatio: 0.5,
|
|
246
|
+
animationDurationUpdate: 500,
|
|
247
|
+
width: '100%',
|
|
248
|
+
height: '100%',
|
|
249
|
+
top: 40,
|
|
250
|
+
bottom: 30,
|
|
251
|
+
left: 0,
|
|
252
|
+
right: 0
|
|
143
253
|
}
|
|
144
254
|
]
|
|
145
255
|
});
|
|
146
256
|
}, [
|
|
147
257
|
treeData,
|
|
148
|
-
|
|
258
|
+
sizeType,
|
|
259
|
+
highlightNodeId,
|
|
260
|
+
rootPath
|
|
261
|
+
]);
|
|
262
|
+
useEffect(()=>{
|
|
263
|
+
if (centerNodeId && chartRef.current && option) {
|
|
264
|
+
const chartInstance = chartRef.current.getEchartsInstance();
|
|
265
|
+
if (chartInstance) {
|
|
266
|
+
const findNodeInfo = (data, targetId, path = [])=>{
|
|
267
|
+
for (const item of data){
|
|
268
|
+
const currentPath = [
|
|
269
|
+
...path,
|
|
270
|
+
item.name
|
|
271
|
+
];
|
|
272
|
+
if (item.id === targetId) return {
|
|
273
|
+
name: item.name,
|
|
274
|
+
path: currentPath
|
|
275
|
+
};
|
|
276
|
+
if (item.children) {
|
|
277
|
+
const found = findNodeInfo(item.children, targetId, currentPath);
|
|
278
|
+
if (found) return found;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
};
|
|
283
|
+
setTimeout(()=>{
|
|
284
|
+
const nodeInfo = findNodeInfo(chartDataRef.current, centerNodeId);
|
|
285
|
+
if (!nodeInfo) return;
|
|
286
|
+
try {
|
|
287
|
+
chartInstance.dispatchAction({
|
|
288
|
+
type: 'highlight',
|
|
289
|
+
seriesIndex: 0,
|
|
290
|
+
name: nodeInfo.name
|
|
291
|
+
});
|
|
292
|
+
} catch (e) {}
|
|
293
|
+
const zoomStrategies = [
|
|
294
|
+
()=>chartInstance.dispatchAction({
|
|
295
|
+
type: 'treemapZoomToNode',
|
|
296
|
+
seriesIndex: 0,
|
|
297
|
+
targetNodeId: String(centerNodeId)
|
|
298
|
+
}),
|
|
299
|
+
()=>chartInstance.dispatchAction({
|
|
300
|
+
type: 'treemapZoomToNode',
|
|
301
|
+
seriesIndex: 0,
|
|
302
|
+
name: nodeInfo.name
|
|
303
|
+
}),
|
|
304
|
+
()=>chartInstance.dispatchAction({
|
|
305
|
+
type: 'treemapZoomToNode',
|
|
306
|
+
seriesIndex: 0,
|
|
307
|
+
name: nodeInfo.path.join('/')
|
|
308
|
+
}),
|
|
309
|
+
()=>nodeInfo.path.length > 0 && chartInstance.dispatchAction({
|
|
310
|
+
type: 'treemapZoomToNode',
|
|
311
|
+
seriesIndex: 0,
|
|
312
|
+
name: nodeInfo.path[nodeInfo.path.length - 1]
|
|
313
|
+
})
|
|
314
|
+
];
|
|
315
|
+
for (const strategy of zoomStrategies)try {
|
|
316
|
+
strategy();
|
|
317
|
+
return;
|
|
318
|
+
} catch (e) {
|
|
319
|
+
console.error('Failed to zoom to node with id:', centerNodeId, e);
|
|
320
|
+
}
|
|
321
|
+
console.warn('Failed to zoom to node with id:', centerNodeId);
|
|
322
|
+
}, 200);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}, [
|
|
326
|
+
centerNodeId,
|
|
327
|
+
option
|
|
149
328
|
]);
|
|
150
329
|
return option ? /*#__PURE__*/ jsx("div", {
|
|
330
|
+
className: treemap_module["chart-container"],
|
|
331
|
+
style: style,
|
|
151
332
|
children: /*#__PURE__*/ jsx(core, {
|
|
152
333
|
ref: chartRef,
|
|
153
334
|
option: option,
|
|
154
335
|
echarts: __WEBPACK_EXTERNAL_MODULE_echarts_core_d2845954__,
|
|
155
|
-
onEvents:
|
|
156
|
-
click:
|
|
157
|
-
|
|
336
|
+
onEvents: {
|
|
337
|
+
click: (params)=>{
|
|
338
|
+
if (chartRef.current) {
|
|
339
|
+
const instance = chartRef.current.getEchartsInstance();
|
|
340
|
+
if (instance && params?.data?.id) instance.dispatchAction({
|
|
341
|
+
type: 'treemapZoomToNode',
|
|
342
|
+
seriesIndex: 0,
|
|
343
|
+
targetNodeId: String(params.data.id)
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
onChartClick?.(params);
|
|
347
|
+
}
|
|
348
|
+
},
|
|
158
349
|
style: {
|
|
159
350
|
width: '100%',
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
border: '5px solid white',
|
|
163
|
-
borderRadius: '10px',
|
|
164
|
-
...style
|
|
165
|
-
},
|
|
166
|
-
className: treemap_module["chart-container"]
|
|
351
|
+
height: '100%'
|
|
352
|
+
}
|
|
167
353
|
})
|
|
168
354
|
}) : null;
|
|
169
355
|
});
|
|
@@ -171,146 +357,286 @@ const TreeMap = /*#__PURE__*/ react.forwardRef((props, ref)=>/*#__PURE__*/ jsx(T
|
|
|
171
357
|
...props,
|
|
172
358
|
forwardedRef: ref
|
|
173
359
|
}));
|
|
174
|
-
const AssetTreemapWithFilter = ({ treeData, onChartClick, bundledSize =
|
|
360
|
+
const AssetTreemapWithFilter = ({ treeData, onChartClick, bundledSize = true })=>/*#__PURE__*/ jsx(ServerAPIProvider, {
|
|
361
|
+
api: SDK.ServerAPI.API.GetProjectInfo,
|
|
362
|
+
children: (projectInfo)=>/*#__PURE__*/ jsx(AssetTreemapWithFilterInner, {
|
|
363
|
+
treeData: treeData,
|
|
364
|
+
onChartClick: onChartClick,
|
|
365
|
+
bundledSize: bundledSize,
|
|
366
|
+
rootPath: projectInfo.root
|
|
367
|
+
})
|
|
368
|
+
});
|
|
369
|
+
const AssetTreemapWithFilterInner = ({ treeData, onChartClick, bundledSize = true, rootPath })=>{
|
|
175
370
|
const assetNames = useMemo(()=>treeData.map((item)=>item.name), [
|
|
176
371
|
treeData
|
|
177
372
|
]);
|
|
178
373
|
const [checkedAssets, setCheckedAssets] = useState(assetNames);
|
|
179
374
|
const [collapsed, setCollapsed] = useState(false);
|
|
180
|
-
const [
|
|
375
|
+
const [sizeType, setSizeType] = useState(bundledSize ? 'parsed' : 'stat');
|
|
376
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
377
|
+
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
378
|
+
const [highlightNodeId, setHighlightNodeId] = useState();
|
|
379
|
+
const [centerNodeId, setCenterNodeId] = useState();
|
|
181
380
|
const chartRef = react.useRef(null);
|
|
182
|
-
const
|
|
183
|
-
const
|
|
381
|
+
const containerRef = react.useRef(null);
|
|
382
|
+
const enterFullscreen = useCallback(()=>{
|
|
383
|
+
if (containerRef.current) containerRef.current.requestFullscreen().then(()=>setIsFullscreen(true)).catch((err)=>console.error('Failed to enter fullscreen:', err));
|
|
384
|
+
}, []);
|
|
385
|
+
const exitFullscreen = useCallback(()=>{
|
|
386
|
+
document.exitFullscreen().then(()=>setIsFullscreen(false)).catch((err)=>console.error('Failed to exit fullscreen:', err));
|
|
387
|
+
}, []);
|
|
388
|
+
const toggleFullscreen = useCallback(()=>{
|
|
389
|
+
if (isFullscreen) exitFullscreen();
|
|
390
|
+
else enterFullscreen();
|
|
391
|
+
}, [
|
|
392
|
+
isFullscreen,
|
|
393
|
+
enterFullscreen,
|
|
394
|
+
exitFullscreen
|
|
395
|
+
]);
|
|
396
|
+
useEffect(()=>{
|
|
397
|
+
const handleFullscreenChange = ()=>{
|
|
398
|
+
setIsFullscreen(!!document.fullscreenElement);
|
|
399
|
+
};
|
|
400
|
+
document.addEventListener('fullscreenchange', handleFullscreenChange);
|
|
401
|
+
return ()=>{
|
|
402
|
+
document.removeEventListener('fullscreenchange', handleFullscreenChange);
|
|
403
|
+
};
|
|
404
|
+
}, []);
|
|
405
|
+
const searchResults = useMemo(()=>{
|
|
406
|
+
if (!searchQuery.trim()) return [];
|
|
407
|
+
const regex = new RegExp(searchQuery, 'i');
|
|
408
|
+
const results = [];
|
|
409
|
+
const collectMatchingPaths = (node)=>{
|
|
410
|
+
if (node.path && regex.test(node.path)) {
|
|
411
|
+
const nodeId = hashString(node.path);
|
|
412
|
+
results.push({
|
|
413
|
+
path: node.path,
|
|
414
|
+
nodeId
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
if (node.children) node.children.forEach(collectMatchingPaths);
|
|
418
|
+
};
|
|
419
|
+
treeData.forEach(collectMatchingPaths);
|
|
420
|
+
return results;
|
|
421
|
+
}, [
|
|
422
|
+
treeData,
|
|
423
|
+
searchQuery
|
|
424
|
+
]);
|
|
425
|
+
const filteredTreeData = useMemo(()=>{
|
|
426
|
+
let filtered = treeData.filter((item)=>checkedAssets.includes(item.name));
|
|
427
|
+
return filtered;
|
|
428
|
+
}, [
|
|
184
429
|
treeData,
|
|
185
430
|
checkedAssets
|
|
186
431
|
]);
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
432
|
+
const handleSearchResultClick = useCallback((nodeId)=>{
|
|
433
|
+
setHighlightNodeId(nodeId);
|
|
434
|
+
setCenterNodeId(nodeId);
|
|
435
|
+
}, []);
|
|
436
|
+
const removeRootPath = useCallback((filepath)=>{
|
|
437
|
+
if (!rootPath || !filepath) return filepath;
|
|
438
|
+
const normalizedRoot = rootPath.replace(/\\/g, '/').replace(/\/$/, '');
|
|
439
|
+
const normalizedPath = filepath.replace(/\\/g, '/');
|
|
440
|
+
if (normalizedPath.startsWith(normalizedRoot + '/')) return normalizedPath.slice(normalizedRoot.length + 1);
|
|
441
|
+
if (normalizedPath === normalizedRoot) return '';
|
|
442
|
+
return filepath;
|
|
443
|
+
}, [
|
|
444
|
+
rootPath
|
|
445
|
+
]);
|
|
446
|
+
const getSize = useCallback((node, type)=>{
|
|
447
|
+
if ('stat' === type) return node.sourceSize || 0;
|
|
448
|
+
if ('parsed' === type) return node.bundledSize || 0;
|
|
449
|
+
if ('gzip' === type) return node.gzipSize || 0;
|
|
450
|
+
if ('value' === type) return node.value || 0;
|
|
451
|
+
if (node.value) return node.value;
|
|
452
|
+
return 0;
|
|
453
|
+
}, []);
|
|
454
|
+
const calculateNodeTotalSize = useCallback((node, type)=>{
|
|
455
|
+
let size = getSize(node, type);
|
|
456
|
+
if (node.children && node.children.length > 0) {
|
|
457
|
+
const childrenSize = node.children.reduce((sum, child)=>sum + calculateNodeTotalSize(child, type), 0);
|
|
458
|
+
if (0 === size || !node.path && childrenSize > 0) size = childrenSize;
|
|
197
459
|
}
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
460
|
+
return size;
|
|
461
|
+
}, [
|
|
462
|
+
getSize
|
|
463
|
+
]);
|
|
464
|
+
const getChunkSize = useCallback((name, type)=>{
|
|
465
|
+
const node = treeData.find((n)=>n.name === name);
|
|
466
|
+
if (!node) return 0;
|
|
467
|
+
const sizeTypeToUse = type || sizeType;
|
|
468
|
+
return calculateNodeTotalSize(node, sizeTypeToUse);
|
|
469
|
+
}, [
|
|
470
|
+
treeData,
|
|
471
|
+
sizeType,
|
|
472
|
+
calculateNodeTotalSize
|
|
473
|
+
]);
|
|
474
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
206
475
|
className: treemap_module.treemap,
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
476
|
+
ref: containerRef,
|
|
477
|
+
children: [
|
|
478
|
+
/*#__PURE__*/ jsx("button", {
|
|
479
|
+
className: treemap_module["fullscreen-button"],
|
|
480
|
+
onClick: toggleFullscreen,
|
|
481
|
+
title: isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen',
|
|
482
|
+
"aria-label": isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen',
|
|
483
|
+
children: isFullscreen ? /*#__PURE__*/ jsx(FullscreenExitOutlined, {}) : /*#__PURE__*/ jsx(FullscreenOutlined, {})
|
|
484
|
+
}),
|
|
485
|
+
/*#__PURE__*/ jsxs("div", {
|
|
486
|
+
className: `${treemap_module.sidebar} ${collapsed ? treemap_module.collapsed : ''}`,
|
|
487
|
+
children: [
|
|
488
|
+
/*#__PURE__*/ jsx("div", {
|
|
489
|
+
className: `${treemap_module["sidebar-toggle"]} ${collapsed ? treemap_module.collapsed : ''}`,
|
|
490
|
+
onClick: ()=>setCollapsed(!collapsed),
|
|
491
|
+
children: collapsed ? /*#__PURE__*/ jsx(RightOutlined, {}) : /*#__PURE__*/ jsx(LeftOutlined, {})
|
|
492
|
+
}),
|
|
493
|
+
/*#__PURE__*/ jsxs("div", {
|
|
494
|
+
className: treemap_module["sidebar-content"],
|
|
215
495
|
children: [
|
|
216
|
-
/*#__PURE__*/
|
|
217
|
-
children:
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
496
|
+
/*#__PURE__*/ jsxs("div", {
|
|
497
|
+
children: [
|
|
498
|
+
/*#__PURE__*/ jsx("h4", {
|
|
499
|
+
children: "Treemap sizes"
|
|
500
|
+
}),
|
|
501
|
+
/*#__PURE__*/ jsxs(Radio.Group, {
|
|
502
|
+
value: sizeType,
|
|
503
|
+
onChange: (e)=>setSizeType(e.target.value),
|
|
504
|
+
size: "small",
|
|
505
|
+
buttonStyle: "solid",
|
|
506
|
+
children: [
|
|
507
|
+
/*#__PURE__*/ jsx(Radio.Button, {
|
|
508
|
+
value: "stat",
|
|
509
|
+
children: "Stat"
|
|
510
|
+
}),
|
|
511
|
+
/*#__PURE__*/ jsx(Radio.Button, {
|
|
512
|
+
value: "parsed",
|
|
513
|
+
children: "Parsed"
|
|
514
|
+
}),
|
|
515
|
+
/*#__PURE__*/ jsx(Radio.Button, {
|
|
516
|
+
value: "gzip",
|
|
517
|
+
children: "Gzipped"
|
|
518
|
+
})
|
|
519
|
+
]
|
|
520
|
+
})
|
|
521
|
+
]
|
|
224
522
|
}),
|
|
225
|
-
/*#__PURE__*/
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
"
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
/*#__PURE__*/ jsx(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}),
|
|
243
|
-
": The size of a module after compilation (e.g., TypeScript/JSX to JS), but before bundling and minification.",
|
|
244
|
-
/*#__PURE__*/ jsx("br", {}),
|
|
245
|
-
"✨ ",
|
|
246
|
-
/*#__PURE__*/ jsx("b", {
|
|
247
|
-
children: "Gzipped Size"
|
|
523
|
+
/*#__PURE__*/ jsxs("div", {
|
|
524
|
+
children: [
|
|
525
|
+
/*#__PURE__*/ jsx("h4", {
|
|
526
|
+
children: "Search modules"
|
|
527
|
+
}),
|
|
528
|
+
/*#__PURE__*/ jsx(Input, {
|
|
529
|
+
placeholder: "Enter regexp",
|
|
530
|
+
value: searchQuery,
|
|
531
|
+
onChange: (e)=>{
|
|
532
|
+
setSearchQuery(e.target.value);
|
|
533
|
+
setHighlightNodeId(void 0);
|
|
534
|
+
setCenterNodeId(void 0);
|
|
535
|
+
},
|
|
536
|
+
suffix: /*#__PURE__*/ jsx(SearchOutlined, {
|
|
537
|
+
style: {
|
|
538
|
+
color: '#ccc'
|
|
539
|
+
}
|
|
248
540
|
}),
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
541
|
+
allowClear: true,
|
|
542
|
+
size: "small"
|
|
543
|
+
}),
|
|
544
|
+
searchQuery.trim() && searchResults.length > 0 && /*#__PURE__*/ jsxs("div", {
|
|
545
|
+
className: treemap_module["search-results"],
|
|
546
|
+
children: [
|
|
547
|
+
/*#__PURE__*/ jsxs("div", {
|
|
548
|
+
className: treemap_module["search-results-header"],
|
|
549
|
+
children: [
|
|
550
|
+
"Found ",
|
|
551
|
+
searchResults.length,
|
|
552
|
+
" file",
|
|
553
|
+
searchResults.length > 1 ? 's' : ''
|
|
554
|
+
]
|
|
555
|
+
}),
|
|
556
|
+
/*#__PURE__*/ jsx("div", {
|
|
557
|
+
className: treemap_module["search-results-list"],
|
|
558
|
+
children: searchResults.map((result, index)=>{
|
|
559
|
+
const displayPath = removeRootPath(result.path);
|
|
560
|
+
return /*#__PURE__*/ jsx("div", {
|
|
561
|
+
className: treemap_module["search-result-item"],
|
|
562
|
+
onClick: ()=>handleSearchResultClick(result.nodeId),
|
|
563
|
+
title: result.path,
|
|
564
|
+
children: displayPath || result.path
|
|
565
|
+
}, index);
|
|
566
|
+
})
|
|
567
|
+
})
|
|
568
|
+
]
|
|
569
|
+
}),
|
|
570
|
+
searchQuery.trim() && 0 === searchResults.length && /*#__PURE__*/ jsxs("div", {
|
|
571
|
+
className: treemap_module["search-results-empty"],
|
|
572
|
+
children: [
|
|
573
|
+
'No files found matching "',
|
|
574
|
+
searchQuery,
|
|
575
|
+
'"'
|
|
576
|
+
]
|
|
577
|
+
})
|
|
578
|
+
]
|
|
263
579
|
}),
|
|
264
|
-
/*#__PURE__*/ jsxs(
|
|
265
|
-
color: "blue",
|
|
580
|
+
/*#__PURE__*/ jsxs("div", {
|
|
266
581
|
children: [
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
582
|
+
/*#__PURE__*/ jsx("h4", {
|
|
583
|
+
children: "Show chunks"
|
|
584
|
+
}),
|
|
585
|
+
/*#__PURE__*/ jsx(Checkbox, {
|
|
586
|
+
indeterminate: checkedAssets.length > 0 && checkedAssets.length < assetNames.length,
|
|
587
|
+
checked: checkedAssets.length === assetNames.length,
|
|
588
|
+
onChange: (e)=>setCheckedAssets(e.target.checked ? assetNames : []),
|
|
589
|
+
className: treemap_module["all-none-checkbox"],
|
|
590
|
+
children: "All"
|
|
591
|
+
}),
|
|
592
|
+
/*#__PURE__*/ jsx("div", {
|
|
593
|
+
className: treemap_module["chunk-list"],
|
|
594
|
+
children: assetNames.map((name)=>/*#__PURE__*/ jsxs("div", {
|
|
595
|
+
className: treemap_module["chunk-item"],
|
|
596
|
+
children: [
|
|
597
|
+
/*#__PURE__*/ jsx(Checkbox, {
|
|
598
|
+
checked: checkedAssets.includes(name),
|
|
599
|
+
onChange: (e)=>{
|
|
600
|
+
e.target.checked ? setCheckedAssets([
|
|
601
|
+
...checkedAssets,
|
|
602
|
+
name
|
|
603
|
+
]) : setCheckedAssets(checkedAssets.filter((a)=>a !== name));
|
|
604
|
+
},
|
|
605
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
606
|
+
title: name,
|
|
607
|
+
children: name
|
|
608
|
+
})
|
|
609
|
+
}),
|
|
610
|
+
/*#__PURE__*/ jsx("span", {
|
|
611
|
+
className: treemap_module["size-tag"],
|
|
612
|
+
children: formatSize(getChunkSize(name, 'value'))
|
|
613
|
+
})
|
|
614
|
+
]
|
|
615
|
+
}, name))
|
|
616
|
+
})
|
|
270
617
|
]
|
|
271
618
|
})
|
|
272
619
|
]
|
|
273
|
-
}),
|
|
274
|
-
extra: /*#__PURE__*/ jsx("span", {
|
|
275
|
-
className: treemap_module["collapse-icon"],
|
|
276
|
-
onClick: ()=>setCollapsed((c)=>!c),
|
|
277
|
-
"aria-label": collapsed ? t('Expand') : t('Collapse'),
|
|
278
|
-
children: collapsed ? /*#__PURE__*/ jsx(VerticalAlignBottomOutlined, {}) : /*#__PURE__*/ jsx(VerticalAlignTopOutlined, {})
|
|
279
|
-
}),
|
|
280
|
-
size: "small",
|
|
281
|
-
className: `card-body ${collapsed ? 'collapsed' : ''}`,
|
|
282
|
-
children: /*#__PURE__*/ jsxs("div", {
|
|
283
|
-
className: `checkbox-container ${collapsed ? 'collapsed' : ''}`,
|
|
284
|
-
children: [
|
|
285
|
-
/*#__PURE__*/ jsx(Checkbox, {
|
|
286
|
-
indeterminate: checkedAssets.length > 0 && checkedAssets.length < assetNames.length,
|
|
287
|
-
checked: checkedAssets.length === assetNames.length,
|
|
288
|
-
onChange: (e)=>setCheckedAssets(e.target.checked ? assetNames : []),
|
|
289
|
-
className: treemap_module["all-none-checkbox"],
|
|
290
|
-
children: 'ALL / NONE'
|
|
291
|
-
}, "all-none-checkbox"),
|
|
292
|
-
/*#__PURE__*/ jsx(Checkbox.Group, {
|
|
293
|
-
options: assetNames,
|
|
294
|
-
value: checkedAssets,
|
|
295
|
-
onChange: setCheckedAssets,
|
|
296
|
-
className: `checkbox-container ${collapsed ? 'collapsed' : ''} ${treemap_module["asset-checkbox-group"]}`
|
|
297
|
-
}, "asset-checkbox-group")
|
|
298
|
-
]
|
|
299
620
|
})
|
|
300
|
-
|
|
301
|
-
|
|
621
|
+
]
|
|
622
|
+
}),
|
|
623
|
+
/*#__PURE__*/ jsx("div", {
|
|
624
|
+
className: treemap_module["chart-wrapper"],
|
|
625
|
+
children: /*#__PURE__*/ jsx(TreeMap, {
|
|
626
|
+
ref: chartRef,
|
|
627
|
+
treeData: filteredTreeData,
|
|
628
|
+
sizeType: sizeType,
|
|
629
|
+
onChartClick: onChartClick,
|
|
630
|
+
highlightNodeId: highlightNodeId,
|
|
631
|
+
centerNodeId: centerNodeId,
|
|
632
|
+
rootPath: rootPath,
|
|
302
633
|
style: {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
ref: chartRef,
|
|
307
|
-
treeData: filteredTreeData,
|
|
308
|
-
valueKey: bundledSize ? 'bundledSize' : 'sourceSize',
|
|
309
|
-
onChartClick: onChartClick
|
|
310
|
-
})
|
|
634
|
+
width: '100%',
|
|
635
|
+
height: '100%'
|
|
636
|
+
}
|
|
311
637
|
})
|
|
312
|
-
|
|
313
|
-
|
|
638
|
+
})
|
|
639
|
+
]
|
|
314
640
|
});
|
|
315
641
|
};
|
|
316
642
|
export { AssetTreemapWithFilter, TreeMap };
|