CN-1548 feat: 关系图用force-graph重新开发

This commit is contained in:
chenjinsong
2024-06-12 18:00:44 +08:00
parent 80a83f0b11
commit 83ad7a3ee8
5 changed files with 580 additions and 1072 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "cn",
"version": "0.1.0",
"version": "24.04",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@@ -18,10 +18,12 @@
"babel-plugin-lodash": "~3.3.0",
"codemirror": "^5.65.1",
"core-js": "~3.31.0",
"d3": "^7.9.0",
"dayjs": "^1.10.5",
"dexie": "~3.2.0",
"echarts": "^5.1.1",
"element-plus": "^2.5.1",
"force-graph": "^1.43.5",
"h3-js": "~3.7.2",
"lib-flexible": "^0.3.2",
"lodash": "^4.17.21",

File diff suppressed because it is too large Load Diff

View File

@@ -1,52 +0,0 @@
import G6 from '@antv/g6'
export default class Edge {
constructor (sourceNode, targetNode, type) {
this.id = sourceNode.id + '__' + targetNode.id
this.source = sourceNode.id
this.target = targetNode.id
this.isTemp = type === 'temp'
this.style = type === 'temp' ? tempStyles.style : normalStyles.style
this.stateStyles = type === 'temp' ? tempStyles.stateStyles : normalStyles.stateStyles
}
}
const normalStyles = {
style: {
stroke: '#BEBEBE',
endArrow: {
path: G6.Arrow.triangle(5, 5),
fill: '#BEBEBE'
}
},
stateStyles: {
mySelected: {
stroke: '#778391',
endArrow: {
path: G6.Arrow.triangle(5, 5),
fill: '#778391'
}
}
}
}
const tempStyles = {
style: {
endArrow: {
path: G6.Arrow.triangle(5, 5),
fill: '#DDD'
},
stroke: '#DDD',
lineDash: [3, 2]
},
stateStyles: {
mySelected: {
stroke: '#DDD',
endArrow: {
path: G6.Arrow.triangle(5, 5),
fill: '#DDD'
},
lineDash: [3, 2]
}
}
}

View File

@@ -0,0 +1,8 @@
export default class Link {
constructor (sourceNode, targetNode, type) {
this.id = sourceNode.id + '__' + targetNode.id
this.source = sourceNode.id
this.target = targetNode.id
this.isTemp = type === 'temp'
}
}

View File

@@ -25,6 +25,10 @@ export default class Node {
this.sourceNode = sourceNode
}
this.label = this.generateLabel()
const img = new Image()
img.src = this.getIconUrl(cfg.entityType, type === nodeType.rootNode)
this.img = img
}
generateLabel () {
@@ -34,7 +38,7 @@ export default class Node {
return this.id
}
case nodeType.listNode: {
return `${this.getLabelText()}(${_.get(this.sourceNode.myData, 'relatedEntity.' + this.myData.entityType + '.total', 0)})`
return `${this.getLabelText()}(${_.get(this.sourceNode.myData, 'relatedEntities.' + this.myData.entityType + '.total', 0)})`
}
case nodeType.tempNode: {
return this.getLabelText()
@@ -64,6 +68,11 @@ export default class Node {
return ''
}
getIconUrl (entityType, colored) {
const suffix = colored ? '-colored' : ''
return require(`@/assets/img/entity-symbol2/${entityType}${suffix}.svg`)
}
isSubdomain () {
if (this.sourceNode) {
return this.sourceNode.myData.entityType === 'domain' && this.myData.entityType === 'domain'
@@ -87,11 +96,11 @@ export default class Node {
}
this.myData.tags = _tags
const relatedEntityTotalCount = await this.queryRelatedEntityCount(entityType, entityName)
this.myData.relatedEntity = {
ip: { total: relatedEntityTotalCount.ipCount, list: [] },
domain: { total: this.myData.entityType === 'domain' ? relatedEntityTotalCount.subDomainCount : relatedEntityTotalCount.domainCount, list: [] },
app: { total: relatedEntityTotalCount.appCount, list: [] }
const relatedEntityTotalCount = await this.queryRelatedEntitiesCount(entityType, entityName)
this.myData.relatedEntities = {
ip: { total: relatedEntityTotalCount.ipCount, loadedCount: 0 },
domain: { total: this.myData.entityType === 'domain' ? relatedEntityTotalCount.subDomainCount : relatedEntityTotalCount.domainCount, loadedCount: 0 },
app: { total: relatedEntityTotalCount.appCount, loadedCount: 0 }
}
}
@@ -121,7 +130,7 @@ export default class Node {
}
}
async queryRelatedEntityCount (entityType, entityName) {
async queryRelatedEntitiesCount (entityType, entityName) {
const response = await axios.get(`${api.entity.entityGraph.relatedEntityCount}/${entityType}?resource=${entityName}`).catch(e => {
console.error(e)
throw e
@@ -137,7 +146,7 @@ export default class Node {
export const nodeType = {
rootNode: 'rootNode',
listNode: 'listNode',
entityNode: 'entityNode',
entityNode: 'en-tityNode',
tempNode: 'tempNode'
}
export async function queryRelatedEntity (node, targetEntityType) {
@@ -146,7 +155,7 @@ export async function queryRelatedEntity (node, targetEntityType) {
_targetEntityType = 'subdomain'
}
let url = `${api.entity.entityGraph[`${node.myData.entityType}Related${_.upperFirst(_targetEntityType)}`]}?resource=${node.myData.entityName}&pageSize=10`
const current = node.myData.relatedEntity[targetEntityType].list.length
const current = node.myData.relatedEntities[targetEntityType].loadedCount
const pageNo = parseInt(current / 10) + 1
url += `&pageNo=${pageNo}`
const response = await axios.get(url).catch(e => {