diff --git a/frontend/package.json b/frontend/package.json index 54af012..0cbe400 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,6 +5,8 @@ "@ant-design/charts": "^1.4.2", "@ant-design/icons": "^5.2.0", "@ant-design/plots": "^2.1.12", + "@antv/g6": "^5.0.50", + "@antv/graphin": "^3.0.5", "antd": "^5.13.2", "prismjs": "^1.29.0", "react": "^18.2.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index f4cfe3d..7ff5b87 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -20,6 +20,12 @@ importers: '@ant-design/plots': specifier: ^2.1.12 version: 2.1.12(lodash-es@4.17.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@antv/g6': + specifier: ^5.0.50 + version: 5.0.50(workerize-loader@2.0.2(webpack@4.19.1)) + '@antv/graphin': + specifier: ^3.0.5 + version: 3.0.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(workerize-loader@2.0.2(webpack@4.19.1)) antd: specifier: ^5.13.2 version: 5.13.2(moment@2.30.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -196,6 +202,9 @@ packages: '@antv/component@0.8.35': resolution: {integrity: sha512-VnRa5X77nBPI952o2xePEEMSNZ6g2mcUDrQY8mVL2kino/8TFhqDq5fTRmDXZyWyIYd4ulJTz5zgeSwAnX/INQ==} + '@antv/component@2.1.11': + resolution: {integrity: sha512-dTdz8VAd3rpjOaGEZTluz82mtzrP4XCtNlNQyrxY7VNRNcjtvpTLDn57bUL2lRu1T+iklKvgbE2llMriWkq9vQ==} + '@antv/component@2.1.2': resolution: {integrity: sha512-5nC9i9lh5rBHE+pk4TNnerLe4mn5874YHHhvv6EdL618UkgpdKJL0hJu4l7uAYjZ3g46VBK+IYT7md0FYv8f4w==} @@ -220,12 +229,18 @@ packages: '@antv/g-camera-api@2.0.33': resolution: {integrity: sha512-ANetXo7FPscqflz+xlmx9yB/M3fN9j7Lymc0SfDMGqgOrurQJWvK0ZQHfkDO7a430ykatvmh9t+4V4ZZNsoyJw==} + '@antv/g-camera-api@2.0.41': + resolution: {integrity: sha512-dF52/wpzHDKi7ZzPlaHurEjWrF9aBKL2udDwQkEeVtfkJ0DHaavr3BAvhuGhtHoecRYQJvpzP1OkGNDLQJQQlw==} + '@antv/g-canvas@0.5.17': resolution: {integrity: sha512-sXYJMWTOlb/Ycb6sTKu00LcJqInXJY4t99+kSM40u2OfqrXYmaXDjHR7D2V0roMkbK/QWiWS9UnEidCR1VtMOA==} '@antv/g-canvas@2.0.37': resolution: {integrity: sha512-6LtBG+U+vk6IwOLTbeDhDglezGDZKSPv6dB7nio0ahqfVtUqSkEWKbNqtzzihCmg9Du9HII7fbaT2VehFRbj4A==} + '@antv/g-canvas@2.0.48': + resolution: {integrity: sha512-P98cTLRbKbCAcUVgHqMjKcvOany6nR7wvt+g+sazIfKSMUCWgjLTOjlLezux2up3At29mt80StaV2AR3d61YQA==} + '@antv/g-device-api@1.6.13': resolution: {integrity: sha512-lTvlSHYDZyWJnAR1W8DOQLwUo32VpRopbS/BPQqStcOV6FqaC+u5YjT50KbJ+oBWcorpzfknhICRwEA3Xm8t9Q==} @@ -235,12 +250,18 @@ packages: '@antv/g-dom-mutation-observer-api@2.0.30': resolution: {integrity: sha512-xwFOvVjZM6stXUlBl851I3tLgUDJzSadI7m820OKQghVBx2qCSV6IvY2DfLTsURBl/FgRqIpDpBz/hr6eVWjkQ==} + '@antv/g-dom-mutation-observer-api@2.0.38': + resolution: {integrity: sha512-xzgbt8GUOiToBeDVv+jmGkDE+HtI9tD6uO8TirJbCya88DKcY/jurQALq0NdWKgMJLn7WPiUKyDwHWimwQcBJw==} + '@antv/g-lite@1.2.24': resolution: {integrity: sha512-7FfySdANOtn2zKq41gbRj30KJ0TpnWDfyvAENVQ6Hbfqmst3/LP14rKwBmFTavjl3POdruf/dh4w6JX2gR/rUA==} '@antv/g-lite@2.2.14': resolution: {integrity: sha512-R38qz8dk6fs9L6Ko3n3sv+eOeFZsGKS+NHcr7Jpuawj9jVrA676b//1aeZuzxmRqv7rNxVD+cPzl0iScZdBroQ==} + '@antv/g-lite@2.3.2': + resolution: {integrity: sha512-fkIxRoqLOGsNPwsp26bPp58cPWuX3E4wQ9cfkB/DHy5LtLrPpvOwHWB3+MBPgZwzk8jTTjchiXa756ZFOAWyQQ==} + '@antv/g-math@0.1.9': resolution: {integrity: sha512-KHMSfPfZ5XHM1PZnG42Q2gxXfOitYveNTA7L61lR6mhZ8Y/aExsYmHqaKBsSarU0z+6WLrl9C07PQJZaw0uljQ==} @@ -250,27 +271,51 @@ packages: '@antv/g-math@3.0.0': resolution: {integrity: sha512-AkmiNIEL1vgqTPeGY2wtsMdBBqKFwF7SKSgs+D1iOS/rqYMsXdhp/HvtuQ5tx/HdawE/ZzTiicIYopc520ADZw==} + '@antv/g-math@3.0.1': + resolution: {integrity: sha512-FvkDBNRpj+HsLINunrL2PW0OlG368MlpHuihbxleuajGim5kra8tgISwCLmAf8Yz2b1CgZ9PvpohqiLzHS7HLg==} + '@antv/g-plugin-canvas-path-generator@2.1.14': resolution: {integrity: sha512-c8IoFaQ/xZ43DS9uWwF9uZxgMRomqQ/d6DZVgK4hw7kdmv0OQKm0HfZIisMrQIV353poa0dEYpGrH2Kq3syzBg==} + '@antv/g-plugin-canvas-path-generator@2.1.22': + resolution: {integrity: sha512-Z0IawzTGgTppa9IpkNNKsqgoU89oOjUsiU8GZZlkDkUggQTHP0wOxTeLAb43YgClx3aTI3bRs44uMQutNdSVxw==} + '@antv/g-plugin-canvas-picker@2.1.16': resolution: {integrity: sha512-W19ryBxUl/jkg4MjsBbh+9GIiA1aj7Xq4C3i4enEat1O+SNQQwDbyQmryDQQZmeFygqRRA5yARLIg8oHlaMD/Q==} + '@antv/g-plugin-canvas-picker@2.1.27': + resolution: {integrity: sha512-DHQ0YLYNXAm6O63pW6nKs/R0fuqlUYfehNs/EtzrmqyUkKASd/Vhs4HLNeHTMUdBMgg41T+x5qay0GGttK4Xdw==} + '@antv/g-plugin-canvas-renderer@2.2.16': resolution: {integrity: sha512-VumeakqQ2pGcb/w8NGgM2Gy9YHP5lcB76Dvsv6qnP71FUIz2YLLZ7O77WBUT3ePQRQjiQt8GYOLaXZpOntc3SQ==} + '@antv/g-plugin-canvas-renderer@2.3.3': + resolution: {integrity: sha512-d6JkZy1YmLnvI9wsbO8QVpBz7z7tl6JRQkF5hx9XLDtf2fD4n83KINeMq13skiNwaiudS771WWiBtfzUHB73pQ==} + '@antv/g-plugin-dom-interaction@2.1.19': resolution: {integrity: sha512-xuhK/WEn4Luu+3qT6JvxqKRc6Sd3Z9Wx4eTfq6LMiPtZWKhuXOARGcYElMQ82xgmmv8t04/GXXPhcbtRbQ+yRw==} + '@antv/g-plugin-dom-interaction@2.1.27': + resolution: {integrity: sha512-hltVZZH+bj0uXmGSR+6BIwhCFYyHmDIQi3vrj/Wn1Dn6PgufvMCXfjr3DfmkQnY+FFP8ZCpg5N9MaE0BE9OddA==} + '@antv/g-plugin-dragndrop@2.0.30': resolution: {integrity: sha512-Etcnnv+6hyyk9XPdX4XQBoZ++NqW7zh4VDY0nttrDSAQwmE1+DGkG62x6uE0iCSJs1FRXZUZNpQrDqFj0Ca6Ew==} + '@antv/g-plugin-dragndrop@2.0.38': + resolution: {integrity: sha512-yCef5ER759i0WpuOekFQ+AcDTu0N/COMbkPOG6YuswVnhQH447GUpuNm7Le+Mq26qONlXTDyjxuMHoUOWwJ7Cw==} + '@antv/g-plugin-html-renderer@2.1.19': resolution: {integrity: sha512-x/a/uuLcczoVfz6WqwxwIggtzM0JXSgIlJMV3etGRGerovsb3skh56b/E5XoVWPI8dfS8xAoDsssMA/9FalR1g==} + '@antv/g-plugin-html-renderer@2.1.27': + resolution: {integrity: sha512-NnI4GxDBb71o/XZzoRdi0xI3xg7GJmthyO5xP5/MiOFmwJ/jW/QDz17vUonmzUVbCt6upikHV5GyYOaogRqdVg==} + '@antv/g-plugin-image-loader@2.1.16': resolution: {integrity: sha512-0NoyILV3shPWlnQvVRJFfqZAFUkYOGZWnrhwPFLYqKylVlV44tsOlCB9jxvG9u9ieOtY4kOmfgU5a8xnYahwMQ==} + '@antv/g-plugin-image-loader@2.1.26': + resolution: {integrity: sha512-AElV0QOX2LAhB3jr9XtvkynntuKhcaU5n7avu5ynM5VoAtMaJRANhCyefA2G3myeJxWcHk4nWDX6u4YMaZnnvw==} + '@antv/g-svg@0.5.7': resolution: {integrity: sha512-jUbWoPgr4YNsOat2Y/rGAouNQYGpw4R0cvlN0YafwOyacFFYy2zC8RslNd6KkPhhR3XHNSqJOuCYZj/YmLUwYw==} @@ -280,6 +325,9 @@ packages: '@antv/g-web-animations-api@2.1.19': resolution: {integrity: sha512-izzAgAxhIV3cZnyv8pqeOSmkMoV1hw7XzBBywbDbMd58d5208RSCBXHrQ68D/hLqzCgrooas5n+usxXWvKhD2A==} + '@antv/g-web-animations-api@2.1.28': + resolution: {integrity: sha512-V5g8bO2D1hb8fRMMi5hXL/De+1UDRzW3C5EX07oazR0q71GONASP+sVwniZdt9R1HAmJSN5dvW3SqWeU3EEstQ==} + '@antv/g-webgpu-core@0.5.6': resolution: {integrity: sha512-DPiH3GkAUiT0Q+LAKeImpI+IOQ/gP2w6HstYKivpFIpBPIvZ/9equM3icVrn1iDfDkZANVXQ1PppcO3xBv1ZTw==} @@ -329,15 +377,30 @@ packages: '@antv/g6@4.8.24': resolution: {integrity: sha512-bgj7sZ+z45JmOngIpYpwmSIg7SboMLZBoAlX0+RoAETZB3/xvZO0MXT3lCSyAhIgm5Sb68pekKi7OStuo04NyQ==} + '@antv/g6@5.0.50': + resolution: {integrity: sha512-L2ZdekSpJreIvSc4DkqGCh2bFmCadDZiR6q9euVtXdLeHPl/YQ4hqTvLIkc7aYO6oE/nC5mPAIOaM6ZiAy7QKA==} + '@antv/g@5.18.27': resolution: {integrity: sha512-SgJ3l7kNfJp0df7g8UItuNk5K7ctzik4z4ZmrXvz9f4cD/s7zfpvRWcIIyBaJQtJCaXtKVqP4wapeqhL7c95zQ==} '@antv/g@6.1.19': resolution: {integrity: sha512-lCLLmaXh5G7J4yKcz4UzUTbC+yHHieyvPdy/r2MXHkM0IiFWalfw+sd2reSwKOolgXPy4gHO1DxwpQTXoBt0hA==} + '@antv/g@6.1.28': + resolution: {integrity: sha512-BwavpbKGR4NEJD3BtVxfBFjCcxy5gsWoUNnBisfG1qfjhGTt7QvUYHFH46+mHJjHMIdYjuFw2T0ZYVtxBddxSg==} + + '@antv/graphin@3.0.5': + resolution: {integrity: sha512-V/j8R8Ty44wUqxVIYLdpPuIO8WWCTIVq1eBJg5YRunL5t5o5qAFpC/qkQxslbBMWyKdIH0oWBnvHA74riGi7cw==} + peerDependencies: + react: ^18.0.0 || ^19.1.0 + react-dom: ^18.0.0 || ^19.1.0 + '@antv/graphlib@1.2.0': resolution: {integrity: sha512-hhJOMThec51nU4Fe5p/viLlNIL71uDEgYFzKPajWjr2715SFG1HAgiP6AVylIeqBcAZ04u3Lw7usjl/TuI5RuQ==} + '@antv/graphlib@2.0.4': + resolution: {integrity: sha512-zc/5oQlsdk42Z0ib1mGklwzhJ5vczLFiPa1v7DgJkTbgJ2YxRh9xdarf86zI49sKVJmgbweRpJs7Nu5bIiwv4w==} + '@antv/hierarchy@0.6.14': resolution: {integrity: sha512-V3uknf7bhynOqQDw2sg+9r9DwZ9pc6k/EcqyTFdfXB1+ydr7urisP0MipIuimucvQKN+Qkd+d6w601r1UIroqQ==} @@ -385,6 +448,9 @@ packages: '@antv/layout@0.3.25': resolution: {integrity: sha512-d29Aw1PXoAavMRZy7iTB9L5rMBeChFEX0BJ9ELP4TI35ySdCu07YbmPo9ju9OH/6sG2/NB3o85Ayxrre3iwX/g==} + '@antv/layout@1.2.14-beta.9': + resolution: {integrity: sha512-wPlwBFMtq2lWZFc89/7Lzb8fjHnyKVZZ9zBb2h+zZIP0YWmVmHRE8+dqCiPKOyOGUXEdDtn813f1g107dCHZlg==} + '@antv/matrix-util@3.0.4': resolution: {integrity: sha512-BAPyu6dUliHcQ7fm9hZSGKqkwcjEDVLVAstlHULLvcMZvANHeLXgHEgV7JqcAV/GIhIz8aZChIlzM1ZboiXpYQ==} @@ -409,6 +475,12 @@ packages: '@antv/util@3.3.10': resolution: {integrity: sha512-basGML3DFA3O87INnzvDStjzS+n0JLEhRnRsDzP9keiXz8gT1z/fTdmJAZFOzMMWxy+HKbi7NbSt0+8vz/OsBQ==} + '@antv/util@3.3.11': + resolution: {integrity: sha512-FII08DFM4ABh2q5rPYdr0hMtKXRgeZazvXaFYCs7J7uTcWDHUhczab2qOCJLNDugoj8jFag1djb7wS9ehaRYBg==} + + '@antv/vendor@1.0.11': + resolution: {integrity: sha512-LmhPEQ+aapk3barntaiIxJ5VHno/Tyab2JnfdcPzp5xONh/8VSfed4bo/9xKo5HcUAEydko38vYLfj6lJliLiw==} + '@antv/x6-react-components@1.1.20': resolution: {integrity: sha512-HpQqjPCUo+jfcbfW2sr9oxuXMCxWnXxWvE8jXKJzvrlMNZ3kgfxNqMCRxwGi2QTCxLB3g/KYi5/n8kze8ui1/Q==} peerDependencies: @@ -1417,6 +1489,11 @@ packages: resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==} engines: {node: '>=4'} + '@naoak/workerize-transferable@0.1.0': + resolution: {integrity: sha512-fDLfuP71IPNP5+zSfxFb52OHgtjZvauRJWbVnpzQ7G7BjcbLjTny0OW1d3ZO806XKpLWNKmeeW3MhE0sy8iwYQ==} + peerDependencies: + workerize-loader: '*' + '@nodelib/fs.stat@1.1.3': resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==} engines: {node: '>= 6'} @@ -1613,9 +1690,66 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-dispatch@3.0.7': + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-shape@3.1.7': + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + '@types/d3-timer@2.0.3': resolution: {integrity: sha512-jhAJzaanK5LqyLQ50jJNIrB8fjL9gwWZTgYjevPvkDLMU+kTAZkYsobI59nYoeSrH1PucuyJEi247Pb90t6XUg==} + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} @@ -2268,6 +2402,9 @@ packages: bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + bubblesets-js@2.3.4: + resolution: {integrity: sha512-DyMjHmpkS2+xcFNtyN00apJYL3ESdp9fTrkDr5+9Qg/GPqFmcWgGsK1akZnttE1XFxJ/VMy4DNNGMGYtmFp1Sg==} + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -2489,6 +2626,9 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + comlink@4.4.2: + resolution: {integrity: sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==} + commander@2.13.0: resolution: {integrity: sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==} @@ -2741,6 +2881,9 @@ packages: resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} engines: {node: '>=12'} + d3-binarytree@1.0.2: + resolution: {integrity: sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==} + d3-collection@1.0.7: resolution: {integrity: sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==} @@ -2770,6 +2913,18 @@ packages: d3-ease@1.0.7: resolution: {integrity: sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ==} + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force-3d@3.0.6: + resolution: {integrity: sha512-4tsKHUPLOVkyfEffZo1v6sFHvGFwAIIjt/W8IThbp08DYAsXZck+2pSHEG5W1+gQgEvFLdZkYvmJAbRM2EzMnA==} + engines: {node: '>=12'} + d3-force@2.1.1: resolution: {integrity: sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==} @@ -2784,6 +2939,11 @@ packages: resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} engines: {node: '>=12'} + d3-geo-projection@4.0.0: + resolution: {integrity: sha512-p0bK60CEzph1iqmnxut7d/1kyTmm3UWtPlwdkM31AU+LW+BXazd5zJdoCn7VFxNCHXRngPHRnsNn5uGjLRGndg==} + engines: {node: '>=12'} + hasBin: true + d3-geo@3.1.1: resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} engines: {node: '>=12'} @@ -2805,6 +2965,9 @@ packages: resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} engines: {node: '>=12'} + d3-octree@1.1.0: + resolution: {integrity: sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A==} + d3-path@3.1.0: resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} engines: {node: '>=12'} @@ -2816,6 +2979,10 @@ packages: resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} engines: {node: '>=12'} + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + d3-regression@1.3.10: resolution: {integrity: sha512-PF8GWEL70cHHWpx2jUQXc68r1pyPHIA+St16muk/XRokETzlegj5LriNKg7o4LR0TySug4nHYPJNNRz/W+/Niw==} @@ -2826,6 +2993,10 @@ packages: d3-scale@2.2.2: resolution: {integrity: sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==} + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + d3-shape@3.2.0: resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} engines: {node: '>=12'} @@ -2836,6 +3007,10 @@ packages: d3-time@1.1.0: resolution: {integrity: sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==} + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + d3-timer@1.0.10: resolution: {integrity: sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==} @@ -4759,6 +4934,10 @@ packages: resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==} engines: {node: '>=4.0.0'} + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + locate-path@2.0.0: resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} engines: {node: '>=4'} @@ -7648,6 +7827,11 @@ packages: worker-farm@1.7.0: resolution: {integrity: sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==} + workerize-loader@2.0.2: + resolution: {integrity: sha512-HoZ6XY4sHWxA2w0WpzgBwUiR3dv1oo7bS+oCwIpb6n54MclQ/7KXdXsVIChTCygyuHtVuGBO1+i3HzTt699UJQ==} + peerDependencies: + webpack: '*' + wrap-ansi@2.1.0: resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} engines: {node: '>=0.10.0'} @@ -7907,6 +8091,13 @@ snapshots: fecha: 4.2.3 tslib: 2.8.1 + '@antv/component@2.1.11': + dependencies: + '@antv/g': 6.1.28 + '@antv/scale': 0.4.16 + '@antv/util': 3.3.11 + svg-path-parser: 1.1.0 + '@antv/component@2.1.2': dependencies: '@antv/g': 6.1.19 @@ -7961,6 +8152,14 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 + '@antv/g-camera-api@2.0.41': + dependencies: + '@antv/g-lite': 2.3.2 + '@antv/util': 3.3.11 + '@babel/runtime': 7.26.0 + gl-matrix: 3.4.3 + tslib: 2.8.1 + '@antv/g-canvas@0.5.17': dependencies: '@antv/g-base': 0.5.16 @@ -7984,6 +8183,19 @@ snapshots: '@babel/runtime': 7.26.0 tslib: 2.8.1 + '@antv/g-canvas@2.0.48': + dependencies: + '@antv/g-lite': 2.3.2 + '@antv/g-plugin-canvas-path-generator': 2.1.22 + '@antv/g-plugin-canvas-picker': 2.1.27 + '@antv/g-plugin-canvas-renderer': 2.3.3 + '@antv/g-plugin-dom-interaction': 2.1.27 + '@antv/g-plugin-html-renderer': 2.1.27 + '@antv/g-plugin-image-loader': 2.1.26 + '@antv/util': 3.3.11 + '@babel/runtime': 7.26.0 + tslib: 2.8.1 + '@antv/g-device-api@1.6.13': dependencies: '@antv/util': 3.3.10 @@ -8001,6 +8213,11 @@ snapshots: '@antv/g-lite': 2.2.14 '@babel/runtime': 7.26.0 + '@antv/g-dom-mutation-observer-api@2.0.38': + dependencies: + '@antv/g-lite': 2.3.2 + '@babel/runtime': 7.26.0 + '@antv/g-lite@1.2.24': dependencies: '@antv/g-math': 2.0.2 @@ -8022,6 +8239,17 @@ snapshots: rbush: 3.0.1 tslib: 2.8.1 + '@antv/g-lite@2.3.2': + dependencies: + '@antv/g-math': 3.0.1 + '@antv/util': 3.3.11 + '@antv/vendor': 1.0.11 + '@babel/runtime': 7.26.0 + eventemitter3: 5.0.1 + gl-matrix: 3.4.3 + rbush: 3.0.1 + tslib: 2.8.1 + '@antv/g-math@0.1.9': dependencies: '@antv/util': 2.0.17 @@ -8039,6 +8267,13 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 + '@antv/g-math@3.0.1': + dependencies: + '@antv/util': 3.3.11 + '@babel/runtime': 7.26.0 + gl-matrix: 3.4.3 + tslib: 2.8.1 + '@antv/g-plugin-canvas-path-generator@2.1.14': dependencies: '@antv/g-lite': 2.2.14 @@ -8047,6 +8282,14 @@ snapshots: '@babel/runtime': 7.26.0 tslib: 2.8.1 + '@antv/g-plugin-canvas-path-generator@2.1.22': + dependencies: + '@antv/g-lite': 2.3.2 + '@antv/g-math': 3.0.1 + '@antv/util': 3.3.11 + '@babel/runtime': 7.26.0 + tslib: 2.8.1 + '@antv/g-plugin-canvas-picker@2.1.16': dependencies: '@antv/g-lite': 2.2.14 @@ -8058,6 +8301,17 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 + '@antv/g-plugin-canvas-picker@2.1.27': + dependencies: + '@antv/g-lite': 2.3.2 + '@antv/g-math': 3.0.1 + '@antv/g-plugin-canvas-path-generator': 2.1.22 + '@antv/g-plugin-canvas-renderer': 2.3.3 + '@antv/util': 3.3.11 + '@babel/runtime': 7.26.0 + gl-matrix: 3.4.3 + tslib: 2.8.1 + '@antv/g-plugin-canvas-renderer@2.2.16': dependencies: '@antv/g-lite': 2.2.14 @@ -8069,12 +8323,29 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 + '@antv/g-plugin-canvas-renderer@2.3.3': + dependencies: + '@antv/g-lite': 2.3.2 + '@antv/g-math': 3.0.1 + '@antv/g-plugin-canvas-path-generator': 2.1.22 + '@antv/g-plugin-image-loader': 2.1.26 + '@antv/util': 3.3.11 + '@babel/runtime': 7.26.0 + gl-matrix: 3.4.3 + tslib: 2.8.1 + '@antv/g-plugin-dom-interaction@2.1.19': dependencies: '@antv/g-lite': 2.2.14 '@babel/runtime': 7.26.0 tslib: 2.8.1 + '@antv/g-plugin-dom-interaction@2.1.27': + dependencies: + '@antv/g-lite': 2.3.2 + '@babel/runtime': 7.26.0 + tslib: 2.8.1 + '@antv/g-plugin-dragndrop@2.0.30': dependencies: '@antv/g-lite': 2.2.14 @@ -8082,6 +8353,13 @@ snapshots: '@babel/runtime': 7.26.0 tslib: 2.8.1 + '@antv/g-plugin-dragndrop@2.0.38': + dependencies: + '@antv/g-lite': 2.3.2 + '@antv/util': 3.3.11 + '@babel/runtime': 7.26.0 + tslib: 2.8.1 + '@antv/g-plugin-html-renderer@2.1.19': dependencies: '@antv/g-lite': 2.2.14 @@ -8090,6 +8368,14 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 + '@antv/g-plugin-html-renderer@2.1.27': + dependencies: + '@antv/g-lite': 2.3.2 + '@antv/util': 3.3.11 + '@babel/runtime': 7.26.0 + gl-matrix: 3.4.3 + tslib: 2.8.1 + '@antv/g-plugin-image-loader@2.1.16': dependencies: '@antv/g-lite': 2.2.14 @@ -8098,6 +8384,14 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 + '@antv/g-plugin-image-loader@2.1.26': + dependencies: + '@antv/g-lite': 2.3.2 + '@antv/util': 3.3.11 + '@babel/runtime': 7.26.0 + gl-matrix: 3.4.3 + tslib: 2.8.1 + '@antv/g-svg@0.5.7': dependencies: '@antv/g-base': 0.5.16 @@ -8119,6 +8413,13 @@ snapshots: '@babel/runtime': 7.26.0 tslib: 2.8.1 + '@antv/g-web-animations-api@2.1.28': + dependencies: + '@antv/g-lite': 2.3.2 + '@antv/util': 3.3.11 + '@babel/runtime': 7.26.0 + tslib: 2.8.1 + '@antv/g-webgpu-core@0.5.6': dependencies: eventemitter3: 4.0.7 @@ -8311,6 +8612,22 @@ snapshots: dependencies: '@antv/g6-pc': 0.8.24(@antv/g6@4.8.24) + '@antv/g6@5.0.50(workerize-loader@2.0.2(webpack@4.19.1))': + dependencies: + '@antv/algorithm': 0.1.26 + '@antv/component': 2.1.11 + '@antv/event-emitter': 0.1.3 + '@antv/g': 6.1.28 + '@antv/g-canvas': 2.0.48 + '@antv/g-plugin-dragndrop': 2.0.38 + '@antv/graphlib': 2.0.4 + '@antv/hierarchy': 0.6.14 + '@antv/layout': 1.2.14-beta.9(workerize-loader@2.0.2(webpack@4.19.1)) + '@antv/util': 3.3.11 + bubblesets-js: 2.3.4 + transitivePeerDependencies: + - workerize-loader + '@antv/g@5.18.27': dependencies: '@antv/g-camera-api': 1.2.25 @@ -8326,8 +8643,28 @@ snapshots: '@antv/g-web-animations-api': 2.1.19 '@babel/runtime': 7.26.0 + '@antv/g@6.1.28': + dependencies: + '@antv/g-camera-api': 2.0.41 + '@antv/g-dom-mutation-observer-api': 2.0.38 + '@antv/g-lite': 2.3.2 + '@antv/g-web-animations-api': 2.1.28 + '@babel/runtime': 7.26.0 + + '@antv/graphin@3.0.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(workerize-loader@2.0.2(webpack@4.19.1))': + dependencies: + '@antv/g6': 5.0.50(workerize-loader@2.0.2(webpack@4.19.1)) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - workerize-loader + '@antv/graphlib@1.2.0': {} + '@antv/graphlib@2.0.4': + dependencies: + '@antv/event-emitter': 0.1.3 + '@antv/hierarchy@0.6.14': {} '@antv/l7-component@2.22.3': @@ -8494,6 +8831,23 @@ snapshots: transitivePeerDependencies: - dagre + '@antv/layout@1.2.14-beta.9(workerize-loader@2.0.2(webpack@4.19.1))': + dependencies: + '@antv/event-emitter': 0.1.3 + '@antv/graphlib': 2.0.4 + '@antv/util': 3.3.11 + '@naoak/workerize-transferable': 0.1.0(workerize-loader@2.0.2(webpack@4.19.1)) + comlink: 4.4.2 + d3-force: 3.0.0 + d3-force-3d: 3.0.6 + d3-octree: 1.1.0 + d3-quadtree: 3.0.1 + dagre: 0.8.5 + ml-matrix: 6.12.0 + tslib: 2.8.1 + transitivePeerDependencies: + - workerize-loader + '@antv/matrix-util@3.0.4': dependencies: '@antv/util': 2.0.17 @@ -8526,7 +8880,7 @@ snapshots: '@antv/scale@0.4.16': dependencies: - '@antv/util': 3.3.10 + '@antv/util': 3.3.11 color-string: 1.9.1 fecha: 4.2.3 @@ -8541,6 +8895,56 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 + '@antv/util@3.3.11': + dependencies: + fast-deep-equal: 3.1.3 + gl-matrix: 3.4.3 + tslib: 2.8.1 + + '@antv/vendor@1.0.11': + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-color': 3.1.3 + '@types/d3-dispatch': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.1 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-shape': 3.1.7 + '@types/d3-time': 3.0.4 + '@types/d3-timer': 3.0.2 + d3-array: 3.2.4 + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-force-3d: 3.0.6 + d3-format: 3.1.0 + d3-geo: 3.1.1 + d3-geo-projection: 4.0.0 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-regression: 1.3.10 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-timer: 3.0.1 + '@antv/x6-react-components@1.1.20(antd@5.13.2(moment@2.30.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: antd: 5.13.2(moment@2.30.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -10028,6 +10432,10 @@ snapshots: call-me-maybe: 1.0.2 glob-to-regexp: 0.3.0 + '@naoak/workerize-transferable@0.1.0(workerize-loader@2.0.2(webpack@4.19.1))': + dependencies: + workerize-loader: 2.0.2(webpack@4.19.1) + '@nodelib/fs.stat@1.1.3': {} '@probe.gl/env@3.6.0': @@ -10241,8 +10649,56 @@ snapshots: dependencies: '@babel/types': 7.26.3 + '@types/d3-array@3.2.2': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-dispatch@3.0.7': {} + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.15 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-shape@3.1.7': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time@3.0.4': {} + '@types/d3-timer@2.0.3': {} + '@types/d3-timer@3.0.2': {} + '@types/estree@1.0.6': {} '@types/geojson@7946.0.15': {} @@ -11143,6 +11599,8 @@ snapshots: dependencies: node-int64: 0.4.0 + bubblesets-js@2.3.4: {} + buffer-from@1.1.2: {} buffer-indexof@1.1.1: {} @@ -11439,6 +11897,8 @@ snapshots: dependencies: delayed-stream: 1.0.0 + comlink@4.4.2: {} + commander@2.13.0: {} commander@2.17.1: {} @@ -11744,6 +12204,8 @@ snapshots: dependencies: internmap: 2.0.3 + d3-binarytree@1.0.2: {} + d3-collection@1.0.7: {} d3-color@1.4.1: {} @@ -11768,6 +12230,20 @@ snapshots: d3-ease@1.0.7: {} + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force-3d@3.0.6: + dependencies: + d3-binarytree: 1.0.2 + d3-dispatch: 3.0.1 + d3-octree: 1.1.0 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + d3-force@2.1.1: dependencies: d3-dispatch: 2.0.0 @@ -11784,6 +12260,12 @@ snapshots: d3-format@3.1.0: {} + d3-geo-projection@4.0.0: + dependencies: + commander: 7.2.0 + d3-array: 3.2.4 + d3-geo: 3.1.1 + d3-geo@3.1.1: dependencies: d3-array: 3.2.4 @@ -11802,12 +12284,16 @@ snapshots: dependencies: d3-color: 3.1.0 + d3-octree@1.1.0: {} + d3-path@3.1.0: {} d3-quadtree@2.0.0: {} d3-quadtree@3.0.1: {} + d3-random@3.0.1: {} + d3-regression@1.3.10: {} d3-scale-chromatic@3.1.0: @@ -11824,6 +12310,14 @@ snapshots: d3-time: 1.1.0 d3-time-format: 2.3.0 + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 2.3.0 + d3-shape@3.2.0: dependencies: d3-path: 3.1.0 @@ -11834,6 +12328,10 @@ snapshots: d3-time@1.1.0: {} + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + d3-timer@1.0.10: {} d3-timer@2.0.0: {} @@ -14239,6 +14737,12 @@ snapshots: emojis-list: 3.0.0 json5: 1.0.2 + loader-utils@2.0.4: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + locate-path@2.0.0: dependencies: p-locate: 2.0.0 @@ -17884,6 +18388,11 @@ snapshots: dependencies: errno: 0.1.8 + workerize-loader@2.0.2(webpack@4.19.1): + dependencies: + loader-utils: 2.0.4 + webpack: 4.19.1 + wrap-ansi@2.1.0: dependencies: string-width: 1.0.2 diff --git a/frontend/src/Layout.tsx b/frontend/src/Layout.tsx index e2948eb..cd140ff 100644 --- a/frontend/src/Layout.tsx +++ b/frontend/src/Layout.tsx @@ -34,6 +34,7 @@ import { ConfigProvider, MenuProps } from 'antd' import { Layout, Menu } from 'antd' import QueryEditorPage from './pages/QueryEditor/QueryEditorPage' import AIToolsPage from './pages/AITools/AIToolsPage' +import Topology from './pages/Topology/Topology' const { Header, Content, Footer, Sider } = Layout @@ -42,6 +43,7 @@ type MenuItem = Required['items'][number] const items: MenuItem[] = [ { key: '', icon: , label: 'Overview' }, { key: 'clusters', label: 'Clusters', icon: }, + { key: 'topology', label: 'Cluster Topology', icon: }, { key: 'backup', label: 'Backup', @@ -54,7 +56,7 @@ const items: MenuItem[] = [ { key: 'query_performance', label: 'Query performance', icon: }, { key: 'running_queries', label: 'Running queries', icon: }, { key: 'schema', label: 'Schema stats', icon: }, - { key: 'disk_usage', label: 'Disk usage', icon: }, + { key: 'disk_usage', label: 'Disk usage', icon: }, { key: 'logs', label: 'Logs', icon: }, { key: 'errors', label: 'Errors', icon: }, { key: 'query_editor', label: 'Query editor', icon: }, @@ -114,6 +116,7 @@ export default function AppLayout(): JSX.Element { + diff --git a/frontend/src/pages/Topology/Topology.tsx b/frontend/src/pages/Topology/Topology.tsx new file mode 100644 index 0000000..3dc4c4e --- /dev/null +++ b/frontend/src/pages/Topology/Topology.tsx @@ -0,0 +1,569 @@ +import React, { useState, useEffect, useMemo } from 'react' +import useSWR from 'swr' +import { notification, Card, Spin, Tabs, Descriptions, Tag, Drawer, Select, Space } from 'antd' +import { Graphin, GraphinData, IUserNode, IUserEdge } from '@antv/graphin' +import { DatabaseOutlined, CloudServerOutlined, TableOutlined, PartitionOutlined } from '@ant-design/icons' +import '@antv/graphin/dist/index.css' + +const { TabPane } = Tabs + +interface ClusterNode { + cluster: string + shard_num: number + replica_num: number + host_name: string + host_address: string + port: number + is_local: number + errors_count: number + slowdowns_count: number +} + +interface TableInfo { + database: string + table: string + engine: string + total_rows: number + total_bytes: number + total_bytes_readable: string +} + +interface ReplicationStatus { + database: string + table: string + replica_name: string + total_replicas: number + active_replicas: number + is_leader: number + is_readonly: number + queue_size: number +} + +interface TopologyData { + cluster_nodes: ClusterNode[] + tables: TableInfo[] + replication_status: ReplicationStatus[] + dependencies: any[] + parts_distribution: any[] +} + +interface NodeDetail { + id: string + type: string + data: any +} + +export default function Topology() { + const [selectedNode, setSelectedNode] = useState(null) + const [drawerVisible, setDrawerVisible] = useState(false) + const [selectedCluster, setSelectedCluster] = useState(null) + const [viewMode, setViewMode] = useState<'cluster' | 'tables' | 'combined'>('cluster') + + const loadData = async (url: string) => { + try { + const res = await fetch(url) + const resJson = await res.json() + return resJson + } catch (err) { + notification.error({ message: 'Failed to load topology data' }) + } + } + + const { data, error, isLoading } = useSWR('/api/clusters/topology', loadData) + + // Get unique clusters + const clusters = useMemo(() => { + if (!data?.cluster_nodes) return [] + const uniqueClusters = [...new Set(data.cluster_nodes.map((n) => n.cluster))] + return uniqueClusters + }, [data]) + + // Set default cluster + useEffect(() => { + if (clusters.length > 0 && !selectedCluster) { + setSelectedCluster(clusters[0]) + } + }, [clusters, selectedCluster]) + + // Transform data to graph format + const graphData: GraphinData = useMemo(() => { + if (!data || !selectedCluster) return { nodes: [], edges: [] } + + const nodes: IUserNode[] = [] + const edges: IUserEdge[] = [] + + if (viewMode === 'cluster' || viewMode === 'combined') { + // Filter nodes for selected cluster + const clusterNodes = data.cluster_nodes.filter((n) => n.cluster === selectedCluster) + + // Group by shards + const shardGroups: { [key: number]: ClusterNode[] } = {} + clusterNodes.forEach((node) => { + if (!shardGroups[node.shard_num]) { + shardGroups[node.shard_num] = [] + } + shardGroups[node.shard_num].push(node) + }) + + // Create cluster root node + nodes.push({ + id: `cluster-${selectedCluster}`, + label: `Cluster: ${selectedCluster}`, + type: 'graphin-circle', + style: { + keyshape: { + size: 60, + fill: '#5B8FF9', + stroke: '#3057A0', + lineWidth: 2, + }, + label: { + value: `Cluster\n${selectedCluster}`, + fill: '#000', + fontSize: 14, + fontWeight: 'bold', + }, + icon: { + type: 'text', + value: '🖥', + size: 30, + fill: '#fff', + }, + }, + data: { + type: 'cluster', + cluster: selectedCluster, + shardCount: Object.keys(shardGroups).length, + }, + }) + + // Create shard nodes and replica nodes + Object.entries(shardGroups).forEach(([shardNum, replicas]) => { + const shardId = `shard-${selectedCluster}-${shardNum}` + + // Create shard node + nodes.push({ + id: shardId, + label: `Shard ${shardNum}`, + type: 'graphin-circle', + style: { + keyshape: { + size: 50, + fill: '#5AD8A6', + stroke: '#2E8B57', + lineWidth: 2, + }, + label: { + value: `Shard ${shardNum}`, + fill: '#000', + fontSize: 12, + }, + icon: { + type: 'text', + value: '📊', + size: 24, + fill: '#fff', + }, + }, + data: { + type: 'shard', + shard_num: shardNum, + replica_count: replicas.length, + }, + }) + + // Edge from cluster to shard + edges.push({ + source: `cluster-${selectedCluster}`, + target: shardId, + style: { + keyshape: { + stroke: '#5B8FF9', + lineWidth: 2, + }, + }, + }) + + // Create replica nodes + replicas.forEach((replica) => { + const replicaId = `replica-${selectedCluster}-${shardNum}-${replica.replica_num}` + const hasErrors = replica.errors_count > 0 + const hasSlow = replica.slowdowns_count > 0 + + nodes.push({ + id: replicaId, + label: replica.host_name, + type: 'graphin-circle', + style: { + keyshape: { + size: 40, + fill: hasErrors ? '#F5222D' : hasSlow ? '#FAAD14' : '#73D13D', + stroke: hasErrors ? '#A8071A' : hasSlow ? '#D46B08' : '#389E0D', + lineWidth: 2, + }, + label: { + value: `${replica.host_name}\n${replica.host_address}:${replica.port}`, + fill: '#000', + fontSize: 10, + }, + icon: { + type: 'text', + value: '🖥', + size: 20, + fill: '#fff', + }, + }, + data: { + type: 'replica', + ...replica, + }, + }) + + // Edge from shard to replica + edges.push({ + source: shardId, + target: replicaId, + style: { + keyshape: { + stroke: '#5AD8A6', + lineWidth: 1.5, + }, + }, + }) + }) + }) + } + + if (viewMode === 'tables' || viewMode === 'combined') { + // Group tables by database + const databases = [...new Set(data.tables.map((t) => t.database))] + + databases.forEach((dbName, dbIndex) => { + const dbNodeId = `database-${dbName}` + const tablesInDb = data.tables.filter((t) => t.database === dbName) + + // Create database node + nodes.push({ + id: dbNodeId, + label: dbName, + type: 'graphin-circle', + style: { + keyshape: { + size: 50, + fill: '#9254DE', + stroke: '#531DAB', + lineWidth: 2, + }, + label: { + value: `DB: ${dbName}`, + fill: '#000', + fontSize: 12, + }, + icon: { + type: 'text', + value: '💾', + size: 24, + fill: '#fff', + }, + }, + data: { + type: 'database', + database: dbName, + table_count: tablesInDb.length, + }, + }) + + // If in combined mode, connect database to cluster + if (viewMode === 'combined') { + edges.push({ + source: `cluster-${selectedCluster}`, + target: dbNodeId, + style: { + keyshape: { + stroke: '#9254DE', + lineWidth: 1, + lineDash: [5, 5], + }, + }, + }) + } + + // Create table nodes (limit to prevent overcrowding) + tablesInDb.slice(0, 10).forEach((table, tableIndex) => { + const tableNodeId = `table-${table.database}-${table.table}` + const isReplicated = data.replication_status.some( + (r) => r.database === table.database && r.table === table.table + ) + + nodes.push({ + id: tableNodeId, + label: table.table, + type: 'graphin-circle', + style: { + keyshape: { + size: 30, + fill: isReplicated ? '#FF7A45' : '#40A9FF', + stroke: isReplicated ? '#D4380D' : '#096DD9', + lineWidth: 1.5, + }, + label: { + value: `${table.table}\n${table.engine}`, + fill: '#000', + fontSize: 9, + }, + icon: { + type: 'text', + value: '📋', + size: 16, + fill: '#fff', + }, + }, + data: { + type: 'table', + ...table, + isReplicated, + }, + }) + + edges.push({ + source: dbNodeId, + target: tableNodeId, + style: { + keyshape: { + stroke: '#9254DE', + lineWidth: 1, + }, + }, + }) + }) + }) + } + + return { nodes, edges } + }, [data, selectedCluster, viewMode]) + + const handleNodeClick = (node: any) => { + const model = node.get('model') + setSelectedNode({ + id: model.id, + type: model.data?.type || 'unknown', + data: model.data, + }) + setDrawerVisible(true) + } + + const renderNodeDetails = () => { + if (!selectedNode) return null + + switch (selectedNode.type) { + case 'cluster': + return ( + + {selectedNode.data.cluster} + {selectedNode.data.shardCount} + + ) + case 'shard': + return ( + + {selectedNode.data.shard_num} + {selectedNode.data.replica_count} + + ) + case 'replica': + return ( + + {selectedNode.data.host_name} + {selectedNode.data.host_address} + {selectedNode.data.port} + {selectedNode.data.shard_num} + {selectedNode.data.replica_num} + + {selectedNode.data.is_local ? Yes : No} + + + {selectedNode.data.errors_count > 0 ? ( + {selectedNode.data.errors_count} + ) : ( + 0 + )} + + + {selectedNode.data.slowdowns_count > 0 ? ( + {selectedNode.data.slowdowns_count} + ) : ( + 0 + )} + + + ) + case 'database': + return ( + + {selectedNode.data.database} + {selectedNode.data.table_count} + + ) + case 'table': + return ( + + {selectedNode.data.database} + {selectedNode.data.table} + {selectedNode.data.engine} + + {selectedNode.data.total_rows.toLocaleString()} + + {selectedNode.data.total_bytes_readable} + + {selectedNode.data.isReplicated ? Yes : No} + + + ) + default: + return

Select a node to view details

+ } + } + + if (isLoading) { + return ( +
+ +
+ ) + } + + if (error || !data) { + return ( +
+

Cluster Topology

+ +

Failed to load topology data. Please check your ClickHouse connection.

+
+
+ ) + } + + return ( +
+

Cluster Topology

+ + + + Cluster: + + + +
+ {graphData.nodes.length > 0 ? ( + handleNodeClick(item)} + /> + ) : ( +
+

No cluster topology data available

+
+ )} +
+ +
+

Legend:

+ +
+ + Healthy Replica +
+
+ + Slowdowns +
+
+ + Errors +
+
+ + Replicated Table +
+
+
+
+ + setDrawerVisible(false)} + open={drawerVisible} + width={450} + > + {renderNodeDetails()} + +
+ ) +} diff --git a/housewatch/api/cluster.py b/housewatch/api/cluster.py index e243515..028c269 100644 --- a/housewatch/api/cluster.py +++ b/housewatch/api/cluster.py @@ -4,6 +4,14 @@ from rest_framework.response import Response from rest_framework.viewsets import GenericViewSet from housewatch.clickhouse import clusters +from housewatch.clickhouse.client import run_query +from housewatch.clickhouse.queries.sql import ( + CLUSTER_TOPOLOGY_SQL, + REPLICATION_STATUS_SQL, + TABLES_WITH_ENGINE_SQL, + TABLE_DEPENDENCIES_SQL, + PARTS_DISTRIBUTION_SQL, +) logger = structlog.get_logger(__name__) @@ -15,3 +23,41 @@ def list(self, request: Request) -> Response: def retrieve(self, request: Request, pk: str) -> Response: return Response(clusters.get_cluster(pk)) + + @action(detail=False, methods=["GET"]) + def topology(self, request: Request) -> Response: + """ + Get comprehensive cluster topology data including: + - Cluster nodes (shards and replicas) + - Tables with replication status + - Table dependencies + - Data distribution across nodes + """ + try: + # Get cluster structure + cluster_nodes = run_query(CLUSTER_TOPOLOGY_SQL) + + # Get replication status for replicated tables + replication_status = run_query(REPLICATION_STATUS_SQL) + + # Get all tables with their engines + tables = run_query(TABLES_WITH_ENGINE_SQL) + + # Get table dependencies (for materialized views, etc.) + dependencies = run_query(TABLE_DEPENDENCIES_SQL) + + # Get parts distribution across nodes + parts_distribution = run_query(PARTS_DISTRIBUTION_SQL) + + return Response( + { + "cluster_nodes": cluster_nodes, + "replication_status": replication_status, + "tables": tables, + "dependencies": dependencies, + "parts_distribution": parts_distribution, + } + ) + except Exception as e: + logger.error("topology_error", error=str(e)) + return Response({"error": str(e)}, status=500) diff --git a/housewatch/clickhouse/queries/sql.py b/housewatch/clickhouse/queries/sql.py index 4e1f251..35ac6c7 100644 --- a/housewatch/clickhouse/queries/sql.py +++ b/housewatch/clickhouse/queries/sql.py @@ -279,3 +279,102 @@ FROM system.tables WHERE %(conditions)s """ + +# Topology visualization queries +CLUSTER_TOPOLOGY_SQL = """ +SELECT + cluster, + shard_num, + shard_weight, + replica_num, + host_name, + host_address, + port, + is_local, + errors_count, + slowdowns_count, + estimated_recovery_time +FROM system.clusters +ORDER BY cluster, shard_num, replica_num +""" + +REPLICATION_STATUS_SQL = """ +SELECT + database, + table, + engine, + replica_name, + replica_path, + total_replicas, + active_replicas, + is_leader, + is_readonly, + is_session_expired, + future_parts, + parts_to_check, + queue_size, + inserts_in_queue, + merges_in_queue, + log_max_index, + log_pointer, + last_queue_update, + absolute_delay, + total_replicas, + active_replicas +FROM system.replicas +WHERE database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA') +ORDER BY database, table, replica_name +""" + +TABLES_WITH_ENGINE_SQL = """ +SELECT + database, + name as table, + engine, + engine_full, + total_rows, + total_bytes, + formatReadableSize(total_bytes) as total_bytes_readable, + partition_key, + sorting_key, + primary_key, + sampling_key, + storage_policy, + dependencies_database, + dependencies_table +FROM system.tables +WHERE database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA') +ORDER BY database, table +""" + +TABLE_DEPENDENCIES_SQL = """ +SELECT + database, + table, + dependencies_database, + dependencies_table +FROM system.tables +WHERE + database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA') + AND (dependencies_database != '' OR dependencies_table != '') +ORDER BY database, table +""" + +PARTS_DISTRIBUTION_SQL = """ +SELECT + database, + table, + partition, + name as part_name, + hostName() as host, + rows, + bytes_on_disk, + formatReadableSize(bytes_on_disk) as bytes_on_disk_readable, + active, + replica_name +FROM system.parts +WHERE + active = 1 + AND database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA') +ORDER BY database, table, partition +"""