diff --git a/src/assets/css/components/views/charts2/graphRightDetailBlock.scss b/src/assets/css/components/views/charts2/graphRightDetailBlock.scss index d49d19ff..41ab1046 100644 --- a/src/assets/css/components/views/charts2/graphRightDetailBlock.scss +++ b/src/assets/css/components/views/charts2/graphRightDetailBlock.scss @@ -32,7 +32,7 @@ $font-size: 12px; .graph-basic-info-name { padding-right: 10px; - width: 260px; + max-width: 260px; font-size: 20px; color: #353636; font-weight: 700; diff --git a/src/assets/css/font/iconfont.css b/src/assets/css/font/iconfont.css index 41be4fc3..378e85db 100644 --- a/src/assets/css/font/iconfont.css +++ b/src/assets/css/font/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "cn-icon"; /* Project id 2614877 */ - src: url('iconfont.woff2?t=1688009911333') format('woff2'), - url('iconfont.woff?t=1688009911333') format('woff'), - url('iconfont.ttf?t=1688009911333') format('truetype'); + src: url('iconfont.woff2?t=1689317280458') format('woff2'), + url('iconfont.woff?t=1689317280458') format('woff'), + url('iconfont.ttf?t=1689317280458') format('truetype'); } .cn-icon { @@ -13,6 +13,38 @@ -moz-osx-font-smoothing: grayscale; } +.cn-icon-add-knowledge-base:before { + content: "\e802"; +} + +.cn-icon-update-knowledge-base:before { + content: "\e803"; +} + +.cn-icon-zoom-out:before { + content: "\e7fd"; +} + +.cn-icon-to-default:before { + content: "\e7fe"; +} + +.cn-icon-reset:before { + content: "\e7ff"; +} + +.cn-icon-next-step:before { + content: "\e800"; +} + +.cn-icon-pre-step:before { + content: "\e801"; +} + +.cn-icon-zoom-in:before { + content: "\e7f"; +} + .cn-icon-expand-continue:before { content: "\e7fc"; } diff --git a/src/assets/css/font/iconfont.js b/src/assets/css/font/iconfont.js index d962ebe9..1f1b6e01 100644 --- a/src/assets/css/font/iconfont.js +++ b/src/assets/css/font/iconfont.js @@ -1 +1 @@ -window._iconfont_svg_string_2614877='',function(l){var a=(a=document.getElementsByTagName("script"))[a.length-1],c=a.getAttribute("data-injectcss"),a=a.getAttribute("data-disable-injectsvg");if(!a){var h,o,i,m,v,z=function(a,c){c.parentNode.insertBefore(a,c)};if(c&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}h=function(){var a,c=document.createElement("div");c.innerHTML=l._iconfont_svg_string_2614877,(c=c.getElementsByTagName("svg")[0])&&(c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.width=0,c.style.height=0,c.style.overflow="hidden",c=c,(a=document.body).firstChild?z(c,a.firstChild):a.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),h()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(i=h,m=l.document,v=!1,s(),m.onreadystatechange=function(){"complete"==m.readyState&&(m.onreadystatechange=null,t())})}function t(){v||(v=!0,i())}function s(){try{m.documentElement.doScroll("left")}catch(a){return void setTimeout(s,50)}t()}}(window); \ No newline at end of file +window._iconfont_svg_string_2614877='',function(l){var a=(a=document.getElementsByTagName("script"))[a.length-1],c=a.getAttribute("data-injectcss"),a=a.getAttribute("data-disable-injectsvg");if(!a){var h,o,i,m,v,z=function(a,c){c.parentNode.insertBefore(a,c)};if(c&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}h=function(){var a,c=document.createElement("div");c.innerHTML=l._iconfont_svg_string_2614877,(c=c.getElementsByTagName("svg")[0])&&(c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.width=0,c.style.height=0,c.style.overflow="hidden",c=c,(a=document.body).firstChild?z(c,a.firstChild):a.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),h()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(i=h,m=l.document,v=!1,s(),m.onreadystatechange=function(){"complete"==m.readyState&&(m.onreadystatechange=null,t())})}function t(){v||(v=!0,i())}function s(){try{m.documentElement.doScroll("left")}catch(a){return void setTimeout(s,50)}t()}}(window); diff --git a/src/assets/css/font/iconfont.ttf b/src/assets/css/font/iconfont.ttf index 6143168f..d19823cf 100644 Binary files a/src/assets/css/font/iconfont.ttf and b/src/assets/css/font/iconfont.ttf differ diff --git a/src/assets/css/font/iconfont.woff b/src/assets/css/font/iconfont.woff index f6d150fd..972a5dcc 100644 Binary files a/src/assets/css/font/iconfont.woff and b/src/assets/css/font/iconfont.woff differ diff --git a/src/assets/css/font/iconfont.woff2 b/src/assets/css/font/iconfont.woff2 index 574d32bf..162b078f 100644 Binary files a/src/assets/css/font/iconfont.woff2 and b/src/assets/css/font/iconfont.woff2 differ diff --git a/src/views/entityExplorer/EntityGraph.vue b/src/views/entityExplorer/EntityGraph.vue index b899056b..b571a3cd 100644 --- a/src/views/entityExplorer/EntityGraph.vue +++ b/src/views/entityExplorer/EntityGraph.vue @@ -57,6 +57,7 @@ import { api } from '@/utils/api' import axios from 'axios' import G6, { Algorithm } from '@antv/g6' import { entityDetailTags } from '@/utils/constants' +import { ElMessage } from 'element-plus' export default { name: 'EntityRelationship', @@ -102,6 +103,7 @@ export default { async init () { const _this = this const tooltip = this.buildTooltip() // tooltip组件 + // const toolbar = this.buildToolbar() // 工具栏组装件 this.chartOption.plugins = [tooltip] this.graph = new G6.Graph(this.chartOption) const rootNode = await this.generateRootNode() @@ -112,7 +114,7 @@ export default { const rootEdges = this.generateEdges(rootNode) const secondEdges = this.generateEdges(secondLevelNodes) this.graphData.edges = [...rootEdges, ...secondEdges] - console.info(this.graphData) + // console.info(this.graphData) this.graph.data(this.graphData) this.graph.render() this.graph.on('node:dragstart', function (e) { @@ -206,7 +208,7 @@ export default { n.label = _this.$t('entities.subdomain') + `(${n.data.count})` } else { n.data.count = relatedEntityCount.domainCount - n.label = _this.$t('entity.graph.resolveDomain') + `(${n.data.count})` + n.label = _this.$t('entity.graph.resolvedDomain') + `(${n.data.count})` } break } @@ -260,7 +262,7 @@ export default { node.label = _this.$t('entities.subdomain') + `(${node.data.count})` } else { node.data.count = queryRelatedEntityCount.domainCount - node.label = _this.$t('entity.graph.resolveDomain') + `(${node.data.count})` + node.label = _this.$t('entity.graph.resolvedDomain') + `(${node.data.count})` } break } @@ -317,7 +319,7 @@ export default { n.label = _this.$t('entities.subdomain') + `(${n.data.count})` } else { n.data.count = relatedEntityCount.domainCount - n.label = _this.$t('entity.graph.resolveDomain') + `(${n.data.count})` + n.label = _this.$t('entity.graph.resolvedDomain') + `(${n.data.count})` } break } @@ -378,7 +380,7 @@ export default { // TODO 高亮 } else { - // TODO 提示无法拓展 + this.$message.error(this.$t('entities.graph.expandedLevelMaxLimit')) } _this.addNodes(entityNodes) _this.addEdges(edges) @@ -610,7 +612,11 @@ export default { case 'ip': { width = 24 height = 22 - label = this.$t('entities.graph.resolveIp') + if (node.data.type === 'app') { + label = this.$t('entities.tab.relatedIp') + } else if (node.data.type === 'ip') { + label = this.$t('entities.graph.resolveIp') + } break } case 'subdomain': { @@ -622,7 +628,11 @@ export default { case 'domain': { width = 24 height = 24 - label = this.$t('entity.graph.resolveDomain') + if (node.data.type === 'app') { + label = this.$t('entities.relatedDomain') + } else if (node.data.type === 'ip') { + label = this.$t('entities.graph.resolvedDomain') + } break } case 'app': { @@ -698,7 +708,7 @@ export default { const domainNode = this.generatePrimaryNode({ id: 'domain-1', parentId: rootNode.id, - label: this.$t('entity.graph.resolveDomain'), + label: this.$t('entity.graph.resolvedDomain'), x: 260, y: -150, data: { @@ -1130,7 +1140,7 @@ export default { } case 'domain': { iconClass = 'cn-icon cn-icon-subdomain' - title = _this.$t('entity.graph.resolveDomain') + title = _this.$t('entity.graph.resolvedDomain') break } case 'app': { @@ -1142,8 +1152,8 @@ export default { return `
${title}
- ${_this.$t('entity.graph.associatedQuantity')}: ${node.data.count || 0} - ${_this.$t('entity.graph.expandedEntityQuantity')}: ${node.data.loaded ? node.data.loaded.length : 0} + ${_this.$t('entity.graph.associatedCount')}: ${node.data.count || 0} + ${_this.$t('entity.graph.expandedEntityCount')}: ${node.data.loaded ? node.data.loaded.length : 0}
` } else if (node.nodeType === 'entity' || node.nodeType === 'root') { @@ -1180,28 +1190,57 @@ export default { } }) }, + buildToolbar () { + const tc = document.createElement('div') + tc.id = 'toolbarContainer' + tc.className = 'graph-toolbar' + document.body.appendChild(tc) + const toolbar = new G6.ToolBar({ + container: tc, + className: 'toolbar__tools', + getContent: () => { + return `` + }, + handleClick: (code, graph) => { + console.info(code) + toolbar.handleDefaultOperator(code) + } + }) + return toolbar + }, async expandList (sourceNodeId, nodeId) { - this.entity.loading = true const sourceNode = this.graphData.nodes.find(n => n.id === sourceNodeId) const node = this.graphData.nodes.find(n => n.id === nodeId) if (node && sourceNode) { + console.info(node) if (node.data.childNodes && node.data.childNodes.length < 50) { - const queryEntityNodes = await this.generateHalfLevelNodes(node) - const relatedEntityCount = await this.queryRelatedEntityCount(sourceNode.data.type, sourceNodeId) - // 赋值总数和已拓展数。entity node可从其childNodes取到已拓展数 - this.entity = { - ...this.entity, - relatedEntityCount: this.handleRelatedEntityCount(sourceNode, relatedEntityCount), - listData: node.data.loaded, - loading: false - } - sourceNode.data.relatedEntityCount = this.entity.relatedEntityCount + if (node.data.childNodes.length >= node.data.count) { + this.$message.error(this.$t('entities.graph.allEntitiesExpanded')) + } else { + this.entity.loading = true + const queryEntityNodes = await this.generateHalfLevelNodes(node) + const relatedEntityCount = await this.queryRelatedEntityCount(sourceNode.data.type, sourceNodeId) + // 赋值总数和已拓展数。entity node可从其childNodes取到已拓展数 + this.entity = { + ...this.entity, + relatedEntityCount: this.handleRelatedEntityCount(sourceNode, relatedEntityCount), + listData: node.data.loaded, + loading: false + } + sourceNode.data.relatedEntityCount = this.entity.relatedEntityCount - this.addNodes(queryEntityNodes) - this.addEdges(this.generateEdges(node, queryEntityNodes)) - this.graph.changeData(this.graphData) + this.addNodes(queryEntityNodes) + this.addEdges(this.generateEdges(node, queryEntityNodes)) + this.graph.changeData(this.graphData) + } } else { - // TODO 提示已达50上限 + this.$message.error(this.$t('entities.graph.expandedNumberMaxLimit')) } } }, @@ -1255,7 +1294,7 @@ export default { edges.push(...this.generateEdges(primaryNode)) // TODO 高亮 } else { - // TODO 提示无法拓展 + this.$message.error(this.$t('entities.graph.expandedLevelMaxLimit')) } this.addNodes(entityNodes) this.addEdges(edges) @@ -1294,6 +1333,29 @@ export default { }