From 97a0dcbda00d2528b4848de2455e46e5633ccaf1 Mon Sep 17 00:00:00 2001 From: Zxilly Date: Wed, 15 May 2024 19:20:42 +0800 Subject: [PATCH 1/4] feat: remove unused package wrapper --- ui/src/Node.tsx | 2 +- ui/src/TreeMap.tsx | 4 +++- ui/src/style.scss | 1 - ui/src/tool/entry.ts | 7 ++----- ui/src/tool/utils.ts | 17 +++++++++++++++++ 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ui/src/Node.tsx b/ui/src/Node.tsx index b1c7aaf9a..c1c6f62ee 100644 --- a/ui/src/Node.tsx +++ b/ui/src/Node.tsx @@ -41,7 +41,7 @@ export const Node: React.FC = ( x: width / 2, y: children != null ? (TOP_PADDING + PADDING) / 2 : height / 2 } - }, []) + }, [children, height, width]) const title = useMemo(() => { const t = trimPrefix(node.data.getName(), node.parent?.data.getName() ?? "") diff --git a/ui/src/TreeMap.tsx b/ui/src/TreeMap.tsx index 6ed5375ff..cc4e20ae1 100644 --- a/ui/src/TreeMap.tsx +++ b/ui/src/TreeMap.tsx @@ -120,7 +120,9 @@ function TreeMap() { node={node} onMouseOver={(node) => { setTooltipNode(node); - setShowTooltip(true); + if (!showTooltip) { + setShowTooltip(true); + } }} selected={selectedNode?.data?.getID() === node.data.getID()} onClick={(node) => { diff --git a/ui/src/style.scss b/ui/src/style.scss index 2ad763074..6a43dcaff 100644 --- a/ui/src/style.scss +++ b/ui/src/style.scss @@ -75,5 +75,4 @@ svg { .node { cursor: pointer; - margin: 2px; } diff --git a/ui/src/tool/entry.ts b/ui/src/tool/entry.ts index 87aa8044a..188aa336a 100644 --- a/ui/src/tool/entry.ts +++ b/ui/src/tool/entry.ts @@ -16,7 +16,7 @@ import {max} from "d3-array"; type Candidate = Section | File | Package | Result | FileSymbol; -type EntryType = "section" | "file" | "package" | "result" | "symbol" | "disasm" | "unknown" | "container"; +export type EntryType = "section" | "file" | "package" | "result" | "symbol" | "disasm" | "unknown" | "container"; export class Entry { private readonly type: EntryType; @@ -255,10 +255,7 @@ function childrenFromResult(result: Result): Entry[] { packageContainer.explain = `The size of the ${type} packages in the binary.` typedPackagesChildren.push(packageContainer); } - const packageContainerSize = typedPackagesChildren.reduce((acc, child) => acc + child.getSize(), 0); - const packageContainer = new Entry("Packages Size", packageContainerSize, "container", typedPackagesChildren); - packageContainer.explain = "The size of the packages in the binary." - children.push(packageContainer); + children.push(...typedPackagesChildren); const leftSize = result.size - children.reduce((acc, child) => acc + child.getSize(), 0); if (leftSize > 0) { diff --git a/ui/src/tool/utils.ts b/ui/src/tool/utils.ts index 9f08da843..a21339261 100644 --- a/ui/src/tool/utils.ts +++ b/ui/src/tool/utils.ts @@ -1,5 +1,6 @@ import {Result} from "../schema/schema.ts"; import {parseResult} from "../generated/schema.ts"; +import {useCallback, useRef} from 'react'; export function loadData(): Result { const doc = document.querySelector("#data")!; @@ -31,3 +32,19 @@ export function trimPrefix(str: string, prefix: string) { return str } } + +export function useThrottle) => ReturnType>(func: T, delay: number): (...args: Parameters) => void { + const lastCall = useRef(0); + const lastFunc = useRef(func); + + lastFunc.current = func; + + return useCallback((...args: Parameters) => { + const now = Date.now(); + + if (now - lastCall.current >= delay) { + lastCall.current = now; + lastFunc.current(...args); + } + }, [delay]); +} From 0736d192b4659c2caa7460f0f7de28621c54dcdd Mon Sep 17 00:00:00 2001 From: Zxilly Date: Wed, 15 May 2024 20:18:01 +0800 Subject: [PATCH 2/4] perf: use global event listener --- ui/package.json | 8 +- ui/pnpm-lock.yaml | 283 +++++++++++++++++++++---------------------- ui/src/Node.tsx | 19 +-- ui/src/TreeMap.tsx | 95 ++++++++++----- ui/src/cache.ts | 4 + ui/src/tool/entry.ts | 10 +- ui/src/tool/id.ts | 4 +- 7 files changed, 231 insertions(+), 192 deletions(-) create mode 100644 ui/src/cache.ts diff --git a/ui/package.json b/ui/package.json index 5faf522d2..aaf087ffb 100644 --- a/ui/package.json +++ b/ui/package.json @@ -25,16 +25,16 @@ "@types/d3-color": "^3.1.3", "@types/d3-hierarchy": "^3.1.7", "@types/d3-scale": "^4.0.8", - "@types/node": "^20.12.11", + "@types/node": "^20.12.12", "@types/react": "^18.3.2", "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^7.8.0", - "@typescript-eslint/parser": "^7.8.0", + "@typescript-eslint/eslint-plugin": "^7.9.0", + "@typescript-eslint/parser": "^7.9.0", "@vitejs/plugin-react-swc": "^3.6.0", "eslint": "^8.57.0", "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.6", + "eslint-plugin-react-refresh": "^0.4.7", "lightningcss": "^1.24.1", "sass": "^1.77.1", "terser": "^5.31.0", diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index b29c7bc1e..e301bb77a 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -32,7 +32,7 @@ importers: devDependencies: '@codecov/vite-plugin': specifier: 0.0.1-beta.6 - version: 0.0.1-beta.6(vite@5.2.11) + version: 0.0.1-beta.6(vite@5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0)) '@types/d3-array': specifier: ^3.2.1 version: 3.2.1 @@ -46,8 +46,8 @@ importers: specifier: ^4.0.8 version: 4.0.8 '@types/node': - specifier: ^20.12.11 - version: 20.12.11 + specifier: ^20.12.12 + version: 20.12.12 '@types/react': specifier: ^18.3.2 version: 18.3.2 @@ -55,14 +55,14 @@ importers: specifier: ^18.3.0 version: 18.3.0 '@typescript-eslint/eslint-plugin': - specifier: ^7.8.0 - version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@5.4.5) + specifier: ^7.9.0 + version: 7.9.0(@typescript-eslint/parser@7.9.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/parser': - specifier: ^7.8.0 - version: 7.8.0(eslint@8.57.0)(typescript@5.4.5) + specifier: ^7.9.0 + version: 7.9.0(eslint@8.57.0)(typescript@5.4.5) '@vitejs/plugin-react-swc': specifier: ^3.6.0 - version: 3.6.0(vite@5.2.11) + version: 3.6.0(vite@5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0)) eslint: specifier: ^8.57.0 version: 8.57.0 @@ -73,7 +73,7 @@ importers: specifier: ^4.6.2 version: 4.6.2(eslint@8.57.0) eslint-plugin-react-refresh: - specifier: ^0.4.6 + specifier: ^0.4.7 version: 0.4.7(eslint@8.57.0) lightningcss: specifier: ^1.24.1 @@ -95,13 +95,13 @@ importers: version: 6.0.3(typescript@5.4.5) vite: specifier: ^5.2.11 - version: 5.2.11(@types/node@20.12.11)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0) + version: 5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0) vite-plugin-html: specifier: ^3.2.2 - version: 3.2.2(vite@5.2.11) + version: 3.2.2(vite@5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0)) vite-plugin-singlefile: specifier: ^2.0.1 - version: 2.0.1(rollup@4.17.2)(vite@5.2.11) + version: 2.0.1(rollup@4.17.2)(vite@5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0)) packages: @@ -402,68 +402,68 @@ packages: '@samchon/openapi@0.1.21': resolution: {integrity: sha512-IUCOZpLOx8IZzxW87ySvFRSyGMRRQS5vpUwhUddzVR9vlDvTfVYjQjFuiJBqQIeGSdZExV3JzuHJCogacmd0/g==} - '@swc/core-darwin-arm64@1.5.5': - resolution: {integrity: sha512-Ol5ZwZYdTOZsv2NwjcT/qVVALKzVFeh+IJ4GNarr3P99+38Dkwi81OqCI1o/WaDXQYKAQC/V+CzMbkEuJJfq9Q==} + '@swc/core-darwin-arm64@1.5.7': + resolution: {integrity: sha512-bZLVHPTpH3h6yhwVl395k0Mtx8v6CGhq5r4KQdAoPbADU974Mauz1b6ViHAJ74O0IVE5vyy7tD3OpkQxL/vMDQ==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.5.5': - resolution: {integrity: sha512-XHWpKBIPKYLgh5/lV2PYjO84lkzf5JR51kjiloyz2Pa9HIV8tHoAP8bYdJwm4nUp2I7KcEh3pPH0AVu5LpxMKw==} + '@swc/core-darwin-x64@1.5.7': + resolution: {integrity: sha512-RpUyu2GsviwTc2qVajPL0l8nf2vKj5wzO3WkLSHAHEJbiUZk83NJrZd1RVbEknIMO7+Uyjh54hEh8R26jSByaw==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.5.5': - resolution: {integrity: sha512-vtoWNCWAe+CNSqtqIwFnIH48qgPPlUZKoQ4EVFeMM+7/kDi6SeNxoh5TierJs5bKAWxD49VkPvRoWFCk6V62mA==} + '@swc/core-linux-arm-gnueabihf@1.5.7': + resolution: {integrity: sha512-cTZWTnCXLABOuvWiv6nQQM0hP6ZWEkzdgDvztgHI/+u/MvtzJBN5lBQ2lue/9sSFYLMqzqff5EHKlFtrJCA9dQ==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.5.5': - resolution: {integrity: sha512-L4l7M78U6h/rCAxId+y5Vu+1KfDRF6dJZtitFcaT293guiUQFwJv8gLxI4Jh5wFtZ0fYd0QaCuvh2Ip79CzGMg==} + '@swc/core-linux-arm64-gnu@1.5.7': + resolution: {integrity: sha512-hoeTJFBiE/IJP30Be7djWF8Q5KVgkbDtjySmvYLg9P94bHg9TJPSQoC72tXx/oXOgXvElDe/GMybru0UxhKx4g==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.5.5': - resolution: {integrity: sha512-DkzJc13ukXa7oJpyn24BjIgsiOybYrc+IxjsQyfNlDrrs1QXP4elStcpkD02SsIuSyHjZV8Hw2HFBMQB3OHPrA==} + '@swc/core-linux-arm64-musl@1.5.7': + resolution: {integrity: sha512-+NDhK+IFTiVK1/o7EXdCeF2hEzCiaRSrb9zD7X2Z7inwWlxAntcSuzZW7Y6BRqGQH89KA91qYgwbnjgTQ22PiQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.5.5': - resolution: {integrity: sha512-kj4ZwWJGeBEUzHrRQP2VudN+kkkYH7OI1dPVDc6kWQx5X4329JeKOas4qY0l7gDVjBbRwN9IbbPI6TIn2KfAug==} + '@swc/core-linux-x64-gnu@1.5.7': + resolution: {integrity: sha512-25GXpJmeFxKB+7pbY7YQLhWWjkYlR+kHz5I3j9WRl3Lp4v4UD67OGXwPe+DIcHqcouA1fhLhsgHJWtsaNOMBNg==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.5.5': - resolution: {integrity: sha512-6pTorCs4mYhPhYtC4jNOnhGgjNd3DZcRoZ9P0tzXXP69aCbYjvlgNH/NRvAROp9AaVFeZ7a7PmCWb6+Rbe7NKg==} + '@swc/core-linux-x64-musl@1.5.7': + resolution: {integrity: sha512-0VN9Y5EAPBESmSPPsCJzplZHV26akC0sIgd3Hc/7S/1GkSMoeuVL+V9vt+F/cCuzr4VidzSkqftdP3qEIsXSpg==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.5.5': - resolution: {integrity: sha512-o0/9pstmEjwZyrY/bA+mymF0zH7E+GT/XCVqdKeWW9Wn3gTTyWa5MZnrFgI2THQ+AXwdglMB/Zo76ARQPaz/+A==} + '@swc/core-win32-arm64-msvc@1.5.7': + resolution: {integrity: sha512-RtoNnstBwy5VloNCvmvYNApkTmuCe4sNcoYWpmY7C1+bPR+6SOo8im1G6/FpNem8AR5fcZCmXHWQ+EUmRWJyuA==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.5.5': - resolution: {integrity: sha512-B+nypUwsmCuaH6RtKWgiPCb+ENjxstJPPJeMJvBqlJqyCaIkZzN4M07Ozi3xVv1VG21SRkd6G3xIqRoalrNc0Q==} + '@swc/core-win32-ia32-msvc@1.5.7': + resolution: {integrity: sha512-Xm0TfvcmmspvQg1s4+USL3x8D+YPAfX2JHygvxAnCJ0EHun8cm2zvfNBcsTlnwYb0ybFWXXY129aq1wgFC9TpQ==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.5.5': - resolution: {integrity: sha512-ry83ki9ZX0Q+GWGnqc2J618Z+FvKE8Ajn42F8EYi8Wj0q6Jz3mj+pJzgzakk2INm2ldEZ+FaRPipn4ozsZDcBg==} + '@swc/core-win32-x64-msvc@1.5.7': + resolution: {integrity: sha512-tp43WfJLCsKLQKBmjmY/0vv1slVywR5Q4qKjF5OIY8QijaEW7/8VwPyUyVoJZEnDgv9jKtUTG5PzqtIYPZGnyg==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.5.5': - resolution: {integrity: sha512-M8O22EEgdSONLd+7KRrXj8pn+RdAZZ7ISnPjE9KCQQlI0kkFNEquWR+uFdlFxQfwlyCe/Zb6uGXGDvtcov4IMg==} + '@swc/core@1.5.7': + resolution: {integrity: sha512-U4qJRBefIJNJDRCCiVtkfa/hpiZ7w0R6kASea+/KLp+vkus3zcLSB8Ub8SvKgTIxjWpwsKcZlPf5nrv4ls46SQ==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': ^0.5.0 @@ -474,8 +474,8 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/types@0.1.6': - resolution: {integrity: sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==} + '@swc/types@0.1.7': + resolution: {integrity: sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==} '@types/d3-array@3.2.1': resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} @@ -495,11 +495,8 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/node@20.12.11': - resolution: {integrity: sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==} + '@types/node@20.12.12': + resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==} '@types/prop-types@15.7.12': resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} @@ -510,11 +507,8 @@ packages: '@types/react@18.3.2': resolution: {integrity: sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==} - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - - '@typescript-eslint/eslint-plugin@7.8.0': - resolution: {integrity: sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==} + '@typescript-eslint/eslint-plugin@7.9.0': + resolution: {integrity: sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -524,8 +518,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@7.8.0': - resolution: {integrity: sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==} + '@typescript-eslint/parser@7.9.0': + resolution: {integrity: sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -534,12 +528,12 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@7.8.0': - resolution: {integrity: sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==} + '@typescript-eslint/scope-manager@7.9.0': + resolution: {integrity: sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/type-utils@7.8.0': - resolution: {integrity: sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==} + '@typescript-eslint/type-utils@7.9.0': + resolution: {integrity: sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -548,12 +542,12 @@ packages: typescript: optional: true - '@typescript-eslint/types@7.8.0': - resolution: {integrity: sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==} + '@typescript-eslint/types@7.9.0': + resolution: {integrity: sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/typescript-estree@7.8.0': - resolution: {integrity: sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==} + '@typescript-eslint/typescript-estree@7.9.0': + resolution: {integrity: sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' @@ -561,14 +555,14 @@ packages: typescript: optional: true - '@typescript-eslint/utils@7.8.0': - resolution: {integrity: sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==} + '@typescript-eslint/utils@7.9.0': + resolution: {integrity: sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/visitor-keys@7.8.0': - resolution: {integrity: sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==} + '@typescript-eslint/visitor-keys@7.9.0': + resolution: {integrity: sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==} engines: {node: ^18.18.0 || >=20.0.0} '@ungap/structured-clone@1.2.0': @@ -1167,8 +1161,8 @@ packages: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} - immutable@4.3.5: - resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==} + immutable@4.3.6: + resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} @@ -1578,8 +1572,8 @@ packages: pathe@0.2.0: resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -1712,8 +1706,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.1: - resolution: {integrity: sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==} + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} engines: {node: '>=10'} hasBin: true @@ -1984,14 +1978,14 @@ snapshots: '@codecov/bundler-plugin-core@0.0.1-beta.6': dependencies: chalk: 4.1.2 - semver: 7.6.1 + semver: 7.6.2 unplugin: 1.10.1 zod: 3.23.8 - '@codecov/vite-plugin@0.0.1-beta.6(vite@5.2.11)': + '@codecov/vite-plugin@0.0.1-beta.6(vite@5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0))': dependencies: '@codecov/bundler-plugin-core': 0.0.1-beta.6 - vite: 5.2.11(@types/node@20.12.11)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0) + vite: 5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0) '@esbuild/aix-ppc64@0.20.2': optional: true @@ -2186,55 +2180,55 @@ snapshots: '@samchon/openapi@0.1.21': {} - '@swc/core-darwin-arm64@1.5.5': + '@swc/core-darwin-arm64@1.5.7': optional: true - '@swc/core-darwin-x64@1.5.5': + '@swc/core-darwin-x64@1.5.7': optional: true - '@swc/core-linux-arm-gnueabihf@1.5.5': + '@swc/core-linux-arm-gnueabihf@1.5.7': optional: true - '@swc/core-linux-arm64-gnu@1.5.5': + '@swc/core-linux-arm64-gnu@1.5.7': optional: true - '@swc/core-linux-arm64-musl@1.5.5': + '@swc/core-linux-arm64-musl@1.5.7': optional: true - '@swc/core-linux-x64-gnu@1.5.5': + '@swc/core-linux-x64-gnu@1.5.7': optional: true - '@swc/core-linux-x64-musl@1.5.5': + '@swc/core-linux-x64-musl@1.5.7': optional: true - '@swc/core-win32-arm64-msvc@1.5.5': + '@swc/core-win32-arm64-msvc@1.5.7': optional: true - '@swc/core-win32-ia32-msvc@1.5.5': + '@swc/core-win32-ia32-msvc@1.5.7': optional: true - '@swc/core-win32-x64-msvc@1.5.5': + '@swc/core-win32-x64-msvc@1.5.7': optional: true - '@swc/core@1.5.5': + '@swc/core@1.5.7': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.6 + '@swc/types': 0.1.7 optionalDependencies: - '@swc/core-darwin-arm64': 1.5.5 - '@swc/core-darwin-x64': 1.5.5 - '@swc/core-linux-arm-gnueabihf': 1.5.5 - '@swc/core-linux-arm64-gnu': 1.5.5 - '@swc/core-linux-arm64-musl': 1.5.5 - '@swc/core-linux-x64-gnu': 1.5.5 - '@swc/core-linux-x64-musl': 1.5.5 - '@swc/core-win32-arm64-msvc': 1.5.5 - '@swc/core-win32-ia32-msvc': 1.5.5 - '@swc/core-win32-x64-msvc': 1.5.5 + '@swc/core-darwin-arm64': 1.5.7 + '@swc/core-darwin-x64': 1.5.7 + '@swc/core-linux-arm-gnueabihf': 1.5.7 + '@swc/core-linux-arm64-gnu': 1.5.7 + '@swc/core-linux-arm64-musl': 1.5.7 + '@swc/core-linux-x64-gnu': 1.5.7 + '@swc/core-linux-x64-musl': 1.5.7 + '@swc/core-win32-arm64-msvc': 1.5.7 + '@swc/core-win32-ia32-msvc': 1.5.7 + '@swc/core-win32-x64-msvc': 1.5.7 '@swc/counter@0.1.3': {} - '@swc/types@0.1.6': + '@swc/types@0.1.7': dependencies: '@swc/counter': 0.1.3 @@ -2252,9 +2246,7 @@ snapshots: '@types/estree@1.0.5': {} - '@types/json-schema@7.0.15': {} - - '@types/node@20.12.11': + '@types/node@20.12.12': dependencies: undici-types: 5.26.5 @@ -2269,96 +2261,93 @@ snapshots: '@types/prop-types': 15.7.12 csstype: 3.1.3 - '@types/semver@7.5.8': {} - - '@typescript-eslint/eslint-plugin@7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@7.9.0(@typescript-eslint/parser@7.9.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.8.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 7.8.0 - '@typescript-eslint/type-utils': 7.8.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.8.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.8.0 - debug: 4.3.4 + '@typescript-eslint/parser': 7.9.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.9.0 + '@typescript-eslint/type-utils': 7.9.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.9.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.9.0 eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 - semver: 7.6.1 ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/parser@7.9.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: - '@typescript-eslint/scope-manager': 7.8.0 - '@typescript-eslint/types': 7.8.0 - '@typescript-eslint/typescript-estree': 7.8.0(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.8.0 + '@typescript-eslint/scope-manager': 7.9.0 + '@typescript-eslint/types': 7.9.0 + '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.9.0 debug: 4.3.4 eslint: 8.57.0 + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@7.8.0': + '@typescript-eslint/scope-manager@7.9.0': dependencies: - '@typescript-eslint/types': 7.8.0 - '@typescript-eslint/visitor-keys': 7.8.0 + '@typescript-eslint/types': 7.9.0 + '@typescript-eslint/visitor-keys': 7.9.0 - '@typescript-eslint/type-utils@7.8.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/type-utils@7.9.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: - '@typescript-eslint/typescript-estree': 7.8.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.8.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.9.0(eslint@8.57.0)(typescript@5.4.5) debug: 4.3.4 eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@7.8.0': {} + '@typescript-eslint/types@7.9.0': {} - '@typescript-eslint/typescript-estree@7.8.0(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@7.9.0(typescript@5.4.5)': dependencies: - '@typescript-eslint/types': 7.8.0 - '@typescript-eslint/visitor-keys': 7.8.0 + '@typescript-eslint/types': 7.9.0 + '@typescript-eslint/visitor-keys': 7.9.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.4 - semver: 7.6.1 + semver: 7.6.2 ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.8.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/utils@7.9.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 7.8.0 - '@typescript-eslint/types': 7.8.0 - '@typescript-eslint/typescript-estree': 7.8.0(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.9.0 + '@typescript-eslint/types': 7.9.0 + '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) eslint: 8.57.0 - semver: 7.6.1 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@7.8.0': + '@typescript-eslint/visitor-keys@7.9.0': dependencies: - '@typescript-eslint/types': 7.8.0 + '@typescript-eslint/types': 7.9.0 eslint-visitor-keys: 3.4.3 '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-react-swc@3.6.0(vite@5.2.11)': + '@vitejs/plugin-react-swc@3.6.0(vite@5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0))': dependencies: - '@swc/core': 1.5.5 - vite: 5.2.11(@types/node@20.12.11)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0) + '@swc/core': 1.5.7 + vite: 5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0) transitivePeerDependencies: - '@swc/helpers' @@ -3118,7 +3107,7 @@ snapshots: ignore@5.3.1: {} - immutable@4.3.5: {} + immutable@4.3.6: {} import-fresh@3.3.0: dependencies: @@ -3527,7 +3516,7 @@ snapshots: pathe@0.2.0: {} - picocolors@1.0.0: {} + picocolors@1.0.1: {} picomatch@2.3.1: {} @@ -3536,7 +3525,7 @@ snapshots: postcss@8.4.38: dependencies: nanoid: 3.3.7 - picocolors: 1.0.0 + picocolors: 1.0.1 source-map-js: 1.2.0 prelude-ls@1.2.1: {} @@ -3672,7 +3661,7 @@ snapshots: sass@1.77.1: dependencies: chokidar: 3.6.0 - immutable: 4.3.5 + immutable: 4.3.6 source-map-js: 1.2.0 scheduler@0.23.2: @@ -3681,7 +3670,7 @@ snapshots: semver@6.3.1: {} - semver@7.6.1: {} + semver@7.6.2: {} set-function-length@1.2.2: dependencies: @@ -3890,7 +3879,7 @@ snapshots: util-deprecate@1.0.2: {} - vite-plugin-html@3.2.2(vite@5.2.11): + vite-plugin-html@3.2.2(vite@5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0)): dependencies: '@rollup/pluginutils': 4.2.1 colorette: 2.0.20 @@ -3904,25 +3893,25 @@ snapshots: html-minifier-terser: 6.1.0 node-html-parser: 5.4.2 pathe: 0.2.0 - vite: 5.2.11(@types/node@20.12.11)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0) + vite: 5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0) - vite-plugin-singlefile@2.0.1(rollup@4.17.2)(vite@5.2.11): + vite-plugin-singlefile@2.0.1(rollup@4.17.2)(vite@5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0)): dependencies: micromatch: 4.0.5 rollup: 4.17.2 - vite: 5.2.11(@types/node@20.12.11)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0) + vite: 5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0) - vite@5.2.11(@types/node@20.12.11)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0): + vite@5.2.11(@types/node@20.12.12)(lightningcss@1.24.1)(sass@1.77.1)(terser@5.31.0): dependencies: - '@types/node': 20.12.11 esbuild: 0.20.2 - lightningcss: 1.24.1 postcss: 8.4.38 rollup: 4.17.2 - sass: 1.77.1 - terser: 5.31.0 optionalDependencies: + '@types/node': 20.12.12 fsevents: 2.3.3 + lightningcss: 1.24.1 + sass: 1.77.1 + terser: 5.31.0 wcwidth@1.0.1: dependencies: diff --git a/ui/src/Node.tsx b/ui/src/Node.tsx index c1c6f62ee..64b88ba20 100644 --- a/ui/src/Node.tsx +++ b/ui/src/Node.tsx @@ -1,15 +1,15 @@ import {HierarchyRectangularNode} from "d3-hierarchy"; -import React, {useLayoutEffect, useMemo, useRef} from "react"; +import React, {useEffect, useLayoutEffect, useMemo, useRef} from "react"; import {Entry} from "./tool/entry.ts"; import {NodeColorGetter} from "./tool/color.ts"; import {PADDING, TOP_PADDING} from "./tool/const.ts"; import {trimPrefix} from "./tool/utils.ts"; +import {globalNodeCache} from "./cache.ts"; type NodeEventHandler = (event: HierarchyRectangularNode) => void; export interface NodeProps { node: HierarchyRectangularNode; - onMouseOver: NodeEventHandler; selected: boolean; onClick: NodeEventHandler; getModuleColor: NodeColorGetter; @@ -18,12 +18,20 @@ export interface NodeProps { export const Node: React.FC = ( { node, - onMouseOver, onClick, selected, getModuleColor } ) => { + useEffect(() => { + globalNodeCache.set(node.data.getID(), node) + + return () => { + // well, I think it won't be called :) + globalNodeCache.delete(node.data.getID()) + } + }, [node]); + const {backgroundColor, fontColor} = getModuleColor(node); const {x0, x1, y1, y0, children = null} = node; @@ -94,10 +102,7 @@ export const Node: React.FC = ( event.stopPropagation(); onClick(node); }} - onMouseOver={(event) => { - event.stopPropagation(); - onMouseOver(node); - }} + data-id={node.data.getID()} > new Entry(loadData()), []) @@ -40,7 +35,7 @@ function TreeMap() { //.paddingOuter(2) .paddingTop(20) .round(true) - .tile(treemapResquarify); + .tile(treemapResquarify.ratio(1)); }, [height, width]) const [selectedNode, setSelectedNode] = useState | null>(null) @@ -60,21 +55,6 @@ function TreeMap() { return selectedNodeLeaveSet.has(node) ? 1 : 0 }, [selectedNode, selectedNodeLeaveSet]) - const [showTooltip, setShowTooltip] = useState(false); - const [tooltipNode, setTooltipNode] = useState< - HierarchyRectangularNode | undefined - >(undefined); - - useEffect(() => { - const handleMouseOut = () => { - setShowTooltip(false); - }; - - document.addEventListener("mouseover", handleMouseOut); - return () => { - document.removeEventListener("mouseover", handleMouseOut); - }; - }, []); const root = useMemo(() => { const rootWithSizesAndSorted = rawHierarchy @@ -106,6 +86,67 @@ function TreeMap() { return nestedData; }, [root]); + const [showTooltip, setShowTooltip] = useState(false); + const [tooltipNode, setTooltipNode] = + useState | undefined>(undefined); + + const svgRef = useRef(null); + + useEffect(() => { + if (!svgRef.current) { + return; + } + const svg = svgRef.current; + + const visibleListener = (value: boolean) => { + return () => { + setShowTooltip(value); + } + } + const enter = visibleListener(true); + const leave = visibleListener(false); + + svg.addEventListener("mouseenter", enter); + svg.addEventListener("mouseleave", leave); + + return () => { + svg.removeEventListener("mouseenter", enter); + svg.removeEventListener("mouseleave", leave); + } + }, []); + + useEffect(() => { + const moveListener = (e: MouseEvent) => { + if (!e.target) { + return; + } + + const target = (e.target as SVGElement).parentNode; + if (!target) { + return; + } + + const dataIdStr = (target as Element).getAttribute("data-id"); + if (!dataIdStr) { + return; + } + + const dataId = parseInt(dataIdStr); + + const node = globalNodeCache.get(dataId); + if (!node) { + return; + } + + setTooltipNode(node); + } + + document.addEventListener("mousemove", moveListener); + return () => { + document.removeEventListener("mousemove", moveListener); + } + }, []); + return ( <> @@ -118,12 +159,6 @@ function TreeMap() { { - setTooltipNode(node); - if (!showTooltip) { - setShowTooltip(true); - } - }} selected={selectedNode?.data?.getID() === node.data.getID()} onClick={(node) => { setSelectedNode(selectedNode?.data?.getID() === node.data.getID() ? null : node); diff --git a/ui/src/cache.ts b/ui/src/cache.ts new file mode 100644 index 000000000..7378408b4 --- /dev/null +++ b/ui/src/cache.ts @@ -0,0 +1,4 @@ +import {Entry} from "./tool/entry.ts"; +import {HierarchyRectangularNode} from "d3-hierarchy"; + +export const globalNodeCache = new Map> diff --git a/ui/src/tool/entry.ts b/ui/src/tool/entry.ts index 188aa336a..4e27f01c1 100644 --- a/ui/src/tool/entry.ts +++ b/ui/src/tool/entry.ts @@ -10,7 +10,7 @@ import { Section, Symbol as FileSymbol } from "../generated/schema.ts"; -import {id} from "./id.ts"; +import {orderedID} from "./id.ts"; import {formatBytes, title} from "./utils.ts"; import {max} from "d3-array"; @@ -24,7 +24,7 @@ export class Entry { private readonly size: number; private readonly name: string; private readonly children: Entry[] = []; - private readonly uid = id(); + private readonly uid = orderedID(); explain: string = ""; // should only be used by the container type constructor(data: Candidate) @@ -198,9 +198,13 @@ export class Entry { return this.children; } - public getID(): string { + public getIDString(): string { return this.uid.toString(16); } + + public getID(): number { + return this.uid; + } } function childrenFromPackage(pkg: Package): Entry[] { diff --git a/ui/src/tool/id.ts b/ui/src/tool/id.ts index 032a9b028..a7e9abd50 100644 --- a/ui/src/tool/id.ts +++ b/ui/src/tool/id.ts @@ -1,5 +1,7 @@ let count = 1; -export function id() { +export function orderedID() { return count++; } + + From eb67a329447d5d91875d14a14f2b3db459aaaa9c Mon Sep 17 00:00:00 2001 From: Zxilly Date: Wed, 15 May 2024 20:41:21 +0800 Subject: [PATCH 3/4] perf: optimize render performance --- ui/src/Node.tsx | 2 +- ui/src/TreeMap.tsx | 47 ++++++++++++++++++++++++++++++++++++-------- ui/src/tool/entry.ts | 4 ---- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/ui/src/Node.tsx b/ui/src/Node.tsx index 64b88ba20..20822d10b 100644 --- a/ui/src/Node.tsx +++ b/ui/src/Node.tsx @@ -43,7 +43,7 @@ export const Node: React.FC = ( const textProps = useMemo(() => { return { - "fontSize": "0.9em", + "fontSize": "0.8em", "dominantBaseline": "middle", "textAnchor": "middle", x: width / 2, diff --git a/ui/src/TreeMap.tsx b/ui/src/TreeMap.tsx index e22323e97..3ddbbb483 100644 --- a/ui/src/TreeMap.tsx +++ b/ui/src/TreeMap.tsx @@ -1,5 +1,5 @@ import {loadData} from "./tool/utils.ts"; -import {useCallback, useEffect, useMemo, useRef, useState} from "react"; +import React, {useCallback, useEffect, useMemo, useRef, useState} from "react"; import {Entry} from "./tool/entry.ts"; import {useWindowSize} from "usehooks-ts"; import {hierarchy, HierarchyNode, HierarchyRectangularNode, treemap, treemapResquarify} from "d3-hierarchy"; @@ -32,10 +32,9 @@ function TreeMap() { return treemap() .size([width, height]) .paddingInner(2) - //.paddingOuter(2) .paddingTop(20) .round(true) - .tile(treemapResquarify.ratio(1)); + .tile(treemapResquarify); }, [height, width]) const [selectedNode, setSelectedNode] = useState | null>(null) @@ -147,10 +146,43 @@ function TreeMap() { } }, []); + const nodes = useMemo(() => { + return ( + + ) + }, [getModuleColor, nestedData, selectedNode]) + return ( <> - + + {nodes} + + + ) +} + +interface NodesProps { + nestedData: { key: number, values: HierarchyRectangularNode[] }[] + selectedNode: HierarchyRectangularNode | null + getModuleColor: (node: HierarchyNode) => { backgroundColor: string, fontColor: string } + setSelectedNode: (node: HierarchyRectangularNode | null) => void +} + +const Nodes: React.FC = + ({ + nestedData, + selectedNode, + getModuleColor, + setSelectedNode + }) => { + return ( + <> {nestedData.map(({key, values}) => { return ( @@ -170,9 +202,8 @@ function TreeMap() { ); })} - - - ) -} + + ) + } export default TreeMap diff --git a/ui/src/tool/entry.ts b/ui/src/tool/entry.ts index 4e27f01c1..73e883fc1 100644 --- a/ui/src/tool/entry.ts +++ b/ui/src/tool/entry.ts @@ -198,10 +198,6 @@ export class Entry { return this.children; } - public getIDString(): string { - return this.uid.toString(16); - } - public getID(): number { return this.uid; } From cc70eaf6994294fcf7e5f2596d3eefe72f59156a Mon Sep 17 00:00:00 2001 From: Zxilly Date: Wed, 15 May 2024 20:54:57 +0800 Subject: [PATCH 4/4] docs: update webui preview --- README.md | 2 +- README_zh-CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 91a26b39e..3524cfd85 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ You can click to expand the package to see the details. $ gsa --tui golang-compiled-binary ``` -![image](https://github.com/Zxilly/go-size-analyzer/assets/31370133/04556f54-7ebb-42b8-ac57-91a17887a44e) +![image](https://github.com/Zxilly/go-size-analyzer/assets/31370133/e69583ce-b189-4a0d-b108-c3b7d5c33a82) > [!NOTE] > There may be a problem with the UI display on Windows, which is caused by dependent libraries. diff --git a/README_zh-CN.md b/README_zh-CN.md index d4fbf101c..5a9318f5c 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -37,7 +37,7 @@ $ gsa --web golang-compiled-binary 网页将如下所示: -![image](https://github.com/Zxilly/go-size-analyzer/assets/31370133/78bb8105-fc5a-4852-8704-8c2fac3bf475) +![image](https://github.com/Zxilly/go-size-analyzer/assets/31370133/e69583ce-b189-4a0d-b108-c3b7d5c33a82) 您可以点击以展开包以查看详细信息。