CN-1548 feat: 调整节点样式
This commit is contained in:
@@ -49,7 +49,6 @@ import { useRoute } from 'vue-router'
|
|||||||
import { ref, shallowRef } from 'vue'
|
import { ref, shallowRef } from 'vue'
|
||||||
import ForceGraph from 'force-graph'
|
import ForceGraph from 'force-graph'
|
||||||
import { Algorithm } from '@antv/g6'
|
import { Algorithm } from '@antv/g6'
|
||||||
// import ForceGraph3D from '3d-force-graph'
|
|
||||||
import * as d3 from 'd3'
|
import * as d3 from 'd3'
|
||||||
import Node, { nodeType } from './entityGraph/node'
|
import Node, { nodeType } from './entityGraph/node'
|
||||||
import Link, { linkType } from './entityGraph/link'
|
import Link, { linkType } from './entityGraph/link'
|
||||||
@@ -71,9 +70,8 @@ export default {
|
|||||||
links: [],
|
links: [],
|
||||||
graph: shallowRef(null),
|
graph: shallowRef(null),
|
||||||
defaultChargeStrength: -20, // 之前的设置-20
|
defaultChargeStrength: -20, // 之前的设置-20
|
||||||
defaultLinkDistance: 40,
|
defaultLinkDistance: 80,
|
||||||
defaultMargin: 2, // 图像与箭头的距离
|
defaultMargin: 2, // 图像与箭头的距离
|
||||||
clickNode: null,
|
|
||||||
rootNode: null
|
rootNode: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -82,110 +80,193 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const initialData = await this.generateInitialData()
|
const initialData = await this.generateInitialData()
|
||||||
this.initialData = _.cloneDeep(initialData) // 初始化数据
|
this.initialData = _.cloneDeep(initialData) // 初始化数据
|
||||||
|
console.info(initialData)
|
||||||
let hoverNode = null
|
let hoverNode = null
|
||||||
this.graph = ForceGraph()(document.getElementById('entityGraph'))
|
this.graph = ForceGraph()(document.getElementById('entityGraph'))
|
||||||
.graphData(initialData)
|
.graphData(initialData)
|
||||||
.nodeCanvasObject((node, ctx) => {
|
.nodeCanvasObject((node, ctx) => {
|
||||||
|
/*
|
||||||
|
* 共有4种 nodeType,3种 entityType
|
||||||
|
* */
|
||||||
const nodeStyle = this.getNodeStyle(node.type, node.data.entityType)
|
const nodeStyle = this.getNodeStyle(node.type, node.data.entityType)
|
||||||
const iconWidth = nodeStyle.iconWidth / 2
|
switch (node.type) {
|
||||||
const iconHeight = nodeStyle.iconHeight / 2
|
case nodeType.rootNode: {
|
||||||
const x = node.x - iconWidth / 2
|
// 如果是鼠标点击高亮的,最外层加上第三层圆环
|
||||||
const y = node.y - iconHeight / 2
|
if (node === this.clickNode) {
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(node.x, node.y, nodeStyle.selectedShadowR, 0, 2 * Math.PI, false)
|
||||||
|
ctx.closePath()
|
||||||
|
ctx.fillStyle = nodeStyle.selectedShadowColor
|
||||||
|
ctx.fill()
|
||||||
|
}
|
||||||
|
|
||||||
if (node.type === nodeType.rootNode) {
|
// 第二层圆环
|
||||||
if (this.clickNode && this.clickNode.type === nodeType.rootNode) {
|
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
ctx.lineWidth = 1
|
ctx.arc(node.x, node.y, nodeStyle.shadowR, 0, 2 * Math.PI, false)
|
||||||
ctx.strokeStyle = 'transparent'
|
ctx.closePath()
|
||||||
ctx.arc(node.x, node.y, nodeStyle.selectedShadowR / 2, 0, Math.PI * 2)
|
ctx.fillStyle = node === this.clickNode || node === hoverNode ?
|
||||||
ctx.fillStyle = nodeStyle.selectedShadowColor// 先画圆形,才能填色
|
nodeStyle.hoveredShadowColor :
|
||||||
|
nodeStyle.shadowColor
|
||||||
|
ctx.fill()
|
||||||
|
// 内部挖空
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(node.x, node.y, nodeStyle.innerR, 0, 2 * Math.PI, false)
|
||||||
|
ctx.closePath()
|
||||||
|
ctx.fillStyle = nodeStyle.fillStyle
|
||||||
ctx.fill()
|
ctx.fill()
|
||||||
ctx.stroke()
|
|
||||||
|
|
||||||
|
// 第一层圆环
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
|
ctx.arc(node.x, node.y, nodeStyle.innerR, 0, 2 * Math.PI, false)
|
||||||
|
ctx.closePath()
|
||||||
ctx.lineWidth = 1
|
ctx.lineWidth = 1
|
||||||
ctx.strokeStyle = 'transparent'
|
ctx.strokeStyle = nodeStyle.borderColor
|
||||||
ctx.arc(node.x, node.y, nodeStyle.shadowR / 2, 0, Math.PI * 2)
|
|
||||||
ctx.fillStyle = nodeStyle.shadowColor
|
|
||||||
ctx.fill()
|
|
||||||
ctx.stroke()
|
|
||||||
} else if (hoverNode && hoverNode.id === node.id) {
|
|
||||||
ctx.beginPath()
|
|
||||||
ctx.lineWidth = 1
|
|
||||||
ctx.strokeStyle = 'transparent'
|
|
||||||
ctx.arc(node.x, node.y, nodeStyle.shadowR / 2, 0, Math.PI * 2)
|
|
||||||
ctx.fillStyle = nodeStyle.hoveredShadowColor
|
|
||||||
ctx.fill()
|
|
||||||
ctx.stroke()
|
|
||||||
} else {
|
|
||||||
ctx.beginPath()
|
|
||||||
ctx.lineWidth = 1
|
|
||||||
ctx.strokeStyle = 'transparent'
|
|
||||||
ctx.arc(node.x, node.y, nodeStyle.shadowR / 2, 0, Math.PI * 2)
|
|
||||||
ctx.fillStyle = nodeStyle.shadowColor
|
|
||||||
ctx.fill()
|
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
|
// 图片
|
||||||
|
ctx.drawImage(node.img, node.x - nodeStyle.iconWidth / 2, node.y - nodeStyle.iconHeight / 2, nodeStyle.iconWidth, nodeStyle.iconHeight);
|
||||||
|
// 文字
|
||||||
|
ctx.font = nodeStyle.font
|
||||||
|
const textWidth = ctx.measureText(node.label).width
|
||||||
|
const bckgDimensions = [textWidth, 9].map(n => n + 9 * 0.2)
|
||||||
|
ctx.fillStyle = nodeStyle.fontBgColor
|
||||||
|
ctx.fillRect(node.x - bckgDimensions[0] / 2, node.y - bckgDimensions[1] / 2 + 31, ...bckgDimensions) // 文字的白底
|
||||||
|
|
||||||
|
ctx.textAlign = 'center'
|
||||||
|
ctx.textBaseline = 'middle'
|
||||||
|
ctx.fillStyle = nodeStyle.fontColor
|
||||||
|
ctx.fillText(node.label, node.x, node.y + 30)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
} else if (node.type === nodeType.listNode) {
|
case nodeType.listNode: {
|
||||||
if (this.clickNode && this.clickNode.id === node.id) {
|
// 如果是鼠标点击或者悬停的,有一层圆环
|
||||||
|
if (node === this.clickNode || node === hoverNode) {
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(node.x, node.y, nodeStyle.shadowR, 0, 2 * Math.PI, false)
|
||||||
|
ctx.closePath()
|
||||||
|
if (node === this.currentSelectedNode) {
|
||||||
|
ctx.fillStyle = nodeStyle.selectedShadowColor
|
||||||
|
} else {
|
||||||
|
ctx.fillStyle = nodeStyle.hoveredShadowColor
|
||||||
|
}
|
||||||
|
ctx.fill()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内部填白
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
ctx.lineWidth = 1
|
ctx.arc(node.x, node.y, nodeStyle.innerR, 0, 2 * Math.PI, false)
|
||||||
ctx.strokeStyle = 'transparent'
|
ctx.closePath()
|
||||||
ctx.arc(node.x, node.y, nodeStyle.shadowR / 2, 0, Math.PI * 2)
|
ctx.fillStyle = nodeStyle.fillStyle
|
||||||
ctx.fillStyle = nodeStyle.selectedShadowColor
|
|
||||||
ctx.fill()
|
ctx.fill()
|
||||||
ctx.stroke()
|
|
||||||
} else if (hoverNode && hoverNode.id === node.id) {
|
// 第一层圆环
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
|
ctx.arc(node.x, node.y, nodeStyle.innerR, 0, 2 * Math.PI, false)
|
||||||
|
ctx.closePath()
|
||||||
ctx.lineWidth = 1
|
ctx.lineWidth = 1
|
||||||
ctx.strokeStyle = 'transparent'
|
ctx.strokeStyle = nodeStyle.borderColor
|
||||||
ctx.arc(node.x, node.y, nodeStyle.shadowR / 2, 0, Math.PI * 2)
|
|
||||||
ctx.fillStyle = nodeStyle.hoveredShadowColor
|
|
||||||
ctx.fill()
|
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
|
// 图片
|
||||||
|
ctx.drawImage(node.img, node.x - nodeStyle.iconWidth / 2, node.y - nodeStyle.iconHeight / 2, nodeStyle.iconWidth, nodeStyle.iconHeight)
|
||||||
|
// 文字
|
||||||
|
ctx.font = nodeStyle.font
|
||||||
|
const textWidth = ctx.measureText(node.label).width
|
||||||
|
const bckgDimensions = [textWidth, 8].map(n => n + 8 * 0.2)
|
||||||
|
ctx.fillStyle = nodeStyle.fontBgColor
|
||||||
|
ctx.fillRect(node.x - bckgDimensions[0] / 2, node.y - bckgDimensions[1] / 2 + 24, ...bckgDimensions) // 文字的白底
|
||||||
|
|
||||||
|
ctx.textAlign = 'center'
|
||||||
|
ctx.textBaseline = 'middle'
|
||||||
|
ctx.fillStyle = nodeStyle.fontColor
|
||||||
|
ctx.fillText(node.label, node.x, node.y + 24)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case nodeType.entityNode: {
|
||||||
|
// 先画个白底圆环,避免 link 穿过不好看
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(node.x, node.y, nodeStyle.innerR, 0, 2 * Math.PI, false)
|
||||||
|
ctx.closePath()
|
||||||
|
ctx.fillStyle = nodeStyle.fillStyle
|
||||||
|
ctx.fill()
|
||||||
|
// 如果是鼠标点击或者悬停的,有一层圆环
|
||||||
|
if (node === this.clickNode || node === hoverNode) {
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(node.x, node.y, nodeStyle.shadowR, 0, 2 * Math.PI, false)
|
||||||
|
ctx.closePath()
|
||||||
|
if (node === this.clickNode) {
|
||||||
|
ctx.fillStyle = nodeStyle.selectedShadowColor
|
||||||
|
} else {
|
||||||
|
ctx.fillStyle = nodeStyle.hoveredShadowColor
|
||||||
|
}
|
||||||
|
ctx.fill()
|
||||||
|
}
|
||||||
|
// 图片
|
||||||
|
ctx.drawImage(node.img, node.x - nodeStyle.iconWidth / 2, node.y - nodeStyle.iconHeight / 2, nodeStyle.iconWidth, nodeStyle.iconHeight)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case nodeType.tempNode: {
|
||||||
|
// 先画个白底圆环,避免 link 穿过不好看
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(node.x, node.y, nodeStyle.innerR, 0, 2 * Math.PI, false)
|
||||||
|
ctx.closePath()
|
||||||
|
ctx.fillStyle = nodeStyle.fillStyle
|
||||||
|
ctx.fill()
|
||||||
|
// 画透明度0.7的图标
|
||||||
|
ctx.globalAlpha = 0.7
|
||||||
|
ctx.drawImage(node.img, node.x - nodeStyle.iconWidth / 2, node.y - nodeStyle.iconHeight / 2, nodeStyle.iconWidth, nodeStyle.iconHeight)
|
||||||
|
ctx.globalAlpha = 1
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.beginPath()
|
|
||||||
ctx.lineWidth = 0.5
|
|
||||||
ctx.strokeStyle = nodeStyle.borderColor// 边的颜色
|
|
||||||
ctx.arc(node.x, node.y, nodeStyle.innerR / 2, 0, Math.PI * 2)
|
|
||||||
ctx.fillStyle = nodeStyle.fill// 中间的填充色
|
|
||||||
ctx.fill()
|
|
||||||
ctx.stroke()
|
|
||||||
|
|
||||||
ctx.drawImage(node.img, x, y, iconWidth, iconHeight)
|
|
||||||
|
|
||||||
if (node.type === nodeType.rootNode) {
|
|
||||||
ctx.font = nodeStyle.font
|
|
||||||
ctx.fillStyle = nodeStyle.fillStyle
|
|
||||||
ctx.textAlign = nodeStyle.textAlign
|
|
||||||
ctx.textBaseline = nodeStyle.textBaseline
|
|
||||||
ctx.fillText(node.label, node.x, node.y + nodeStyle.selectedShadowR / 2 + 5)
|
|
||||||
} else if (node.type === nodeType.listNode || node.type === nodeType.tempNode) {
|
|
||||||
ctx.beginPath()
|
|
||||||
ctx.lineWidth = 1
|
|
||||||
ctx.strokeStyle = '#FFFFFF'// 边的颜色
|
|
||||||
ctx.rect(node.x - 19, node.y + nodeStyle.innerR / 2 + 8 - 6, 38, 12)
|
|
||||||
ctx.fillStyle = '#FFFFFF'
|
|
||||||
ctx.fill()
|
|
||||||
ctx.stroke()
|
|
||||||
|
|
||||||
ctx.font = nodeStyle.font
|
|
||||||
ctx.fillStyle = nodeStyle.fillStyle
|
|
||||||
ctx.textAlign = nodeStyle.textAlign
|
|
||||||
ctx.textBaseline = nodeStyle.textBaseline
|
|
||||||
ctx.fillText(node.label, node.x, node.y + nodeStyle.innerR / 2 + 8)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.nodePointerAreaPaint((node, color, ctx) => { // 鼠标hover起作用的范围
|
|
||||||
const nodeStyle = this.getNodeStyle(node.type, node.data.entityType)
|
|
||||||
const size = nodeStyle.innerR
|
|
||||||
ctx.fillStyle = color
|
|
||||||
ctx.fillRect(node.x - size / 2, node.y - size / 2, size, size) // draw square as pointer trap
|
|
||||||
})
|
})
|
||||||
.linkCanvasObject((link, ctx) => {
|
.linkCanvasObject((link, ctx) => {
|
||||||
if (link.source.x !== undefined && link.source.y !== undefined && link.target.x !== undefined && link.target.y !== undefined) {
|
const start = link.source
|
||||||
|
const end = link.target
|
||||||
|
const width = 1 // 线宽
|
||||||
|
const arrowSize = 3 // 箭头大小
|
||||||
|
const shortenedLength = 20 // link 末端缩短长度
|
||||||
|
|
||||||
|
// 计算箭头角度
|
||||||
|
const dx = end.x - start.x
|
||||||
|
const dy = end.y - start.y
|
||||||
|
const angle = Math.atan2(dy, dx) // 计算与x轴的角度(弧度)
|
||||||
|
const lineEndX = end.x - shortenedLength * Math.cos(angle)
|
||||||
|
const lineEndY = end.y - shortenedLength * Math.sin(angle)
|
||||||
|
const arrowEndX = lineEndX + arrowSize * Math.cos(angle)
|
||||||
|
const arrowEndY = lineEndY + arrowSize * Math.sin(angle)
|
||||||
|
|
||||||
|
// 绘制线
|
||||||
|
let color
|
||||||
|
ctx.beginPath()
|
||||||
|
if (link.type === linkType.temp) {
|
||||||
|
ctx.setLineDash([2, 2])
|
||||||
|
color = 'rgba(119,131,145,0.2)' // 虚线颜色
|
||||||
|
} else {
|
||||||
|
ctx.setLineDash([])
|
||||||
|
if (this.clickNode === link.source || this.clickNode === link.target) {
|
||||||
|
color = 'rgba(119,131,145,0.8)' // 高亮线颜色
|
||||||
|
} else {
|
||||||
|
color = 'rgba(119,131,145,0.3)' // 普通线颜色
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.moveTo(start.x, start.y)
|
||||||
|
ctx.lineTo(lineEndX, lineEndY)
|
||||||
|
ctx.strokeStyle = color
|
||||||
|
ctx.lineWidth = width
|
||||||
|
ctx.stroke()
|
||||||
|
|
||||||
|
// 绘制箭头
|
||||||
|
ctx.save() // 保存当前状态以便之后恢复
|
||||||
|
ctx.translate(arrowEndX, arrowEndY) // 将坐标原点移动到箭头末端
|
||||||
|
ctx.rotate(angle) // 根据链接方向旋转坐标系
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(0, 0)
|
||||||
|
ctx.lineTo(-arrowSize, arrowSize) // 绘制箭头的一边
|
||||||
|
ctx.lineTo(-arrowSize, -arrowSize) // 绘制箭头的另一边
|
||||||
|
ctx.closePath()
|
||||||
|
ctx.fillStyle = color
|
||||||
|
ctx.fill()
|
||||||
|
ctx.restore() // 恢复之前保存的状态
|
||||||
|
/*if (link.source.x !== undefined && link.source.y !== undefined && link.target.x !== undefined && link.target.y !== undefined) {
|
||||||
const nodeStyle = this.getNodeStyle(link.target.type, link.target.data.entityType)
|
const nodeStyle = this.getNodeStyle(link.target.type, link.target.data.entityType)
|
||||||
|
|
||||||
ctx.lineWidth = 0.5
|
ctx.lineWidth = 0.5
|
||||||
@@ -213,7 +294,7 @@ export default {
|
|||||||
ctx.fill()
|
ctx.fill()
|
||||||
ctx.closePath()
|
ctx.closePath()
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
}
|
}*/
|
||||||
})
|
})
|
||||||
.autoPauseRedraw(false) // keep redrawing after engine has stopped如果您有依赖于画布的不断重绘的自定义动态对象,建议关闭此选项。
|
.autoPauseRedraw(false) // keep redrawing after engine has stopped如果您有依赖于画布的不断重绘的自定义动态对象,建议关闭此选项。
|
||||||
.onNodeHover(node => {
|
.onNodeHover(node => {
|
||||||
@@ -223,6 +304,7 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.centerAt(0, 30)// 设置中心节点位置
|
.centerAt(0, 30)// 设置中心节点位置
|
||||||
|
.zoom(1)
|
||||||
.onNodeClick(async (node, e) => {
|
.onNodeClick(async (node, e) => {
|
||||||
this.clickNode = node || null
|
this.clickNode = node || null
|
||||||
if (node.type !== 'tempNode') {
|
if (node.type !== 'tempNode') {
|
||||||
@@ -256,7 +338,7 @@ export default {
|
|||||||
this.getIconUrl(k, false, false)
|
this.getIconUrl(k, false, false)
|
||||||
)
|
)
|
||||||
|
|
||||||
const tempLink = new Link(node, tempNode, 'temp', this.defaultLinkDistance, 3)
|
const tempLink = new Link(node, tempNode, linkType.temp)
|
||||||
toAddNodes.push(tempNode)
|
toAddNodes.push(tempNode)
|
||||||
toAddLinks.push(tempLink)
|
toAddLinks.push(tempLink)
|
||||||
}
|
}
|
||||||
@@ -265,7 +347,7 @@ export default {
|
|||||||
if (toAddNodes.length || toAddLinks.length) {
|
if (toAddNodes.length || toAddLinks.length) {
|
||||||
this.addItems(toAddNodes, toAddLinks)
|
this.addItems(toAddNodes, toAddLinks)
|
||||||
}
|
}
|
||||||
this.rightBox.node = _.cloneDeep(node)
|
this.rightBox.node = node
|
||||||
this.rightBox.mode = 'detail'
|
this.rightBox.mode = 'detail'
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
@@ -274,17 +356,17 @@ export default {
|
|||||||
this.rightBox.loading = false
|
this.rightBox.loading = false
|
||||||
}
|
}
|
||||||
} else if (node.type === nodeType.listNode) {
|
} else if (node.type === nodeType.listNode) {
|
||||||
this.rightBox.node = _.cloneDeep(node)
|
this.rightBox.node = node
|
||||||
this.rightBox.mode = 'list'
|
this.rightBox.mode = 'list'
|
||||||
} else if (node.type === nodeType.rootNode) {
|
} else if (node.type === nodeType.rootNode) {
|
||||||
this.rightBox.node = _.cloneDeep(node)
|
this.rightBox.node = node
|
||||||
this.rightBox.mode = 'detail'
|
this.rightBox.mode = 'detail'
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 点击tempNode,根据source生成listNode和entityNode以及对应的edge。查完entityNode的接口再删除临时node和edge。
|
// 点击tempNode,根据source生成listNode和entityNode以及对应的edge。查完entityNode的接口再删除临时node和edge。
|
||||||
// 若已达第六层,则只生成listNode,不再展开entityNode
|
// 若已达第六层,则只生成listNode,不再展开entityNode
|
||||||
const nodes = []
|
const nodes = []
|
||||||
const edges = []
|
const links = []
|
||||||
const sourceNode = node.getSourceNode(this.graph.graphData())
|
const sourceNode = node.getSourceNode(this.graph.graphData())
|
||||||
const listNode = new Node(
|
const listNode = new Node(
|
||||||
nodeType.listNode,
|
nodeType.listNode,
|
||||||
@@ -299,12 +381,12 @@ export default {
|
|||||||
this.getIconUrl(node.data.entityType, false, false)
|
this.getIconUrl(node.data.entityType, false, false)
|
||||||
)
|
)
|
||||||
nodes.push(listNode)
|
nodes.push(listNode)
|
||||||
edges.push(new Link(sourceNode, listNode, null, this.defaultLinkDistance, 2))
|
links.push(new Link(sourceNode, listNode, null))
|
||||||
|
|
||||||
// 判断listNode的sourceNode层级,若大于等于10(即第6层listNode),则不继续拓展entity node,并给用户提示。否则拓展entity node
|
// 判断listNode的sourceNode层级,若大于等于10(即第6层listNode),则不继续拓展entity node,并给用户提示。否则拓展entity node
|
||||||
const level = this.getNodeLevel(listNode.sourceNode.id)
|
const level = this.getNodeLevel(listNode.sourceNode.id)
|
||||||
if (level < 10) {
|
if (level < 10) {
|
||||||
// this.rightBox.loading = true
|
this.rightBox.loading = true
|
||||||
try {
|
try {
|
||||||
const entities = await sourceNode.queryRelatedEntities(listNode.data.entityType)
|
const entities = await sourceNode.queryRelatedEntities(listNode.data.entityType)
|
||||||
sourceNode.data.relatedEntities[listNode.data.entityType].list.push(...entities.list)
|
sourceNode.data.relatedEntities[listNode.data.entityType].list.push(...entities.list)
|
||||||
@@ -314,9 +396,9 @@ export default {
|
|||||||
entityName: entity.vertex,
|
entityName: entity.vertex,
|
||||||
x: e.x + Math.random() * 100 - 50,
|
x: e.x + Math.random() * 100 - 50,
|
||||||
y: e.y + Math.random() * 100 - 50
|
y: e.y + Math.random() * 100 - 50
|
||||||
}, listNode, this.defaultChargeStrength, this.getIconUrl(listNode.data.entityType, true, false))
|
}, listNode, this.defaultChargeStrength, this.getIconUrl(listNode.data.entityType, false, false))
|
||||||
nodes.push(entityNode)
|
nodes.push(entityNode)
|
||||||
edges.push(new Link(listNode, entityNode, null, this.defaultLinkDistance, 2))
|
links.push(new Link(listNode, entityNode, null))
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
@@ -327,7 +409,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.$message.warning(this.$t('tip.maxExpandDepth'))
|
this.$message.warning(this.$t('tip.maxExpandDepth'))
|
||||||
}
|
}
|
||||||
this.addItems(nodes, edges)
|
this.addItems(nodes, links)
|
||||||
this.cleanTempItems()
|
this.cleanTempItems()
|
||||||
// this.graph.layout()
|
// this.graph.layout()
|
||||||
|
|
||||||
@@ -361,7 +443,10 @@ export default {
|
|||||||
|
|
||||||
.d3Force('link', d3.forceLink().id(link => link.id)
|
.d3Force('link', d3.forceLink().id(link => link.id)
|
||||||
.distance(link => {
|
.distance(link => {
|
||||||
return link.distance
|
if (link.source.type === nodeType.rootNode) {
|
||||||
|
return 160
|
||||||
|
}
|
||||||
|
return 80
|
||||||
})
|
})
|
||||||
.strength(link => {
|
.strength(link => {
|
||||||
return link.strength
|
return link.strength
|
||||||
@@ -541,27 +626,26 @@ export default {
|
|||||||
return this.getEntityNodeStyle(entityType)
|
return this.getEntityNodeStyle(entityType)
|
||||||
}
|
}
|
||||||
case nodeType.tempNode: {
|
case nodeType.tempNode: {
|
||||||
return this.getTempNodeStyle(entityType)
|
return this.getEntityNodeStyle(entityType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getRootNodeStyle (entityType) {
|
getRootNodeStyle (entityType) {
|
||||||
const nodeStyle = {
|
const nodeStyle = {
|
||||||
innerR: 26,
|
innerR: 19,
|
||||||
fill: '#FFFFFF',
|
fillStyle: '#FFFFFF',
|
||||||
shadowR: 31.5,
|
shadowR: 25,
|
||||||
selectedShadowR: 38.5,
|
selectedShadowR: 36,
|
||||||
font: '8px NotoSansSChineseRegular',
|
font: '9px NotoSansSChineseRegular',
|
||||||
textAlign: 'center',
|
fontColor: '#353636',
|
||||||
textBaseline: 'middle',
|
fontBgColor: 'rgba(255,255,255,0.8)'
|
||||||
fillStyle: '#353636'
|
|
||||||
}
|
}
|
||||||
switch (entityType) {
|
switch (entityType) {
|
||||||
case 'ip': {
|
case 'ip': {
|
||||||
return {
|
return {
|
||||||
...nodeStyle,
|
...nodeStyle,
|
||||||
iconWidth: 26,
|
iconWidth: 24,
|
||||||
iconHeight: 23,
|
iconHeight: 21,
|
||||||
borderColor: 'rgba(126,159,84,1)',
|
borderColor: 'rgba(126,159,84,1)',
|
||||||
shadowColor: 'rgba(126,159,84,0.21)',
|
shadowColor: 'rgba(126,159,84,0.21)',
|
||||||
hoveredShadowColor: 'rgba(126,159,84,0.36)',
|
hoveredShadowColor: 'rgba(126,159,84,0.36)',
|
||||||
@@ -571,7 +655,7 @@ export default {
|
|||||||
case 'domain': {
|
case 'domain': {
|
||||||
return {
|
return {
|
||||||
...nodeStyle,
|
...nodeStyle,
|
||||||
iconWidth: 28,
|
iconWidth: 24,
|
||||||
iconHeight: 24,
|
iconHeight: 24,
|
||||||
borderColor: 'rgba(56,172,210,1)',
|
borderColor: 'rgba(56,172,210,1)',
|
||||||
shadowColor: 'rgba(56,172,210,0.21)',
|
shadowColor: 'rgba(56,172,210,0.21)',
|
||||||
@@ -582,8 +666,8 @@ export default {
|
|||||||
case 'app': {
|
case 'app': {
|
||||||
return {
|
return {
|
||||||
...nodeStyle,
|
...nodeStyle,
|
||||||
iconWidth: 24,
|
iconWidth: 21,
|
||||||
iconHeight: 26,
|
iconHeight: 24,
|
||||||
borderColor: 'rgba(229,162,25,1)',
|
borderColor: 'rgba(229,162,25,1)',
|
||||||
shadowColor: 'rgba(229,162,25,0.21)',
|
shadowColor: 'rgba(229,162,25,0.21)',
|
||||||
hoveredShadowColor: 'rgba(229,162,25,0.36)',
|
hoveredShadowColor: 'rgba(229,162,25,0.36)',
|
||||||
@@ -593,8 +677,8 @@ export default {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...nodeStyle,
|
...nodeStyle,
|
||||||
iconWidth: 26,
|
iconWidth: 24,
|
||||||
iconHeight: 23,
|
iconHeight: 21,
|
||||||
borderColor: 'rgba(126,159,84,1)',
|
borderColor: 'rgba(126,159,84,1)',
|
||||||
shadowColor: 'rgba(126,159,84,0.21)',
|
shadowColor: 'rgba(126,159,84,0.21)',
|
||||||
hoveredShadowColor: 'rgba(126,159,84,0.36)',
|
hoveredShadowColor: 'rgba(126,159,84,0.36)',
|
||||||
@@ -602,153 +686,68 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
getListNodeStyle (entityType) {
|
getListNodeStyle (entityType) {
|
||||||
const nodeStyle = {
|
let iconWidth = 20
|
||||||
innerR: 21,
|
let iconHeight = 18
|
||||||
shadowR: 26.5,
|
|
||||||
fill: '#FFFFFF',
|
|
||||||
font: '8px NotoSansSChineseRegular',
|
|
||||||
textAlign: 'center',
|
|
||||||
textBaseline: 'middle',
|
|
||||||
fillStyle: '#353636'
|
|
||||||
}
|
|
||||||
switch (entityType) {
|
switch (entityType) {
|
||||||
case 'ip': {
|
case 'ip': {
|
||||||
return {
|
iconWidth = 20
|
||||||
...nodeStyle,
|
iconHeight = 18
|
||||||
iconWidth: 24,
|
break
|
||||||
iconHeight: 21,
|
|
||||||
borderColor: 'rgba(119,131,145,0.6)',
|
|
||||||
selectedBorderColor: 'rgba(126,159,84,1)',
|
|
||||||
hoveredShadowColor: 'rgba(151,151,151,0.21)',
|
|
||||||
selectedShadowColor: 'rgba(126,159,84,0.21)'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case 'domain': {
|
case 'domain': {
|
||||||
return {
|
iconWidth = 20
|
||||||
...nodeStyle,
|
iconHeight = 20
|
||||||
iconWidth: 24,
|
break
|
||||||
iconHeight: 24,
|
|
||||||
borderColor: 'rgba(119,131,145,0.6)',
|
|
||||||
selectedBorderColor: 'rgba(56,172,210,1)',
|
|
||||||
hoveredShadowColor: 'rgba(151,151,151,0.21)',
|
|
||||||
selectedShadowColor: 'rgba(56,172,210,0.21)'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case 'app': {
|
case 'app': {
|
||||||
return {
|
iconWidth = 18
|
||||||
...nodeStyle,
|
iconHeight = 20
|
||||||
iconWidth: 22,
|
break
|
||||||
iconHeight: 24,
|
|
||||||
borderColor: 'rgba(119,131,145,0.6)',
|
|
||||||
selectedBorderColor: 'rgba(229,162,25,1)',
|
|
||||||
hoveredShadowColor: 'rgba(151,151,151,0.21)',
|
|
||||||
selectedShadowColor: 'rgba(229,162,25,0.21)'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...nodeStyle,
|
innerR: 16,
|
||||||
iconWidth: 24,
|
shadowR: 22,
|
||||||
iconHeight: 21,
|
fillStyle: '#FFFFFF',
|
||||||
borderColor: 'rgba(119,131,145,0.6)',
|
font: '9px NotoSansSChineseRegular',
|
||||||
selectedBorderColor: 'rgba(126,159,84,1)',
|
fontColor: '#353636',
|
||||||
|
fontBgColor: 'rgba(255,255,255,0.8)',
|
||||||
|
iconWidth,
|
||||||
|
iconHeight,
|
||||||
|
borderColor: 'rgba(119,131,145,0.5)',
|
||||||
|
selectedBorderColor: 'rgba(119,131,145,0.8)',
|
||||||
hoveredShadowColor: 'rgba(151,151,151,0.21)',
|
hoveredShadowColor: 'rgba(151,151,151,0.21)',
|
||||||
selectedShadowColor: 'rgba(126,159,84,0.21)'
|
selectedShadowColor: 'rgba(151,151,151,0.4)'
|
||||||
}
|
|
||||||
},
|
|
||||||
getTempNodeStyle (entityType) {
|
|
||||||
const nodeStyle = {
|
|
||||||
innerR: 14,
|
|
||||||
fill: 'transparent',
|
|
||||||
font: '8px NotoSansSChineseRegular',
|
|
||||||
textAlign: 'center',
|
|
||||||
textBaseline: 'middle',
|
|
||||||
fillStyle: '#353636'
|
|
||||||
}
|
|
||||||
switch (entityType) {
|
|
||||||
case 'ip': {
|
|
||||||
return {
|
|
||||||
...nodeStyle,
|
|
||||||
iconWidth: 24,
|
|
||||||
iconHeight: 21,
|
|
||||||
borderColor: '#FFFFFF',
|
|
||||||
selectedBorderColor: 'rgba(126,159,84,1)',
|
|
||||||
hoveredShadowColor: 'rgba(151,151,151,0.21)',
|
|
||||||
selectedShadowColor: 'rgba(126,159,84,0.21)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 'domain': {
|
|
||||||
return {
|
|
||||||
...nodeStyle,
|
|
||||||
iconWidth: 24,
|
|
||||||
iconHeight: 24,
|
|
||||||
borderColor: '#FFFFFF',
|
|
||||||
selectedBorderColor: 'rgba(56,172,210,1)',
|
|
||||||
hoveredShadowColor: 'rgba(151,151,151,0.21)',
|
|
||||||
selectedShadowColor: 'rgba(56,172,210,0.21)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 'app': {
|
|
||||||
return {
|
|
||||||
...nodeStyle,
|
|
||||||
iconWidth: 22,
|
|
||||||
iconHeight: 24,
|
|
||||||
borderColor: '#FFFFFF',
|
|
||||||
selectedBorderColor: 'rgba(229,162,25,1)',
|
|
||||||
hoveredShadowColor: 'rgba(151,151,151,0.21)',
|
|
||||||
selectedShadowColor: 'rgba(229,162,25,0.21)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...nodeStyle,
|
|
||||||
iconWidth: 24,
|
|
||||||
iconHeight: 21,
|
|
||||||
borderColor: '#FFFFFF',
|
|
||||||
selectedBorderColor: 'rgba(126,159,84,1)',
|
|
||||||
hoveredShadowColor: 'rgba(151,151,151,0.21)',
|
|
||||||
selectedShadowColor: 'rgba(126,159,84,0.21)'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getEntityNodeStyle (entityType) {
|
getEntityNodeStyle (entityType) {
|
||||||
const nodeStyle = {
|
let iconWidth = 20
|
||||||
innerR: 12,
|
let iconHeight = 18
|
||||||
fill: 'transparent'
|
|
||||||
}
|
|
||||||
switch (entityType) {
|
switch (entityType) {
|
||||||
case 'ip': {
|
case 'ip': {
|
||||||
return {
|
iconWidth = 20
|
||||||
...nodeStyle,
|
iconHeight = 18
|
||||||
iconWidth: 22,
|
break
|
||||||
iconHeight: 20,
|
|
||||||
selectedShadowColor: 'rgba(126,159,84,0.1)'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case 'domain': {
|
case 'domain': {
|
||||||
return {
|
iconWidth = 20
|
||||||
...nodeStyle,
|
iconHeight = 20
|
||||||
iconWidth: 22,
|
break
|
||||||
iconHeight: 22,
|
|
||||||
selectedShadowColor: 'rgba(56,172,210,0.1)'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case 'app': {
|
case 'app': {
|
||||||
return {
|
iconWidth = 18
|
||||||
...nodeStyle,
|
iconHeight = 20
|
||||||
iconWidth: 21,
|
break
|
||||||
iconHeight: 24,
|
|
||||||
selectedShadowColor: 'rgba(229,162,25,0.1)'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...nodeStyle,
|
shadowR: 15,
|
||||||
iconWidth: 22,
|
innerR: 10,
|
||||||
iconHeight: 20,
|
fillStyle: '#FFFFFF',
|
||||||
borderColor: 'rgba(119,131,145,1)',
|
iconWidth,
|
||||||
selectedBorderColor: 'rgba(126,159,84,1)',
|
iconHeight,
|
||||||
hoveredShadowColor: 'rgba(151,151,151,0.21)',
|
hoveredShadowColor: 'rgba(151,151,151,0.12)',
|
||||||
selectedShadowColor: 'rgba(126,159,84,0.1)'
|
selectedShadowColor: 'rgba(151,151,151,0.24)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -822,7 +821,7 @@ export default {
|
|||||||
l.source = l.source.id
|
l.source = l.source.id
|
||||||
l.target = l.target.id
|
l.target = l.target.id
|
||||||
})
|
})
|
||||||
const info = findShortestPath(g6FormatData, this.entity.entityName, id)
|
const info = findShortestPath(g6FormatData, this.entity.entityName + nodeType.rootNode, id)
|
||||||
return info.length
|
return info.length
|
||||||
},
|
},
|
||||||
generateTempNodeCoordinate (sourceNode, event) {
|
generateTempNodeCoordinate (sourceNode, event) {
|
||||||
@@ -847,7 +846,7 @@ export default {
|
|||||||
cleanTempItems () {
|
cleanTempItems () {
|
||||||
const { nodes, links } = this.graph.graphData()
|
const { nodes, links } = this.graph.graphData()
|
||||||
const newNodes = nodes.filter(n => n.type !== nodeType.tempNode)
|
const newNodes = nodes.filter(n => n.type !== nodeType.tempNode)
|
||||||
const newLinks = links.filter(l => l.level !== 3)
|
const newLinks = links.filter(l => l.type !== linkType.temp)
|
||||||
if (newNodes.length !== nodes.length || newLinks.length !== links.length) {
|
if (newNodes.length !== nodes.length || newLinks.length !== links.length) {
|
||||||
this.graph.graphData({ nodes: newNodes, links: newLinks })
|
this.graph.graphData({ nodes: newNodes, links: newLinks })
|
||||||
}
|
}
|
||||||
@@ -895,7 +894,7 @@ export default {
|
|||||||
this.getIconUrl(k, false, false)
|
this.getIconUrl(k, false, false)
|
||||||
)
|
)
|
||||||
listNodes.push(listNode)
|
listNodes.push(listNode)
|
||||||
links.push(new Link(rootNode, listNode, null, 60, 1))
|
links.push(new Link(rootNode, listNode, null))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// entityNode
|
// entityNode
|
||||||
@@ -913,10 +912,10 @@ export default {
|
|||||||
},
|
},
|
||||||
listNode,
|
listNode,
|
||||||
this.defaultChargeStrength,
|
this.defaultChargeStrength,
|
||||||
this.getIconUrl(listNode.data.entityType, true, false)
|
this.getIconUrl(listNode.data.entityType, false, false)
|
||||||
)
|
)
|
||||||
entityNodes.push(entityNode)
|
entityNodes.push(entityNode)
|
||||||
links.push(new Link(listNode, entityNode, null, this.defaultLinkDistance, 2))
|
links.push(new Link(listNode, entityNode, null))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
nodes.push(...listNodes, ...entityNodes)
|
nodes.push(...listNodes, ...entityNodes)
|
||||||
@@ -946,14 +945,14 @@ export default {
|
|||||||
const toAddNode = new Node(nodeType.entityNode, entity.vertex, {
|
const toAddNode = new Node(nodeType.entityNode, entity.vertex, {
|
||||||
entityType: expandType,
|
entityType: expandType,
|
||||||
entityName: entity.vertex
|
entityName: entity.vertex
|
||||||
}, node, this.defaultChargeStrength, this.getIconUrl(node.data.entityType, true, false))
|
}, node, this.defaultChargeStrength, this.getIconUrl(node.data.entityType, false, false))
|
||||||
toAddNodes.push(toAddNode)
|
toAddNodes.push(toAddNode)
|
||||||
|
|
||||||
const toAddLink = new Link(node, toAddNode, null, this.defaultLinkDistance)
|
const toAddLink = new Link(node, toAddNode, null)
|
||||||
toAddLinks.push(toAddLink)
|
toAddLinks.push(toAddLink)
|
||||||
})
|
})
|
||||||
this.addItems(toAddNodes, toAddLinks)
|
this.addItems(toAddNodes, toAddLinks)
|
||||||
this.rightBox.node = _.cloneDeep(node)
|
this.rightBox.node = node
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
this.$message.error(this.errorMsgHandler(e))
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
@@ -986,7 +985,7 @@ export default {
|
|||||||
let listNode = neighbors.targetNodes.find(n => n.data.entityType === expandType)
|
let listNode = neighbors.targetNodes.find(n => n.data.entityType === expandType)
|
||||||
if (!listNode) {
|
if (!listNode) {
|
||||||
listNode = new Node(nodeType.listNode, `${node.id}__${expandType}-list`, { entityType: expandType }, node, this.defaultChargeStrength, this.getIconUrl(expandType, false, false))
|
listNode = new Node(nodeType.listNode, `${node.id}__${expandType}-list`, { entityType: expandType }, node, this.defaultChargeStrength, this.getIconUrl(expandType, false, false))
|
||||||
const link = new Link(node, listNode, null, this.defaultLinkDistance)
|
const link = new Link(node, listNode, null)
|
||||||
toAddNodes.push(listNode)
|
toAddNodes.push(listNode)
|
||||||
toAddLinks.push(link)
|
toAddLinks.push(link)
|
||||||
}
|
}
|
||||||
@@ -994,9 +993,9 @@ export default {
|
|||||||
const entityNode = new Node(nodeType.entityNode, entity.vertex, {
|
const entityNode = new Node(nodeType.entityNode, entity.vertex, {
|
||||||
entityType: expandType,
|
entityType: expandType,
|
||||||
entityName: entity.vertex
|
entityName: entity.vertex
|
||||||
}, listNode, this.defaultChargeStrength, this.getIconUrl(expandType, true, false))
|
}, listNode, this.defaultChargeStrength, this.getIconUrl(expandType, false, false))
|
||||||
toAddNodes.push(entityNode)
|
toAddNodes.push(entityNode)
|
||||||
toAddLinks.push(new Link(listNode, entityNode, null, this.defaultLinkDistance))
|
toAddLinks.push(new Link(listNode, entityNode, null))
|
||||||
})
|
})
|
||||||
this.addItems(toAddNodes, toAddLinks)
|
this.addItems(toAddNodes, toAddLinks)
|
||||||
this.rightBox.node = _.cloneDeep(node)
|
this.rightBox.node = _.cloneDeep(node)
|
||||||
@@ -1053,10 +1052,12 @@ export default {
|
|||||||
node: null,
|
node: null,
|
||||||
loading: true
|
loading: true
|
||||||
})
|
})
|
||||||
|
const clickNode = shallowRef(null)
|
||||||
return {
|
return {
|
||||||
entity,
|
entity,
|
||||||
rightBox,
|
rightBox,
|
||||||
graph
|
graph,
|
||||||
|
clickNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ export default {
|
|||||||
node: {
|
node: {
|
||||||
deep: true,
|
deep: true,
|
||||||
handler (n) {
|
handler (n) {
|
||||||
|
console.info(n)
|
||||||
this.handleDetailData(n)
|
this.handleDetailData(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,6 +270,8 @@ export default {
|
|||||||
return location || '-'
|
return location || '-'
|
||||||
},
|
},
|
||||||
handleDetailData (node) {
|
handleDetailData (node) {
|
||||||
|
console.info(node)
|
||||||
|
console.info(_.get(node, 'data.relatedEntities.ip.list', []))
|
||||||
const n = node
|
const n = node
|
||||||
const type = _.get(n, 'data.entityType', '')
|
const type = _.get(n, 'data.entityType', '')
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -432,6 +435,7 @@ export default {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.info(this.relationList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
|
import { nodeType } from './node'
|
||||||
|
|
||||||
export default class Link {
|
export default class Link {
|
||||||
constructor (sourceNode, targetNode, type = linkType.normal, distance, level = 1) {
|
constructor (sourceNode, targetNode, type) {
|
||||||
this.source = sourceNode.id
|
this.source = sourceNode.id
|
||||||
this.target = targetNode.id
|
this.target = targetNode.id
|
||||||
this.type = type
|
this.type = type || linkType.normal
|
||||||
this.distance = distance || 20// 连接中心节点的线的distance为60,其他节点为20
|
this.strength = strengthHandler(sourceNode, targetNode)
|
||||||
this.strength = level === 1 ? 0.5 : (level === 2 ? 1 : 1)// level2:设置为0.5-1
|
}
|
||||||
this.color = '#c8c8cc'// 未点击线所连接的节点时线的颜色
|
}
|
||||||
this.clickColor = '#7b7b99'// 点击此线所连接的节点后,线的颜色
|
|
||||||
// this.width = 1//未点击线所连接的节点时线的宽度
|
function strengthHandler (sourceNode, targetNode) {
|
||||||
// this.arrowColor = '#c8c8cc'
|
if (sourceNode.type === nodeType.rootNode) {
|
||||||
// this.clickArrowColor = '#7b7b99'
|
return 0.5
|
||||||
// this.clickWidth = 1//点击节点后,此节点所连接的线的宽度
|
} else {
|
||||||
this.level = level// 1:source为中心节点的线,是直线; 2:source为listNode节点的线,是直线; 3:target为临时节点的线,是虚线
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ export default class Node {
|
|||||||
this.type = type
|
this.type = type
|
||||||
this.vx = 0
|
this.vx = 0
|
||||||
this.vy = 0
|
this.vy = 0
|
||||||
|
this.x = null
|
||||||
|
this.y = null
|
||||||
this.fx = sourceNode ? null : 0// 设置为0,即可固定中心节点。0为中心节点,1为中心节点的子节点,2为第三级节点
|
this.fx = sourceNode ? null : 0// 设置为0,即可固定中心节点。0为中心节点,1为中心节点的子节点,2为第三级节点
|
||||||
this.fy = sourceNode ? null : 0// 设置为0,即可固定中心节点。0为中心节点,1为中心节点的子节点,2为第三级节点
|
this.fy = sourceNode ? null : 0// 设置为0,即可固定中心节点。0为中心节点,1为中心节点的子节点,2为第三级节点
|
||||||
this.preDragX = null
|
this.preDragX = null
|
||||||
@@ -30,6 +32,20 @@ export default class Node {
|
|||||||
}
|
}
|
||||||
this.label = generateLabel(type, id, data, sourceNode)
|
this.label = generateLabel(type, id, data, sourceNode)
|
||||||
this.name = builtTooltip(this)
|
this.name = builtTooltip(this)
|
||||||
|
|
||||||
|
// val 值决定鼠标触发 hover 的半径
|
||||||
|
switch (type) {
|
||||||
|
case nodeType.rootNode:
|
||||||
|
this.val = 19
|
||||||
|
break
|
||||||
|
case nodeType.listNode:
|
||||||
|
this.val = 16
|
||||||
|
break
|
||||||
|
case nodeType.entityNode:
|
||||||
|
case nodeType.tempNode:
|
||||||
|
this.val = 10
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// listNode和entityNode专用,查询实体信息
|
// listNode和entityNode专用,查询实体信息
|
||||||
@@ -99,7 +115,6 @@ export default class Node {
|
|||||||
if (this.data.entityType === entityType.domain && targetEntityType === entityType.domain) {
|
if (this.data.entityType === entityType.domain && targetEntityType === entityType.domain) {
|
||||||
_targetEntityType = 'subdomain'
|
_targetEntityType = 'subdomain'
|
||||||
}
|
}
|
||||||
console.info(this.data, targetEntityType)
|
|
||||||
const url = `${api.entity.entityGraph[`${this.data.entityType}Related${_.upperFirst(_targetEntityType)}`]}?resource=${this.data.entityName}&pageSize=10&pageNo=${this.data.relatedEntities[targetEntityType].pageNo + 1}`
|
const url = `${api.entity.entityGraph[`${this.data.entityType}Related${_.upperFirst(_targetEntityType)}`]}?resource=${this.data.entityName}&pageSize=10&pageNo=${this.data.relatedEntities[targetEntityType].pageNo + 1}`
|
||||||
const response = await axios.get(url).catch(e => {
|
const response = await axios.get(url).catch(e => {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
|||||||
Reference in New Issue
Block a user