From 33ceabf630656762790faf69209401580be9e81d Mon Sep 17 00:00:00 2001 From: Francisco Lopez Date: Wed, 3 Jan 2024 23:00:14 -0500 Subject: [PATCH 1/4] Was able to get the nodes to render on the screen using d3, still working on adding edges and getting the positioning of the nodes to represent a tree shape. --- package-lock.json | 334 +++++++++++++++++++++++++++++++++++- package.json | 1 + src/getNonce 2.js | 11 ++ src/parser.ts | 5 + src/treeTemplates/tree 2.js | 11 ++ src/types/hierarchyData.ts | 10 ++ src/types/tree.ts | 1 + src/webview/Flow.tsx | 67 +++++++- webpack.config 2.js | 32 ++++ 9 files changed, 462 insertions(+), 10 deletions(-) create mode 100644 src/getNonce 2.js create mode 100644 src/treeTemplates/tree 2.js create mode 100644 src/types/hierarchyData.ts create mode 100644 webpack.config 2.js diff --git a/package-lock.json b/package-lock.json index 2fe2a0b..c443ff2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "babel": "^6.23.0", "babel-loader": "^9.1.3", "css-loader": "^6.8.1", + "d3": "^7.8.5", "react": "^18.2.0", "react-dom": "^18.2.0", "reactflow": "^11.10.1", @@ -3440,13 +3441,13 @@ "version": "15.7.11", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", - "devOptional": true + "dev": true }, "node_modules/@types/react": { "version": "18.2.45", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.45.tgz", "integrity": "sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg==", - "devOptional": true, + "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3466,7 +3467,7 @@ "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "devOptional": true + "dev": true }, "node_modules/@types/vscode": { "version": "1.84.1", @@ -4486,7 +4487,92 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true + "dev": true + }, + "node_modules/d3": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz", + "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } }, "node_modules/d3-color": { "version": "3.1.0", @@ -4496,6 +4582,28 @@ "node": ">=12" } }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-dispatch": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", @@ -4516,6 +4624,38 @@ "node": ">=12" } }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", @@ -4524,6 +4664,57 @@ "node": ">=12" } }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, "node_modules/d3-interpolate": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", @@ -4535,6 +4726,65 @@ "node": ">=12" } }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-selection": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", @@ -4543,6 +4793,39 @@ "node": ">=12" } }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-timer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", @@ -4618,6 +4901,14 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/delaunator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", + "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", + "dependencies": { + "robust-predicates": "^3.0.0" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -5236,6 +5527,17 @@ "node": ">= 6" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", @@ -5386,6 +5688,14 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -7501,6 +7811,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7524,11 +7839,21 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/sass-loader": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.2.tgz", @@ -8109,6 +8434,7 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index fbf98dd..a455535 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,7 @@ "babel": "^6.23.0", "babel-loader": "^9.1.3", "css-loader": "^6.8.1", + "d3": "^7.8.5", "react": "^18.2.0", "react-dom": "^18.2.0", "reactflow": "^11.10.1", diff --git a/src/getNonce 2.js b/src/getNonce 2.js new file mode 100644 index 0000000..bd01ad0 --- /dev/null +++ b/src/getNonce 2.js @@ -0,0 +1,11 @@ +function getNonce() { + let text = ""; + const possible = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for (let i = 0; i < 32; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return text; + } + +module.exports = { getNonce } \ No newline at end of file diff --git a/src/parser.ts b/src/parser.ts index 0c068f1..f16d5d1 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -71,6 +71,7 @@ export class Parser { reactRouter: false, reduxConnect: false, children: [], + parent: null, parentList: [], props: {}, error: '', @@ -180,6 +181,9 @@ export class Parser { if (componentTree.parentList.includes(componentTree.filePath)) { return; } + // if (typeof componentTree.parentList === 'string' && componentTree.parentList.includes(componentTree.filePath)) { + // return; + // } // Create abstract syntax tree of current component tree file let ast: babel.ParseResult; @@ -468,6 +472,7 @@ export class Parser { count: 1, props: props, children: [], + parent: parent.id, // consider adding the id to the parentList array somehow for D3 integration... parentList: [parent.filePath].concat(parent.parentList), error: '', diff --git a/src/treeTemplates/tree 2.js b/src/treeTemplates/tree 2.js new file mode 100644 index 0000000..ae488b7 --- /dev/null +++ b/src/treeTemplates/tree 2.js @@ -0,0 +1,11 @@ +const Tree = { + id: undefined, + fileName: undefined, + filePath: undefined, + // children & parentList should be populated with other Tree objects + children: [], + parentList: [], + isClientComponent: false +} + +module.exports = { Tree }; \ No newline at end of file diff --git a/src/types/hierarchyData.ts b/src/types/hierarchyData.ts new file mode 100644 index 0000000..fe3bb80 --- /dev/null +++ b/src/types/hierarchyData.ts @@ -0,0 +1,10 @@ +import { Tree } from "./tree" + + +export interface hierarchyData { + children?: hierarchyData[], + data: Tree, + depth: number, + height: number, + parent: hierarchyData | null +} \ No newline at end of file diff --git a/src/types/tree.ts b/src/types/tree.ts index 5b6eb7a..03506cb 100644 --- a/src/types/tree.ts +++ b/src/types/tree.ts @@ -11,6 +11,7 @@ export type Tree = { reactRouter: boolean; reduxConnect: boolean; children: Tree[]; + parent: string; parentList: string[]; props: { [key: string]: boolean; }; error: string; diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index 19d827c..7ceba22 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from "react"; +import React, { useCallback, useEffect, useRef } from "react"; import ReactFlow, { addEdge, MiniMap, @@ -12,13 +12,19 @@ import ReactFlow, { import "reactflow/dist/style.css"; import { ConnectionLineType } from "../types/connection"; import FlowBuilder from './flowBuilder'; +import * as d3 from 'd3'; +import { Tree } from "../types/tree"; +import { hierarchyData } from "../types/hierarchyData"; const onInit = (reactFlowInstance: ReactFlowInstance) => console.log("flow loaded:", reactFlowInstance); const OverviewFlow = () => { + const reactFlowWrapper = useRef(null); const initialNodes = []; const initialEdges = []; + const elements = []; + const edge = []; const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); @@ -33,26 +39,74 @@ const OverviewFlow = () => { const msg = e.data; // object containing type prop and value prop switch (msg.type) { case 'parsed-data': { - const results = new FlowBuilder(msg.value); - results.build(msg.settings) - setNodes(results.initialNodes); - setEdges(results.initialEdges); + // const results = new FlowBuilder(msg.value); + // results.build(msg.settings) + let data : object | undefined = msg.value; + console.log('data', data) + // setNodes(results.initialNodes); + // setEdges(results.initialEdges); + + // create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees + const root : any = d3.hierarchy(data) + console.log('root', root) + + + //create tree layout and give nodes their positions + const treeLayout = d3.tree() + treeLayout(root); + + root.each((node: any) : void => { + // console.log('node name',Object.keys(node)) + elements.push({ + id: node.data.name, + type: 'default', + data: { label: node.data.name }, + position: { x: node.x || 0, y: node.y || 0 }, + }); + + // figure out how to get edges to connect + if (node.data.parent) { + // elements.push(addEdge({ + // id: node.data.id, + // source: node.data.id, + // target: node.data.parent, + // // sourceHandle: null, + // // targetHandle: null, + // })) + } + }) break; } } }); + + setNodes(elements); + + //Rendering reactFlow + if (reactFlowWrapper.current) { + // Set initial position for the nodes + const initialPosition = { x: 0, y: 0 }; + // reactFlowWrapper.current?.fitView(initialPosition); + } + // assign root variable using d3.heirarchy(data[0]), this will use d3 to format our data in a easy way to visualize the heirarchy + // const elements: Tree[]; + }, []); return ( +
{ @@ -80,6 +134,7 @@ const OverviewFlow = () => { +
); }; diff --git a/webpack.config 2.js b/webpack.config 2.js new file mode 100644 index 0000000..f926942 --- /dev/null +++ b/webpack.config 2.js @@ -0,0 +1,32 @@ +const path = require('path') + + +module.exports = { +entry: './src/webview/index.jsx', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, './build'), + }, + resolve: { + extensions: ['.js', '.jsx', '.css'], + }, + module: { + rules: [ + { + test: /\.jsx?/, + exclude: /node_modules/, + use: { + loader: "babel-loader", + options: { + presets: ['@babel/preset-env', '@babel/preset-react'] + } + } + }, + { + test: /\.(scss|css)$/, + use: ["style-loader", "css-loader"], + }, + ] + }, + mode: "development" +} From b1914fda56ba9618fc1d2ebeaa0119885cf41c65 Mon Sep 17 00:00:00 2001 From: Francisco Lopez Date: Thu, 4 Jan 2024 23:07:42 -0500 Subject: [PATCH 2/4] Got the nodes to render as a tree structure using D3. Need to get the edges to connect upon rendering to finish the tree. --- src/webview/Flow.tsx | 53 +++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index 7ceba22..7859ebb 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -15,6 +15,7 @@ import FlowBuilder from './flowBuilder'; import * as d3 from 'd3'; import { Tree } from "../types/tree"; import { hierarchyData } from "../types/hierarchyData"; +import { getNonce } from "../getNonce"; const onInit = (reactFlowInstance: ReactFlowInstance) => console.log("flow loaded:", reactFlowInstance); @@ -24,7 +25,7 @@ const OverviewFlow = () => { const initialNodes = []; const initialEdges = []; const elements = []; - const edge = []; + const edgeArr = []; const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); @@ -52,7 +53,7 @@ const OverviewFlow = () => { //create tree layout and give nodes their positions - const treeLayout = d3.tree() + const treeLayout = d3.tree().size([500, 300]) treeLayout(root); root.each((node: any) : void => { @@ -61,25 +62,51 @@ const OverviewFlow = () => { id: node.data.name, type: 'default', data: { label: node.data.name }, - position: { x: node.x || 0, y: node.y || 0 }, + position: { x: node.x ? node.x : 0, y: node.y ? node.y : 0 }, + style: { + borderRadius: '6px', + borderWidth: '2px', + borderColor: '#6b7280', + display: 'flex', + justifyContent: 'center', + placeItems: 'center', + backgroundColor: `${(node.data.isClientComponent) ? '#fdba74' : '#93C5FD'}`, + } }); // figure out how to get edges to connect if (node.data.parent) { - // elements.push(addEdge({ - // id: node.data.id, - // source: node.data.id, - // target: node.data.parent, - // // sourceHandle: null, - // // targetHandle: null, - // })) + const newEdge = { + id: `${getNonce()}`, + source: node.data.parent, + target: node.data.id, + type: ConnectionLineType.Bezier, + animated: true + }; + + // Check if the edge already exists before adding + const edgeExists = edgeArr.some( + edge => edge[0].source === newEdge.source && edge[0].target === newEdge.target + ); + + if (!edgeExists) { + initialEdges.push(newEdge); + } } - }) + } + ) + console.log('Initial Edges', initialEdges) + setEdges(initialEdges) + console.log('Edges', edges) break; } } + + }); + + setNodes(elements); //Rendering reactFlow @@ -97,9 +124,9 @@ const OverviewFlow = () => {
Date: Sat, 6 Jan 2024 16:07:25 -0500 Subject: [PATCH 3/4] Got the React Flow diagram working --- src/webview/Flow.tsx | 151 ++++++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 66 deletions(-) diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index 7859ebb..40bed50 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -24,17 +24,35 @@ const OverviewFlow = () => { const reactFlowWrapper = useRef(null); const initialNodes = []; const initialEdges = []; + const initialEdge = []; const elements = []; - const edgeArr = []; + // const elementsRef = useRef(elements); + // const edgesRef = useRef(initialEdges) - const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); - const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); + const [nodes, setNodes, onNodesChange] = useNodesState([]); + const [edges, setEdges, onEdgesChange] = useEdgesState([]); const onConnect = useCallback( (params) => setEdges((eds) => addEdge({ ...params, type: ConnectionLineType.Bezier, animated: true }, eds)), [] ); + // const memoizedOnNodesChange = useCallback( + // (newNodes) => { + // setNodes(newNodes); + // elementsRef.current = newNodes; + // }, + // [setNodes] + // ); + + // const memoizedOnEdgesChange = useCallback( + // (newEdges) => { + // setEdges(newEdges); + // edgesRef.current = newEdges + // }, + // [setEdges] + // ); + useEffect(() => { window.addEventListener('message', (e) => { const msg = e.data; // object containing type prop and value prop @@ -42,72 +60,24 @@ const OverviewFlow = () => { case 'parsed-data': { // const results = new FlowBuilder(msg.value); // results.build(msg.settings) - let data : object | undefined = msg.value; - console.log('data', data) // setNodes(results.initialNodes); // setEdges(results.initialEdges); - - // create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees - const root : any = d3.hierarchy(data) - console.log('root', root) - - - //create tree layout and give nodes their positions - const treeLayout = d3.tree().size([500, 300]) - treeLayout(root); - - root.each((node: any) : void => { - // console.log('node name',Object.keys(node)) - elements.push({ - id: node.data.name, - type: 'default', - data: { label: node.data.name }, - position: { x: node.x ? node.x : 0, y: node.y ? node.y : 0 }, - style: { - borderRadius: '6px', - borderWidth: '2px', - borderColor: '#6b7280', - display: 'flex', - justifyContent: 'center', - placeItems: 'center', - backgroundColor: `${(node.data.isClientComponent) ? '#fdba74' : '#93C5FD'}`, - } - }); - - // figure out how to get edges to connect - if (node.data.parent) { - const newEdge = { - id: `${getNonce()}`, - source: node.data.parent, - target: node.data.id, - type: ConnectionLineType.Bezier, - animated: true - }; - - // Check if the edge already exists before adding - const edgeExists = edgeArr.some( - edge => edge[0].source === newEdge.source && edge[0].target === newEdge.target - ); - - if (!edgeExists) { - initialEdges.push(newEdge); - } - } - } - ) - console.log('Initial Edges', initialEdges) - setEdges(initialEdges) - console.log('Edges', edges) + let data : object | undefined = msg.value; + console.log('data', data) + mappedData(data) + console.log('nodes', elements) + setEdges(initialEdges); + setNodes(elements) + console.log('edges: ', edges); break; } } - - }); - - - setNodes(elements); + + + // memoizedOnEdgesChange(edgesRef.current); + // memoizedOnNodesChange(elementsRef.current); //Rendering reactFlow if (reactFlowWrapper.current) { @@ -115,17 +85,66 @@ const OverviewFlow = () => { const initialPosition = { x: 0, y: 0 }; // reactFlowWrapper.current?.fitView(initialPosition); } - // assign root variable using d3.heirarchy(data[0]), this will use d3 to format our data in a easy way to visualize the heirarchy - // const elements: Tree[]; }, []); + function mappedData (data) { + // create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees + const root : any = d3.hierarchy(data) + console.log('root', root) + + + //create tree layout and give nodes their positions + const treeLayout = d3.tree().size([800, 500]) + treeLayout(root); + + root.each((node: any) : void => { + + elements.push({ + id: node.data.id, + type: 'default', + data: { label: node.data.name }, + position: { x: node.x ? node.x : 0, y: node.y ? node.y : 0 }, + style: { + borderRadius: '6px', + borderWidth: '2px', + borderColor: '#6b7280', + display: 'flex', + justifyContent: 'center', + placeItems: 'center', + backgroundColor: `${(node.data.isClientComponent) ? '#fdba74' : '#93C5FD'}`, + } + }); + + // figure out how to get edges to connect + if (node.data.parent) { + const newEdge = { + id: `${getNonce()}`, + source: node.data.parent, + target: node.data.id, + type: ConnectionLineType.Bezier, + animated: true, + }; + + + // Check if the edge already exists before adding + const edgeExists = initialEdges.some( + edge => edge.source === newEdge.source && edge.target === newEdge.target + ); + + if (!edgeExists) { + initialEdges.push(newEdge) + } + } + } + ) + + } + return (
Date: Sat, 6 Jan 2024 16:26:52 -0500 Subject: [PATCH 4/4] Cleaned up Flow.tsx, Still need to fully convert to TypeScript now that the mapping is working properly. --- src/webview/Flow.tsx | 61 ++++++++++++-------------------------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index 40bed50..9ccd323 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -24,11 +24,7 @@ const OverviewFlow = () => { const reactFlowWrapper = useRef(null); const initialNodes = []; const initialEdges = []; - const initialEdge = []; - const elements = []; - // const elementsRef = useRef(elements); - // const edgesRef = useRef(initialEdges) - + const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); @@ -37,70 +33,44 @@ const OverviewFlow = () => { [] ); - // const memoizedOnNodesChange = useCallback( - // (newNodes) => { - // setNodes(newNodes); - // elementsRef.current = newNodes; - // }, - // [setNodes] - // ); - - // const memoizedOnEdgesChange = useCallback( - // (newEdges) => { - // setEdges(newEdges); - // edgesRef.current = newEdges - // }, - // [setEdges] - // ); useEffect(() => { window.addEventListener('message', (e) => { - const msg = e.data; // object containing type prop and value prop + // object containing type prop and value prop + const msg = e.data; + switch (msg.type) { case 'parsed-data': { - // const results = new FlowBuilder(msg.value); - // results.build(msg.settings) - // setNodes(results.initialNodes); - // setEdges(results.initialEdges); let data : object | undefined = msg.value; console.log('data', data) mappedData(data) - console.log('nodes', elements) + console.log('nodes', initialNodes) setEdges(initialEdges); - setNodes(elements) + setNodes(initialNodes) console.log('edges: ', edges); break; } } }); - - - - // memoizedOnEdgesChange(edgesRef.current); - // memoizedOnNodesChange(elementsRef.current); - - //Rendering reactFlow - if (reactFlowWrapper.current) { - // Set initial position for the nodes - const initialPosition = { x: 0, y: 0 }; - // reactFlowWrapper.current?.fitView(initialPosition); - } - }, []); + + // Function that creates Tree Structure function mappedData (data) { - // create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees + + // Create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees const root : any = d3.hierarchy(data) console.log('root', root) - //create tree layout and give nodes their positions const treeLayout = d3.tree().size([800, 500]) treeLayout(root); + // Iterate through each Tree and create a node root.each((node: any) : void => { - elements.push({ + // Create a Node from the current Root and add it to our nodes array + initialNodes.push({ id: node.data.id, type: 'default', data: { label: node.data.name }, @@ -116,7 +86,7 @@ const OverviewFlow = () => { } }); - // figure out how to get edges to connect + // If the current node has a parent, create an edge to show relationship if (node.data.parent) { const newEdge = { id: `${getNonce()}`, @@ -131,7 +101,8 @@ const OverviewFlow = () => { const edgeExists = initialEdges.some( edge => edge.source === newEdge.source && edge.target === newEdge.target ); - + + // If edge does not exist, add to our edges array if (!edgeExists) { initialEdges.push(newEdge) }