CN-1087 feat: 关系图部分实现

This commit is contained in:
chenjinsong
2023-07-02 22:38:59 +08:00
parent 24864ca1be
commit f724477934
17 changed files with 3280 additions and 403 deletions

View File

@@ -12,6 +12,7 @@
"dependencies": {
"@amcharts/amcharts4": "^4.10.24",
"@amcharts/amcharts4-geodata": "^4.1.20",
"@antv/g6": "^4.8.17",
"axios": "^0.21.1",
"babel-plugin-lodash": "^3.3.4",
"codemirror": "^5.65.1",
@@ -27,7 +28,6 @@
"node-sass": "^4.14.1",
"postcss-plugin-px2rem": "^0.8.1",
"postcss-px2rem-exclude": "0.0.6",
"relation-graph": "^2.0.26",
"sass-loader": "^8.0.2",
"sass-resources-loader": "^2.2.1",
"tiny-emitter": "^2.1.0",

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1687771200531" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7765" width="36" height="36" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M723.84487531 71.54166698c60.46291698 0 110.11458302 49.45145802 110.11458302 110.11458302v12.21270802h10.05045802c27.58870802 0 49.77179198 22.30320802 49.77179198 49.73175v256.78720896c0 27.42854198-22.34325 49.73175-49.77179198 49.73175h-10.05045802v292.22408302c0 60.50295802-49.4915 110.11458302-110.11458302 110.11458302H310.89516635a110.394875 110.394875 0 0 1-110.11458302-110.11458302v-292.22408302h-10.0905A49.81183302 49.81183302 0 0 1 140.95833333 500.38791698V243.60070802c0-27.42854198 22.30320802-49.73175 49.73175-49.73175h10.0905V181.65625C200.78058333 121.15329198 250.23204135 71.54166698 310.89516635 71.54166698z m54.97720802 688.31625H255.75779135v82.48583302a55.2575 55.2575 0 0 0 55.137375 55.137375h412.94970896a55.2575 55.2575 0 0 0 55.09733302-55.137375l-0.120125-82.48583302z m-261.47208302 27.508625c22.02291698 0 41.24291698 19.22 41.24291604 41.28295802 0 22.02291698-19.22 41.24291698-41.24291604 41.24291698-21.90279198 0-41.24291698-19.22-41.24291698-41.24291698s19.22-41.24291698 41.24291698-41.24291698z m261.59220802-237.246875H255.87791635v154.56083302h523.06429198v-154.56083302z m61.06354198-302.47475H194.73429135v248.65875h645.27145896v-248.65875z m-518.53958396 23.78475c12.41291698 0 23.5445 7.52783302 28.10925 18.97975l60.903375 150.55666604a24.865875 24.865875 0 0 1-23.10404104 34.27566698 25.106125 25.106125 0 0 1-23.26420896-15.8565l-6.56683302-16.697375H284.78800031l-6.32658396 16.53720802a25.14616698 25.14616698 0 1 1-46.76866604-18.41916604l61.70420802-150.55666698a30.43166698 30.43166698 0 0 1 28.10925-18.81958302z m217.82666698 0c40.722375 0 71.63454198 31.47275 71.63454198 69.6725 0 38.15970802-31.19245802 69.071875-74.4775 69.071875h-20.70154198v40.32195802a24.66566698 24.66566698 0 0 1-24.74575 24.74575 24.82583302 24.82583302 0 0 1-24.74575-24.74575V296.17541698a24.66566698 24.66566698 0 0 1 24.74575-24.74575z m190.878625 0c40.722375 0 71.67458302 31.47275 71.67458302 69.6725 0 38.15970802-31.2325 69.071875-74.4775 69.071875h-20.74158302v40.32195802a24.66566698 24.66566698 0 0 1-24.74575 24.74575 24.66566698 24.66566698 0 0 1-24.70570802-24.74575V296.17541698a24.66566698 24.66566698 0 0 1 24.70570802-24.74575zM321.10579135 348.30966698l-20.181 52.05416604H341.16666635l-20.02083302-52.05416604z m215.46420896-27.3885h-20.70154198v47.16908302h18.17891698c18.65941698 0 27.3885-11.57204198 27.3885-25.14616698 0-11.01145802-6.68695802-22.02291698-24.82583396-22.02291604z m190.7585 0h-20.70154198v47.16908302h18.138875c18.69945802 0 27.42854198-11.57204198 27.42854198-25.14616698 0-11.01145802-6.727-22.02291698-24.82583396-22.02291604z m-3.3635-194.40229198H311.01529135A55.2575 55.2575 0 0 0 255.87791635 181.65625v12.21270802h523.22445896V181.65625a55.2575 55.2575 0 0 0-55.137375-55.137375z" p-id="7766" fill="#E5A219"></path></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1688290120782" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7911" xmlns:xlink="http://www.w3.org/1999/xlink" width="36" height="36"><path d="M723.84487531 71.54166698c60.46291698 0 110.11458302 49.45145802 110.11458302 110.11458302v12.21270802h10.05045802c27.58870802 0 49.77179198 22.30320802 49.77179198 49.73175v256.78720896c0 27.42854198-22.34325 49.73175-49.77179198 49.73175h-10.05045802v292.22408302c0 60.50295802-49.4915 110.11458302-110.11458302 110.11458302H310.89516635a110.394875 110.394875 0 0 1-110.11458302-110.11458302v-292.22408302h-10.0905A49.81183302 49.81183302 0 0 1 140.95833333 500.38791698V243.60070802c0-27.42854198 22.30320802-49.73175 49.73175-49.73175h10.0905V181.65625C200.78058333 121.15329198 250.23204135 71.54166698 310.89516635 71.54166698z m54.97720802 688.31625H255.75779135v82.48583302a55.2575 55.2575 0 0 0 55.137375 55.137375h412.94970896a55.2575 55.2575 0 0 0 55.09733302-55.137375l-0.120125-82.48583302z m-261.47208302 27.508625c22.02291698 0 41.24291698 19.22 41.24291604 41.28295802 0 22.02291698-19.22 41.24291698-41.24291604 41.24291698-21.90279198 0-41.24291698-19.22-41.24291698-41.24291698s19.22-41.24291698 41.24291698-41.24291698z m261.59220802-237.246875H255.87791635v154.56083302h523.06429198v-154.56083302z m61.06354198-302.47475H194.73429135v248.65875h645.27145896v-248.65875z m-518.53958396 23.78475c12.41291698 0 23.5445 7.52783302 28.10925 18.97975l60.903375 150.55666604a24.865875 24.865875 0 0 1-23.10404104 34.27566698 25.106125 25.106125 0 0 1-23.26420896-15.8565l-6.56683302-16.697375H284.78800031l-6.32658396 16.53720802a25.14616698 25.14616698 0 1 1-46.76866604-18.41916604l61.70420802-150.55666698a30.43166698 30.43166698 0 0 1 28.10925-18.81958302z m217.82666698 0c40.722375 0 71.63454198 31.47275 71.63454198 69.6725 0 38.15970802-31.19245802 69.071875-74.4775 69.071875h-20.70154198v40.32195802a24.66566698 24.66566698 0 0 1-24.74575 24.74575 24.82583302 24.82583302 0 0 1-24.74575-24.74575V296.17541698a24.66566698 24.66566698 0 0 1 24.74575-24.74575z m190.878625 0c40.722375 0 71.67458302 31.47275 71.67458302 69.6725 0 38.15970802-31.2325 69.071875-74.4775 69.071875h-20.74158302v40.32195802a24.66566698 24.66566698 0 0 1-24.74575 24.74575 24.66566698 24.66566698 0 0 1-24.70570802-24.74575V296.17541698a24.66566698 24.66566698 0 0 1 24.70570802-24.74575zM321.10579135 348.30966698l-20.181 52.05416604H341.16666635l-20.02083302-52.05416604z m215.46420896-27.3885h-20.70154198v47.16908302h18.17891698c18.65941698 0 27.3885-11.57204198 27.3885-25.14616698 0-11.01145802-6.68695802-22.02291698-24.82583396-22.02291604z m190.7585 0h-20.70154198v47.16908302h18.138875c18.69945802 0 27.42854198-11.57204198 27.42854198-25.14616698 0-11.01145802-6.727-22.02291698-24.82583396-22.02291604z m-3.3635-194.40229198H311.01529135A55.2575 55.2575 0 0 0 255.87791635 181.65625v12.21270802h523.22445896V181.65625a55.2575 55.2575 0 0 0-55.137375-55.137375z" p-id="7912" fill="#778391"></path></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1688298522321" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7364" xmlns:xlink="http://www.w3.org/1999/xlink" width="36" height="36"><path d="M512 61.06201172a450.93798828 450.93798828 0 1 1 0 901.87597656 450.93798828 450.93798828 0 0 1 0-901.87597656z m0 45.09379883a405.84418945 405.84418945 0 1 0 0 811.6883789 405.84418945 405.84418945 0 0 0 0-811.6883789z" p-id="7365" fill="#38ACD2"></path><path d="M229.64344446 586.23133044l15.95626722-52.586307c4.64812962-15.19314186 8.18625866-30.6637832 10.54501134-46.41192491h0.69375048c3.1912538 18.3150199 6.17438209 31.77378466 10.12876124 46.48129978l15.05439124 52.51693213h46.82817591l49.11755284-149.36453686h-48.77067761l-13.73626514 59.24631408c-3.60750391 17.06626868-6.93750745 33.855037-9.22688438 50.99068056h-0.69375136a864.41343565 864.41343565 0 0 0-11.79376257-50.64380531l-15.95626721-59.59318933h-39.33566772l-17.06626869 61.39694129c-3.88500427 14.63814112-8.46375903 31.70440892-11.79376256 48.84005335h-0.69375049A890.56783897 890.56783897 0 0 0 199.81216237 497.84748474l-12.7650143-61.05006603h-50.78255506l46.55067554 149.36453685h46.82817591zM570.27506324 496.04373279c-3.53812904 17.20501843-6.86813258 33.99378674-9.1575104 51.06005543h-0.69375047c-3.1912538-17.13564355-7.49250818-33.855037-11.79376257-50.64380531l-15.95626721-59.59318933H493.26872999l-17.06626869 61.39694129c-3.88500427 14.63814112-8.46375903 31.77378466-11.79376256 48.84005335h-0.69375137a904.30410413 904.30410413 0 0 0-9.08813463-49.18692861l-12.83438917-61.05006603h-50.78255417l46.48129978 149.29516199h46.89755078l16.09501783-52.51693213c4.57875475-15.26251673 8.11688379-30.73315807 10.40626074-46.48130068h0.69375136c3.33000354 18.38439477 6.24375697 31.84315955 10.19813611 46.48130068l15.05439124 52.51693212h46.82817502l49.11755373-149.29516198H584.15007813l-13.73626514 59.24631408zM825.22846423 496.04373279c-3.60750391 17.20501843-6.93750745 33.99378674-9.15751039 51.06005543h-0.69375048c-3.26062867-17.13564355-7.56188305-33.855037-11.79376256-50.64380531l-16.02564208-59.59318933h-39.33566773l-16.99689381 61.39694129a710.40076917 710.40076917 0 0 0-11.79376257 48.84005335h-0.69375049a893.96721827 893.96721827 0 0 0-9.15751038-49.18692861l-12.76501342-61.05006603H645.89389464l46.55067554 149.29516199h46.82817591l16.09501784-52.51693213a328.14410573 328.14410573 0 0 0 10.47563559-46.48130068h0.69375136c3.26062867 18.38439477 6.24375697 31.84315955 10.12876036 46.48130068l15.05439124 52.51693212h46.82817591l49.1869286-149.29516198h-48.84005337l-13.73626426 59.24631408z" p-id="7366" fill="#38ACD2"></path><path d="M320.17791736 643.11889184c28.65190576 164.34955323 107.87824195 274.72529762 191.82208264 274.72529761 81.30758763 0 158.24454601-103.7157373 189.04707984-259.80965612l2.42812756-12.83438916 44.40004835 7.90875828C715.4077206 835.28784972 623.34699522 962.93798828 512 962.93798828c-109.26574291 0-200.07771705-123.00200805-233.93275317-299.56157396l-2.28937782-12.48751393 44.40004835-7.70063368zM512 61.06201172c109.40449353 0 200.14709193 123.14075868 234.00212804 299.83907432l2.28937782 12.48751393-44.40004834 7.70063369C675.10080202 216.67030556 595.94384069 106.15581055 512 106.15581055c-82.07071387 0-159.56267298 105.58886413-189.81020519 263.62528552l-2.28937782 12.69563854-44.40004834-7.63125792C307.06602784 190.65465198 399.7511288 61.06201172 512 61.06201172z" p-id="7367" fill="#38ACD2"></path><path d="M549.60129065 647.28139648V962.93798828h-60.14819006V647.28139648h60.14819006z m0-586.21938476v315.6565918h-60.14819006V61.06201172h60.14819006z" p-id="7368" fill="#38ACD2"></path><path d="M151.24960938 241.43720703h721.50078124v45.09379883H151.24960938V241.43720703z m0 496.03178711h721.50078124v45.09379883H151.24960938v-45.09379883z" p-id="7369" fill="#38ACD2"></path></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1687771150463" class="icon" viewBox="0 0 1228 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7479" width="35.9765625" height="30" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M1099.86729167 250.4559668V115.17457031H125.84123698v135.28139649h974.02605469z m0 54.11255859H125.84123698v595.23814453h974.02605469V304.56852539zM71.72867839 61.06201172h1082.25117187v892.8572168H71.72867839V61.06201172z m324.31460117 504.74992185v44.34223492c0.1803752 10.31144837 2.1344401 18.12770712 5.89225608 23.50890074 3.72775374 5.38119362 11.15319987 8.05675843 22.27633663 8.05675844h99.65729541v44.34223581h-119.73906657c-20.14189651 0-34.15103728-4.65969284-41.99735827-13.9490154-7.81625876-9.28932256-11.7243877-23.32852556-11.72438769-42.14767035v-82.61183945c0-18.81914567 3.90812893-32.85834779 11.72438769-42.14767034 7.81625876-9.31938479 21.82539863-13.9490154 41.99735827-13.9490154h119.73906657v44.34223581h-99.65729541c-11.12313675 0-18.54858288 2.70562793-22.27633663 8.05675842-3.75781686 5.38119362-5.71188089 12.7465135-5.89225608 22.1560868z m327.98223044 64.15344416c0 18.12770712-3.72775374 32.01659717-11.21332523 41.66667012-7.4855706 9.62001071-21.40452288 14.43001562-41.7267946 14.43001563h-66.76888539c-20.17195963 0-34.18109951-4.65969284-41.99735738-13.9490154-7.81625876-9.28932256-11.7243877-23.32852556-11.7243877-42.14767035v-82.61183945c0-18.81914567 3.90812893-32.85834779 11.7243877-42.14767034 7.81625876-9.31938479 21.82539863-13.9490154 41.99735738-13.9490154h66.73882227c20.35233483 0 34.27128711 4.81000491 41.75685772 14.43001562 7.4855706 9.62001071 11.21332435 23.53896299 11.21332523 41.66667012v82.61183945zM678.39058559 611.20635742v-44.67292307c0-10.76238636-1.74362659-18.60870736-5.23088067-23.50890076-3.48725407-4.93025564-11.21332435-7.39538301-23.20827572-7.395383h-25.55315237c-11.12313675 0-18.57864512 2.70562793-22.30639886 8.05675842-3.72775374 5.38119362-5.6216933 12.98701406-5.62169418 22.84752534v44.31217268c0 9.86051038 1.89393956 17.4663317 5.62169418 22.84752444 3.72775374 5.38119362 11.18326211 8.05675843 22.30639886 8.05675932h25.55315237c11.99495049 0 19.63083405-2.46512737 22.93771293-7.39538301 3.30687888-4.90019251 5.14069306-12.62626367 5.50144346-23.14815036z m241.37207356-119.91944264c20.32227171 0 34.27128711 4.81000491 41.72679548 14.43001562 7.4855706 9.62001071 11.21332435 23.53896299 11.21332434 41.66667012v138.7085252h-45.63492441v-119.55869137c0-10.76238636-1.74362659-18.60870736-5.23088066-23.50890076-3.48725407-4.93025564-11.21332435-7.39538301-23.20827484-7.395383h-14.61039082v150.46297513h-46.17605l-0.24050055-150.46297513h-13.04713943c-11.12313675 0-18.54858288 2.70562793-22.30639886 8.05675842-3.72775374 5.38119362-5.59163105 12.98701406-5.59163105 22.84752534v119.55869137h-45.90548721v-138.7085252c0-18.81914567 3.90812893-32.85834779 11.72438769-42.14767035 7.81625876-9.31938479 21.82539863-13.9490154 41.99735828-13.94901539h115.28981204zM244.88886589 637.36076074h48.70130273v48.70130274H244.88886589v-48.70130274z" p-id="7480" fill="#38ACD2"></path></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1688290376101" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8107" xmlns:xlink="http://www.w3.org/1999/xlink" width="36" height="36"><path d="M512 61.06201172a450.93798828 450.93798828 0 1 1 0 901.87597656 450.93798828 450.93798828 0 0 1 0-901.87597656z m0 45.09379883a405.84418945 405.84418945 0 1 0 0 811.6883789 405.84418945 405.84418945 0 0 0 0-811.6883789z" p-id="8108" fill="#778391"></path><path d="M229.64344446 586.23133044l15.95626722-52.586307c4.64812962-15.19314186 8.18625866-30.6637832 10.54501134-46.41192491h0.69375048c3.1912538 18.3150199 6.17438209 31.77378466 10.12876124 46.48129978l15.05439124 52.51693213h46.82817591l49.11755284-149.36453686h-48.77067761l-13.73626514 59.24631408c-3.60750391 17.06626868-6.93750745 33.855037-9.22688438 50.99068056h-0.69375136a864.41343565 864.41343565 0 0 0-11.79376257-50.64380531l-15.95626721-59.59318933h-39.33566772l-17.06626869 61.39694129c-3.88500427 14.63814112-8.46375903 31.70440892-11.79376256 48.84005335h-0.69375049A890.56783897 890.56783897 0 0 0 199.81216237 497.84748474l-12.7650143-61.05006603h-50.78255506l46.55067554 149.36453685h46.82817591zM570.27506324 496.04373279c-3.53812904 17.20501843-6.86813258 33.99378674-9.1575104 51.06005543h-0.69375047c-3.1912538-17.13564355-7.49250818-33.855037-11.79376257-50.64380531l-15.95626721-59.59318933H493.26872999l-17.06626869 61.39694129c-3.88500427 14.63814112-8.46375903 31.77378466-11.79376256 48.84005335h-0.69375137a904.30410413 904.30410413 0 0 0-9.08813463-49.18692861l-12.83438917-61.05006603h-50.78255417l46.48129978 149.29516199h46.89755078l16.09501783-52.51693213c4.57875475-15.26251673 8.11688379-30.73315807 10.40626074-46.48130068h0.69375136c3.33000354 18.38439477 6.24375697 31.84315955 10.19813611 46.48130068l15.05439124 52.51693212h46.82817502l49.11755373-149.29516198H584.15007813l-13.73626514 59.24631408zM825.22846423 496.04373279c-3.60750391 17.20501843-6.93750745 33.99378674-9.15751039 51.06005543h-0.69375048c-3.26062867-17.13564355-7.56188305-33.855037-11.79376256-50.64380531l-16.02564208-59.59318933h-39.33566773l-16.99689381 61.39694129a710.40076917 710.40076917 0 0 0-11.79376257 48.84005335h-0.69375049a893.96721827 893.96721827 0 0 0-9.15751038-49.18692861l-12.76501342-61.05006603H645.89389464l46.55067554 149.29516199h46.82817591l16.09501784-52.51693213a328.14410573 328.14410573 0 0 0 10.47563559-46.48130068h0.69375136c3.26062867 18.38439477 6.24375697 31.84315955 10.12876036 46.48130068l15.05439124 52.51693212h46.82817591l49.1869286-149.29516198h-48.84005337l-13.73626426 59.24631408z" p-id="8109" fill="#778391"></path><path d="M320.17791736 643.11889184c28.65190576 164.34955323 107.87824195 274.72529762 191.82208264 274.72529761 81.30758763 0 158.24454601-103.7157373 189.04707984-259.80965612l2.42812756-12.83438916 44.40004835 7.90875828C715.4077206 835.28784972 623.34699522 962.93798828 512 962.93798828c-109.26574291 0-200.07771705-123.00200805-233.93275317-299.56157396l-2.28937782-12.48751393 44.40004835-7.70063368zM512 61.06201172c109.40449353 0 200.14709193 123.14075868 234.00212804 299.83907432l2.28937782 12.48751393-44.40004834 7.70063369C675.10080202 216.67030556 595.94384069 106.15581055 512 106.15581055c-82.07071387 0-159.56267298 105.58886413-189.81020519 263.62528552l-2.28937782 12.69563854-44.40004834-7.63125792C307.06602784 190.65465198 399.7511288 61.06201172 512 61.06201172z" p-id="8110" fill="#778391"></path><path d="M549.60129065 647.28139648V962.93798828h-60.14819006V647.28139648h60.14819006z m0-586.21938476v315.6565918h-60.14819006V61.06201172h60.14819006z" p-id="8111" fill="#778391"></path><path d="M151.24960938 241.43720703h721.50078124v45.09379883H151.24960938V241.43720703z m0 496.03178711h721.50078124v45.09379883H151.24960938v-45.09379883z" p-id="8112" fill="#778391"></path></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1687770782238" class="icon" viewBox="0 0 1109 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7446" width="35.7392578125" height="33" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M306.07165232 286.53100586h88.45900173v402.31184159H306.07165232V286.53100586z m254.70480646 258.08684225h92.9683825c25.1773713 0 46.59692575-3.68265995 64.25866333-10.97282467 17.66173758-7.36532077 32.01659717-16.9853306 43.06457788-29.01034421 11.12313675-12.02501272 19.1648645-25.85377829 24.27549445-41.48629492a152.94313406 152.94313406 0 0 0 0-95.44854056 111.6071521 111.6071521 0 0 0-24.27549445-41.18566989 120.25012991 120.25012991 0 0 0-43.06457788-29.01034333A167.59861869 167.59861869 0 0 0 653.74484128 286.53100586H472.31745703v402.31184159h88.45900175v-144.30015625z m0-189.39395508h68.7680432c10.14610474 0 19.84127148 0.75156302 29.31096924 2.25468995a68.39226126 68.39226126 0 0 1 24.80158936 8.79329077 47.72427072 47.72427072 0 0 1 17.13564355 18.33814456 64.48413233 64.48413233 0 0 1 6.46344479 30.96440824c0 12.77657663-2.1795339 23.07299344-6.46344479 30.96440911a47.6491138 47.6491138 0 0 1-17.21079959 18.33814456 68.09163623 68.09163623 0 0 1-24.80158936 8.71813474c-9.39454172 1.50312692-19.08970846 2.25468994-29.31096923 2.25468994H560.85161569V355.29904907z" p-id="7447" fill="#7E9F54"></path><path d="M997.43474439 61.06201172H101.72158671C79.2498442 61.06201172 61.06201172 80.60265817 61.06201172 104.65268362v814.69463276c0 24.05002634 18.18783249 43.5906719 40.65957499 43.5906719h895.71315768c22.47174337 0 40.65957499-19.54064646 40.65957497-43.5906719V104.65268362c0-24.05002634-18.18783249-43.5906719-40.65957497-43.5906719z m-20.36736551 835.73840524H122.0889531V126.44802001h854.97842578v770.35239695z" p-id="7448" fill="#7E9F54"></path></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1688290403407" class="icon" viewBox="0 0 1109 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8307" xmlns:xlink="http://www.w3.org/1999/xlink" width="38.98828125" height="36"><path d="M306.07165232 286.53100586h88.45900173v402.31184159H306.07165232V286.53100586z m254.70480646 258.08684225h92.9683825c25.1773713 0 46.59692575-3.68265995 64.25866333-10.97282467 17.66173758-7.36532077 32.01659717-16.9853306 43.06457788-29.01034421 11.12313675-12.02501272 19.1648645-25.85377829 24.27549445-41.48629492a152.94313406 152.94313406 0 0 0 0-95.44854056 111.6071521 111.6071521 0 0 0-24.27549445-41.18566989 120.25012991 120.25012991 0 0 0-43.06457788-29.01034333A167.59861869 167.59861869 0 0 0 653.74484128 286.53100586H472.31745703v402.31184159h88.45900175v-144.30015625z m0-189.39395508h68.7680432c10.14610474 0 19.84127148 0.75156302 29.31096924 2.25468995a68.39226126 68.39226126 0 0 1 24.80158936 8.79329077 47.72427072 47.72427072 0 0 1 17.13564355 18.33814456 64.48413233 64.48413233 0 0 1 6.46344479 30.96440824c0 12.77657663-2.1795339 23.07299344-6.46344479 30.96440911a47.6491138 47.6491138 0 0 1-17.21079959 18.33814456 68.09163623 68.09163623 0 0 1-24.80158936 8.71813474c-9.39454172 1.50312692-19.08970846 2.25468994-29.31096923 2.25468994H560.85161569V355.29904907z" p-id="8308" fill="#778391"></path><path d="M997.43474439 61.06201172H101.72158671C79.2498442 61.06201172 61.06201172 80.60265817 61.06201172 104.65268362v814.69463276c0 24.05002634 18.18783249 43.5906719 40.65957499 43.5906719h895.71315768c22.47174337 0 40.65957499-19.54064646 40.65957497-43.5906719V104.65268362c0-24.05002634-18.18783249-43.5906719-40.65957497-43.5906719z m-20.36736551 835.73840524H122.0889531V126.44802001h854.97842578v770.35239695z" p-id="8309" fill="#778391"></path></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -1,302 +1,304 @@
.el-drawer.rtl {
width: 700px !important;
}
.el-drawer__body {
.common-right-box {
height: 100%;
}
.right-box, .right-sub-box {
display: flex;
flex-direction: column;
padding: 0;
height: 100%;
width: 100%;
.el-date-editor {
.el-input__inner {
padding-left: 32px;
}
.el-drawer__body {
height: 100%;
}
}
.right-box__header {
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
padding: 0 20px;
border-bottom: 1px solid $--right-box-border-color;
.right-box, .right-sub-box {
display: flex;
flex-direction: column;
padding: 0;
height: 100%;
width: 100%;
.header__title {
font-size: 16px;
font-weight: bold;
color: #333;
}
.header__operation {
i {
color: #999;
font-size: 14px;
}
}
}
.right-box__container {
height: calc(100% - 130px);
padding: 0 30px;
overflow-x: hidden;
overflow-y: auto;
.el-textarea__inner {
padding: 5px 70px 4px 15px;
}
.container__form-width.container__form{
.input-box {
.el-textarea {
.el-textarea__inner {
width: 530px;
height: 32px;
padding: 5px 70px 4px 10px;
}
.el-input__count {
right: -40px;
line-height: 29px;
height: 25px;
}
.el-date-editor {
.el-input__inner {
padding-left: 32px;
}
}
}
.el-form-item__content {
.input-box {
.el-textarea {
.el-textarea__inner {
width: 517px;
height: 32px;
padding: 5px 70px 4px 10px;
}
.el-input__count {
right: -40px;
line-height: 29px;
height: 25px;
}
.right-box__header {
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
padding: 0 20px;
border-bottom: 1px solid $--right-box-border-color;
.header__title {
font-size: 16px;
font-weight: bold;
color: #333;
}
.header__operation {
i {
color: #999;
font-size: 14px;
}
}
}
.form-row-item {
.input-box {
.el-textarea {
.el-textarea__inner {
width: 466px;
height: 32px;
padding: 5px 70px 4px 10px;
}
.el-input__count {
right: 0;
.right-box__container {
height: calc(100% - 130px);
padding: 0 30px;
overflow-x: hidden;
overflow-y: auto;
.el-textarea__inner {
padding: 5px 70px 4px 15px;
}
.container__form-width.container__form{
.input-box {
.el-textarea {
.el-textarea__inner {
width: 530px;
height: 32px;
padding: 5px 70px 4px 10px;
}
.el-input__count {
right: -40px;
line-height: 29px;
height: 25px;
}
}
}
}
}
.el-form-item {
.el-input__count {
line-height: 29px;
height: 25px;
.el-form-item__content {
.input-box {
.el-textarea {
.el-textarea__inner {
width: 517px;
height: 32px;
padding: 5px 70px 4px 10px;
}
.el-input__count {
right: -40px;
line-height: 29px;
height: 25px;
}
}
}
}
}
.el-form-item {
.el-input--small.not-fixed-height {
height: 32px;
.form-row-item {
.input-box {
.el-textarea {
.el-textarea__inner {
width: 466px;
height: 32px;
padding: 5px 70px 4px 10px;
}
.el-input__count {
right: 0;
}
}
}
}
.el-form-item {
.el-input__count {
line-height: 29px;
height: 25px;
}
}
}
.el-input__inner, .el-textarea__inner {
padding: 0 10px;
border-radius: $--border-radius-primary;
border: 1px solid $--right-box-border-color;
}
.el-textarea__inner {
padding: 5px 70px 4px 15px;
}
.el-form {
padding-top: 20px;
.el-form-item {
margin-bottom: 16px;
.el-form-item__label{
padding-bottom: 6px;
font-size: 14px;
line-height: 16px;
color: #666;
}
.el-input__inner:hover {
border-color: darken($--right-box-border-color, 10%);
}
.el-input__inner:focus {
border-color: darken($--right-box-border-color, 20%);
.el-input--small.not-fixed-height {
height: 32px;
.el-input__count {
line-height: 29px;
height: 25px;
}
}
}
.el-form-item.is-error .el-input__inner, .el-form-item.is-error .el-input__inner:focus, .el-form-item.is-error .el-textarea__inner, .el-form-item.is-error .el-textarea__inner:focus, .el-message-box__input input.invalid, .el-message-box__input input.invalid:focus {
border-color: #F56C6C
}
.form__sub-title {
display: flex;
justify-content: space-between;
.el-input__inner, .el-textarea__inner {
padding: 0 10px;
margin-bottom: 20px;
line-height: 32px;
font-size: 14px;
font-weight: bold;
color: #555;
background-color: #F6F6F6;
}
/* 虚线框类型的form-item */
.form__dotted-item {
padding: 10px 10px 6px 10px;
margin-bottom: 10px;
border: 1px dashed $--border-color-primary;
border-radius: $--border-radius-primary;
border: 1px solid $--right-box-border-color;
}
.el-textarea__inner {
padding: 5px 70px 4px 15px;
}
.el-form {
padding-top: 20px;
.el-form-item {
margin-bottom: 0;
.el-form-item__label {
width: 100%;
margin-bottom: 16px;
.el-form-item__label{
padding-bottom: 6px;
font-size: 14px;
line-height: 16px;
color: #666;
}
.form__labels-label {
display: flex;
justify-content: space-between;
.el-input__inner:hover {
border-color: darken($--right-box-border-color, 10%);
}
.el-input__inner:focus {
border-color: darken($--right-box-border-color, 20%);
}
}
.el-form-item.is-error .el-input__inner, .el-form-item.is-error .el-input__inner:focus, .el-form-item.is-error .el-textarea__inner, .el-form-item.is-error .el-textarea__inner:focus, .el-message-box__input input.invalid, .el-message-box__input input.invalid:focus {
border-color: #F56C6C
}
.form__sub-title {
display: flex;
justify-content: space-between;
padding: 0 10px;
margin-bottom: 20px;
line-height: 32px;
font-size: 14px;
font-weight: bold;
color: #555;
background-color: #F6F6F6;
}
/* 虚线框类型的form-item */
.form__dotted-item {
padding: 10px 10px 6px 10px;
margin-bottom: 10px;
border: 1px dashed $--border-color-primary;
border-radius: $--border-radius-primary;
.el-form-item {
margin-bottom: 0;
.el-form-item__label {
width: 100%;
}
.form__labels-label {
display: flex;
justify-content: space-between;
}
}
}
.form__create-btn {
margin-bottom: 20px;
width: 300px;
height: 28px;
border: 1px solid lighten($--color-primary, 60%);
border-radius: $--border-radius-primary;
background-color: lighten($--color-primary, 95%);
i {
color: $--color-primary;
}
}
.form__flex-container {
display: flex;
justify-content: center;
align-items: center;
}
.one-third-form-item-left{
display: inline-block;
width: calc(50% - 5px);
}
.one-third-form-item-right{
display: inline-block;
width: calc(50% - 5px);
}
.form-item--half-width-other-two{
display: inline-block;
width: calc(50% - 10px);
}
.form-item--half-width-other{
display: inline-block;
width: calc(50% - 10px);
}
}
.form__create-btn {
margin-bottom: 20px;
}
.right-box__footer {
display: flex;
align-items: center;
justify-content: center;
height: 70px;
box-shadow: -3px 0 8px -3px rgba(205,205,205,0.77);
.footer__btn {
margin: 0 15px;
height: 30px;
min-width: 74px;
padding: 0 15px;
color: white;
background-color: $--color-primary;
border: none;
border-radius: 4px;
outline: none;
font-size: 14px;
cursor: pointer;
transition: background-color linear .2s, color linear .1s;
}
.footer__btn:hover:not(.footer__btn--disabled) {
background-color: lighten($--color-primary, 10%);
}
.footer__btn--light {
background-color: white;
border: 1px solid $--border-color-primary;
color: #333;
}
.footer__btn.footer__btn--light:hover:not(.footer__btn--disabled) {
background-color: white;
border-color: lighten($--color-primary, 40%);
color: $--color-primary;
}
.footer__btn--disabled {
opacity: .6;
cursor: default;
}
}
/* 隐藏label新增按钮处级联选择器的input */
.hide-casc-input {
position: relative;
.hide-input {
position: absolute;
top: 0;
width: 300px;
height: 28px;
border: 1px solid lighten($--color-primary, 60%);
border-radius: $--border-radius-primary;
background-color: lighten($--color-primary, 95%);
opacity: 0;
}
}
.label__multi-text {
display: flex;
justify-content: space-between;
}
.right-box__select {
width: 100%;
}
.el-select-last.right-box-select-dropdown {
left: 1698px;
}
.limit-height .el-cascader-menu {
max-height: 200px;
overflow: auto;
}
i {
color: $--color-primary;
.form-items--half-width-group {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.form-item--half-width {
width: calc(50% - 10px);
.el-select {
width: 100%;
}
}
.form__flex-container {
display: flex;
justify-content: center;
align-items: center;
}
.one-third-form-item-left{
display: inline-block;
width: calc(50% - 5px);
}
.one-third-form-item-right{
display: inline-block;
width: calc(50% - 5px);
}
.form-item--half-width-other-two{
display: inline-block;
width: calc(50% - 10px);
}
.form-item--half-width-other{
display: inline-block;
width: calc(50% - 10px);
}
}
}
.right-box__footer {
display: flex;
align-items: center;
justify-content: center;
height: 70px;
box-shadow: -3px 0 8px -3px rgba(205,205,205,0.77);
.footer__btn {
margin: 0 15px;
height: 30px;
min-width: 74px;
padding: 0 15px;
color: white;
background-color: $--color-primary;
border: none;
border-radius: 4px;
outline: none;
font-size: 14px;
cursor: pointer;
transition: background-color linear .2s, color linear .1s;
}
.footer__btn:hover:not(.footer__btn--disabled) {
background-color: lighten($--color-primary, 10%);
}
.footer__btn--light {
background-color: white;
border: 1px solid $--border-color-primary;
color: #333;
}
.footer__btn.footer__btn--light:hover:not(.footer__btn--disabled) {
background-color: white;
border-color: lighten($--color-primary, 40%);
color: $--color-primary;
}
.footer__btn--disabled {
opacity: .6;
cursor: default;
}
}
/* 隐藏label新增按钮处级联选择器的input */
.hide-casc-input {
position: relative;
.hide-input {
.cn-icon-minus-position {
display: inline-flex;
flex-direction: column;
position: absolute;
top: 0;
width: 300px;
opacity: 0;
right: 0;
top: 50%;
height: 100%;
transform: translateY(-50%);
justify-content: space-between;
}
.form-item--end-with-btn { // 末尾留出btn宽度空间的form item
}
.el-form-item__content .el-autocomplete .el-input-group {
vertical-align: unset;
}
}
.label__multi-text {
display: flex;
justify-content: space-between;
}
.right-box__select {
width: 100%;
}
.el-select-last.right-box-select-dropdown {
left: 1698px;
}
.limit-height .el-cascader-menu {
max-height: 200px;
overflow: auto;
}
.form-items--half-width-group {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.form-item--half-width {
width: calc(50% - 10px);
.el-select {
width: 100%;
}
}
}
.cn-icon-minus-position {
display: inline-flex;
flex-direction: column;
position: absolute;
right: 0;
top: 50%;
height: 100%;
transform: translateY(-50%);
justify-content: space-between;
}
.form-item--end-with-btn { // 末尾留出btn宽度空间的form item
}
.el-form-item__content .el-autocomplete .el-input-group {
vertical-align: unset;
}

View File

@@ -50,6 +50,8 @@
<el-drawer
v-model="rightBox.show"
direction="rtl"
custom-class="common-right-box"
:size="700"
:with-header="false"
destroy-on-close>
<chart-box

View File

@@ -74,6 +74,8 @@
<el-drawer
v-model="rightBox.show"
direction="rtl"
custom-class="common-right-box"
:size="700"
:with-header="false"
destroy-on-close>
<galaxy-proxy-box :object="object" @close="closeRightBox"></galaxy-proxy-box>

View File

@@ -51,6 +51,8 @@
<el-drawer
v-model="rightBox.show"
direction="rtl"
custom-class="common-right-box"
:size="700"
:with-header="false"
destroy-on-close>
<i18n-box

View File

@@ -52,7 +52,9 @@
<el-drawer
v-model="rightBox.show"
direction="rtl"
custom-class="common-right-box"
:with-header="false"
:size="700"
destroy-on-close>
<role-box :object="object" @close="closeRightBox"></role-box>
</el-drawer>

View File

@@ -49,6 +49,8 @@
<el-drawer
v-model="rightBox.show"
direction="rtl"
custom-class="common-right-box"
:size="700"
:with-header="false"
destroy-on-close>
<user-box

View File

@@ -1,46 +1,37 @@
<template>
<div class="entity-graph">
<div class="entity-graph__chart" id="entityGraph">
<relation-graph ref="relationGraph" :options="chartOption">
<template #node="{ node }">
<!-- root节点 -->
<template v-if="node.data.level === '1'">
<i :class="node.data.iconClass"></i>
<div class="graph-node__text">{{node.text}}</div>
</template>
<!-- primary节点 -->
<template v-else-if="node.data.level && node.data.level.length === 1">
<i :class="node.data.iconClass"></i>
<div class="graph-node__text">{{node.text}}({{node.data.count}})</div>
</template>
<!-- entity节点 -->
<template v-else-if="node.data.level && node.data.level.length === 3">
<i :class="node.data.iconClass"></i>
</template>
</template>
</relation-graph>
</div>
<div class="entity-graph__detail">
<ip-list
v-if="mode === 'ipList'"
:entity="entity"
@closeBlock="onCloseBlock"
@mouseenter="onMouseenter"
@expandDetail="onExpandDetail">
</ip-list>
<app-or-domain-list
v-if="mode === 'appList' || mode === 'domainList'"
:entity="entity"
@expandDetail="onExpandDetail"
@mouseenter="onMouseenter"
@closeBlock="onCloseBlock">
</app-or-domain-list>
<graph-detail
v-if="mode === 'appDetail' || mode === 'ipDetail' || mode === 'domainDetail'"
:entity="entity"
@expand="onExpand"
@closeBlock="onCloseBlock">
</graph-detail>
<div class="entity-graph__right-box">
<el-drawer
v-model="rightBox.show"
direction="rtl"
custom-class="entity-graph__detail"
:modal="false"
:size="360"
:with-header="false"
destroy-on-close>
<ip-list
v-if="rightBox.mode === 'ipList'"
:entity="entity"
@closeBlock="onCloseBlock"
@mouseenter="onMouseenter"
@expandDetail="onExpandDetail">
</ip-list>
<app-or-domain-list
v-if="rightBox.mode === 'appList' || rightBox.mode === 'domainList'"
:entity="entity"
@expandDetail="onExpandDetail"
@mouseenter="onMouseenter"
@closeBlock="onCloseBlock">
</app-or-domain-list>
<graph-detail
v-if="rightBox.mode === 'appDetail' || rightBox.mode === 'ipDetail' || rightBox.mode === 'domainDetail'"
:entity="entity"
@expand="onExpand"
@closeBlock="onCloseBlock">
</graph-detail>
</el-drawer>
</div>
</div>
</template>
@@ -54,104 +45,256 @@ import { ref, shallowRef } from 'vue'
import _ from 'lodash'
import { api } from '@/utils/api'
import axios from 'axios'
import RelationGraph from 'relation-graph/vue3'
import G6 from '@antv/g6'
import testData from './testData'
export default {
name: 'EntityRelationship',
components: {
IpList,
GraphDetail,
AppOrDomainList,
RelationGraph
AppOrDomainList
},
data () {
return {
rightBox: {
show: false
},
chartOption: {
debug: false
container: 'entityGraph',
layout: {
type: 'force',
preventOverlap: true,
linkDistance: (d) => {
if (!d.target.isRoot && d.target.data.level && d.target.data.level.length === 1) {
return 300
}
return 80
},
nodeStrength: (d) => {
if (!d.isRoot && d.data.level && d.data.level.length === 1) {
return -50
}
return -10
},
edgeStrength: (d) => {
if (!d.target.isRoot && d.target.data.level && d.target.data.level.length === 1) {
return 0.1
}
return 0.7
}
},
modes: {
default: ['drag-nodes', 'click-select', 'zoom-canvas']
}
}
}
},
methods: {
async init () {
/* 定义了以下几种节点类型和节点状态:
* 1.类型:根节点 root状态ip、app、domain;
* 2.类型:普通节点 primary状态normal、active;
* 3.类型:实体 entity状态1ip、app、domain状态2normal、active.
*
* ip基色#7E9F54domain基色#38ACD2app基色E5A219
*
* 为方便在逻辑上区分实体列表(圆圈节点)和实体(纯图标节点),将层级分为整层和半层两种,实体列表为整层,实体为半层。
* */
this.graphData.rootId = this.entity.entityName
// 初始化时加载到2层半
const rootNode = this.generateRootNode()
const _this = this
const graph = new G6.Graph(this.chartOption)
/*const rootNode = this.generateRootNode()
const secondLevelNodes = await this.generateSecondLevelNodes(rootNode)
const secondHalfLevelNodes = await this.generateHalfLevelNodes(secondLevelNodes)
this.graphData.nodes = [rootNode, ...secondLevelNodes, ...secondHalfLevelNodes]
this.graphData.lines = this.generateLines(rootNode)
this.graphData.lines.push(...this.generateLines(secondLevelNodes))
const rootEdges = this.generateEdges(rootNode)
const secondEdges = this.generateEdges(secondLevelNodes)
this.graphData.edges = [...rootEdges, ...secondEdges]
graph.data(this.graphData)*/
graph.data(testData)
graph.render()
console.info(JSON.stringify(this.graphData))
this.$refs.relationGraph.setJsonData(this.graphData)
graph.on('node:dragstart', function (e) {
graph.layout()
refreshDragedNodePosition(e)
})
graph.on('node:drag', function (e) {
refreshDragedNodePosition(e)
})
graph.on('node:dragend', function (e) {
e.item.get('model').fx = null
e.item.get('model').fy = null
})
graph.on('node:click', function (e) {
const node = e.item.get('model')
if (!_this.rightBox.show) {
_this.rightBox.show = true
}
if (node.data.level && node.data.level.length === 1) {
_this.rightBox.mode = `${node.data.type}List`
} else {
_this.rightBox.mode = `${node.data.type}Detail`
}
})
function refreshDragedNodePosition (e) {
const model = e.item.get('model')
model.fx = e.x
model.fy = e.y
}
},
generateIconUrl (entityType, colored, isRoot) {
let subfix = ''
if (entityType === 'domain' && isRoot) {
subfix = '-colored2'
} else {
subfix = colored ? '-colored' : ''
}
return `${window.location.protocol}//${window.location.host}/images/entity-symbol2/${entityType}${subfix}.svg`
},
generateRootNode () {
let iconClass = ''
let borderColor = ''
let shadowColor = ''
let width = 0
let height = 0
switch (this.entity.entityType) {
case 'ip': {
iconClass = 'cn-icon cn-icon-resolve-ip'
borderColor = '#CBD9BB'
shadowColor = 'rgba(126,159,84,0.14)'
width = 36
height = 33
break
}
case 'domain': {
iconClass = 'cn-icon cn-icon-domain1'
borderColor = '#AFDEED'
shadowColor = 'rgba(56,172,210,0.14)'
width = 36
height = 30
break
}
case 'app': {
iconClass = 'cn-icon cn-icon-app-name'
borderColor = '#F5DAA3'
shadowColor = 'rgba(229,162,25,0.14)'
width = 30
height = 36
break
}
}
return {
isRoot: true,
type: 'circle',
id: this.entity.entityName,
text: this.entity.entityName,
nodeShape: 0,
styleClass: `graph-node graph-node--root graph-node--${this.entity.entityType}`,
data: { level: '1', iconClass }
label: this.entity.entityName,
size: 82,
x: 0,
y: 0,
icon: {
show: true,
img: this.generateIconUrl(this.entity.entityType, true, true),
width,
height
},
style: {
fill: 'white',
stroke: borderColor,
lineWidth: 5
},
labelCfg: {
position: 'bottom',
offset: 10,
style: {
fill: '#353636',
fontSize: 12
}
},
data: {
level: '1'
}
}
},
generatePrimaryNode (props) {
const node = {
styleClass: 'graph-node graph-node--primary'
}
return {
...node,
...props
}
},
generateEntityNode (level, relatedType, data) {
let iconClass = ''
switch (relatedType) {
let width = 0
let height = 0
switch (props.data.type) {
case 'ip': {
iconClass = 'cn-icon cn-icon-resolve-ip'
width = 24
height = 22
break
}
case 'domain': {
iconClass = 'cn-icon cn-icon-subdomain'
width = 24
height = 24
break
}
case 'app': {
iconClass = 'cn-icon cn-icon-app-name'
width = 20
height = 24
break
}
}
return {
...props,
type: 'circle',
size: 66,
icon: {
show: true,
img: this.generateIconUrl(props.data.type, false),
width,
height
},
style: {
fill: 'white',
stroke: '#A7B0B9',
lineWidth: 1
},
labelCfg: {
position: 'bottom',
offset: 10,
style: {
fill: '#353636',
fontSize: 12
}
}
}
},
generateEntityNode (level, type, data) {
let width = 0
let height = 0
switch (type) {
case 'ip': {
width = 20
height = 18
break
}
case 'domain': {
width = 20
height = 20
break
}
case 'app': {
width = 17
height = 20
break
}
}
return {
id: data.vertex,
text: data.vertex,
styleClass: `graph-node graph-node--entity graph-node--${relatedType}`,
type: 'circle',
size: 28,
icon: {
show: true,
img: this.generateIconUrl(type, true),
width,
height
},
style: {
fill: 'transparent',
stroke: 'transparent',
lineWidth: 0
},
labelCfg: {
position: 'bottom',
offset: 10,
style: {
fill: '#353636',
fontSize: 12
}
},
data: {
level,
iconClass,
entityName: data.vertex,
entityType: relatedType
type,
name: data.vertex,
data
}
}
},
@@ -164,56 +307,62 @@ export default {
if (relatedEntityCount) {
const ipNode = this.generatePrimaryNode({
id: 'ip-1',
text: this.$t('entities.graph.resolveIp'),
label: this.$t('entities.graph.resolveIp'),
x: 0,
y: 300,
data: {
level: '2',
iconClass: 'cn-icon cn-icon-resolve-ip',
entityName: this.entity.entityName,
entityType: this.entity.entityType,
relatedType: 'ip'
sourceName: this.entity.entityName,
sourceType: this.entity.entityType,
type: 'ip'
}
})
const domainNode = this.generatePrimaryNode({
id: 'domain-1',
text: this.$t('entity.graph.resolveDomain'),
label: this.$t('entity.graph.resolveDomain'),
x: 260,
y: -150,
data: {
level: '2',
iconClass: 'cn-icon cn-icon-subdomain',
entityName: this.entity.entityName,
entityType: this.entity.entityType,
relatedType: 'domain'
sourceName: this.entity.entityName,
sourceType: this.entity.entityType,
type: 'domain'
}
})
const subdomainNode = this.generatePrimaryNode({
id: 'domain-1',
text: this.$t('entities.subdomain'),
label: this.$t('entities.subdomain'),
x: 260,
y: -150,
data: {
level: '2',
iconClass: 'cn-icon cn-icon-subdomain',
entityName: this.entity.entityName,
entityType: this.entity.entityType,
relatedType: 'domain'
sourceName: this.entity.entityName,
sourceType: this.entity.entityType,
type: 'domain'
}
})
const appNode = this.generatePrimaryNode({
id: 'app-1',
text: this.$t('entities.tab.relatedApp'),
label: this.$t('entities.tab.relatedApp'),
x: -260,
y: -150,
data: {
level: '2',
iconClass: 'cn-icon cn-icon-app-name',
entityName: this.entity.entityName,
entityType: this.entity.entityType,
relatedType: 'app'
sourceName: this.entity.entityName,
sourceType: this.entity.entityType,
type: 'app'
}
})
switch (this.entity.entityType) {
case 'ip': {
if (relatedEntityCount.domainCount) {
domainNode.data.count = relatedEntityCount.domainCount
domainNode.label += `(${relatedEntityCount.domainCount})`
nodes.push(domainNode)
}
if (relatedEntityCount.appCount) {
domainNode.data.count = relatedEntityCount.appCount
appNode.data.count = relatedEntityCount.appCount
appNode.label += `(${relatedEntityCount.appCount})`
nodes.push(appNode)
}
break
@@ -221,14 +370,17 @@ export default {
case 'domain': {
if (relatedEntityCount.ipCount) {
ipNode.data.count = relatedEntityCount.ipCount
ipNode.label += `(${relatedEntityCount.ipCount})`
nodes.push(ipNode)
}
if (relatedEntityCount.subDomainCount) {
subdomainNode.data.count = relatedEntityCount.subDomainCount
subdomainNode.label += `(${relatedEntityCount.subDomainCount})`
nodes.push(subdomainNode)
}
if (relatedEntityCount.appCount) {
appNode.data.count = relatedEntityCount.appCount
appNode.label += `(${relatedEntityCount.appCount})`
nodes.push(appNode)
}
break
@@ -236,10 +388,12 @@ export default {
case 'app': {
if (relatedEntityCount.ipCount) {
ipNode.data.count = relatedEntityCount.ipCount
ipNode.label += `(${relatedEntityCount.ipCount})`
nodes.push(ipNode)
}
if (relatedEntityCount.domainCount) {
domainNode.data.count = relatedEntityCount.domainCount
domainNode.label += `(${relatedEntityCount.domainCount})`
nodes.push(domainNode)
}
break
@@ -247,17 +401,18 @@ export default {
}
rootNode.data.childNodes = nodes
}
console.info(nodes)
return nodes
},
async generateHalfLevelNodes (nodes) {
const newNodes = []
for (const node of nodes) {
const newNodes2 = []
const data = await this.queryRelatedEntity(node.data.entityType, node.data.entityName, node.data.relatedType)
const data = await this.queryRelatedEntity(node.data.sourceType, node.data.sourceName, node.data.type)
if (data) {
// 生成节点
data.list.forEach(d => {
newNodes2.push(this.generateEntityNode(String(parseInt(node.data.level) + 0.5), node.data.relatedType, d))
newNodes2.push(this.generateEntityNode(String(parseInt(node.data.level) + 0.5), node.data.type, d))
})
// 更新源节点的已拓展数和列表
this.handleLoaded(node, data, newNodes2)
@@ -281,12 +436,12 @@ export default {
return null
}
},
async queryRelatedEntity (entityType, entityName, relatedType) {
if (entityType === relatedType) {
async queryRelatedEntity (sourceType, sourceName, type) {
if (sourceType === type) {
// 若源type和关联type都是domain说明关联type是subdomain
relatedType = 'subdomain'
type = 'subdomain'
}
const response = await axios.get(`${api.entity.entityGraph[`${entityType}Related${_.upperFirst(relatedType)}`]}?resource=${entityName}`).catch(e => {
const response = await axios.get(`${api.entity.entityGraph[`${sourceType}Related${_.upperFirst(type)}`]}?resource=${sourceName}`).catch(e => {
console.error(e)
this.showError = true
this.errorMsg = this.errorMsgHandler(e)
@@ -304,8 +459,8 @@ export default {
* 若只有一个参数则取参数的childNodes集合作为line终点
* 若有两个参数则以第一个参数作为line起点第二个参数作为终点
* */
generateLines (source, target) {
const lines = []
generateEdges (source, target) {
const edges = []
if (!target) {
const sourceArr = []
@@ -316,20 +471,26 @@ export default {
}
sourceArr.forEach(s => {
if (s.data && s.data.childNodes) {
const lines2 = []
const edges2 = []
s.data.childNodes.forEach(c => {
lines2.push({
from: s.id,
to: c.id,
color: '#BEBEBE'
edges2.push({
id: `${s.id}-${c.id}`,
source: s.id,
target: c.id,
style: {
stroke: '#BEBEBE',
endArrow: {
path: G6.Arrow.triangle(5, 5)
}
}
})
})
s.lines = lines2
lines.push(...lines2)
s.edges = edges2
edges.push(...edges2)
}
})
}
return lines
return edges
},
handleLoaded (node, data, childNodes) {
if (!node.data.loaded) {
@@ -344,10 +505,11 @@ export default {
},
onCloseBlock () {
// todo 关闭右侧graph面板
this.mode = ''
this.rightBox.mode = ''
this.rightBox.show = false
},
onExpandDetail (mode) {
this.mode = mode
this.rightBox.mode = mode
},
onExpand (val) {
// todo 调用接口,拓展关系
@@ -371,7 +533,10 @@ export default {
entityType,
entityName
}
const mode = ref('ipList') // ipList, ipDetail, domainList, domainDetail, appList, appDetail
const rightBox = ref({
mode: 'ipList', // ipList, ipDetail, domainList, domainDetail, appList, appDetail
show: false
})
// echarts关系图的节点和连线
const graphData = ref({})
@@ -381,7 +546,7 @@ export default {
graphData,
entity,
myChart,
mode
rightBox
}
}
}
@@ -390,11 +555,8 @@ export default {
.entity-graph {
display: flex;
.rel-node-peel {
padding: 4px;
}
.entity-graph__chart {
width: calc(100% - 360px);
width: 100%;
.graph-node {
display: flex;
@@ -421,7 +583,7 @@ export default {
}
&.graph-node--ip {
border-color: #CBD9BB !important;
box-shadow: 0 0 0 8px #EDF1E7;
box-shadow: 0 0 0 8px rgba(126,159,84,0.14);
i {
color: #7E9F54;
}
@@ -435,7 +597,7 @@ export default {
}
&.graph-node--app {
border-color: #F5DAA3 !important;
box-shadow: 0 0 0 8px #FBF2DF;
box-shadow: 0 0 0 8px rgba(229,162,25,0.14);
i {
color: #E5A219;
}
@@ -497,12 +659,19 @@ export default {
}
}
}
.entity-graph__detail {
width: 360px;
border-left: 1px solid #E2E5EC;
overflow: auto;
padding: 20px;
.entity-graph__right-box {
& > div {
left: unset !important;
right: 0 !important;
width: 360px;
}
.entity-graph__detail {
height: calc(100% - 100px) !important;
top: 100px !important;
border-left: 1px solid #E2E5EC;
overflow: auto;
padding: 20px;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -66,6 +66,8 @@
<el-drawer
v-model="rightBox.show"
direction="rtl"
custom-class="common-right-box"
:size="700"
:with-header="false"
destroy-on-close>
<report-box