CN-1087 feat: 完成剩余工作,包括工具栏
This commit is contained in:
@@ -18,6 +18,13 @@
|
|||||||
color: #575757;
|
color: #575757;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.toolbar--unactivated {
|
||||||
|
cursor: default;
|
||||||
|
i {
|
||||||
|
opacity: .4;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "cn-icon"; /* Project id 2614877 */
|
font-family: "cn-icon"; /* Project id 2614877 */
|
||||||
src: url('iconfont.woff2?t=1689317280458') format('woff2'),
|
src: url('iconfont.woff2?t=1690879635451') format('woff2'),
|
||||||
url('iconfont.woff?t=1689317280458') format('woff'),
|
url('iconfont.woff?t=1690879635451') format('woff'),
|
||||||
url('iconfont.ttf?t=1689317280458') format('truetype');
|
url('iconfont.ttf?t=1690879635451') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.cn-icon {
|
.cn-icon {
|
||||||
@@ -13,6 +13,30 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cn-icon-next-step:before {
|
||||||
|
content: "\e7fd";
|
||||||
|
}
|
||||||
|
|
||||||
|
.cn-icon-zoom-out:before {
|
||||||
|
content: "\e808";
|
||||||
|
}
|
||||||
|
|
||||||
|
.cn-icon-reset:before {
|
||||||
|
content: "\e809";
|
||||||
|
}
|
||||||
|
|
||||||
|
.cn-icon-to-default:before {
|
||||||
|
content: "\e805";
|
||||||
|
}
|
||||||
|
|
||||||
|
.cn-icon-pre-step:before {
|
||||||
|
content: "\e806";
|
||||||
|
}
|
||||||
|
|
||||||
|
.cn-icon-zoom-in:before {
|
||||||
|
content: "\e807";
|
||||||
|
}
|
||||||
|
|
||||||
.cn-icon-add-knowledge-base:before {
|
.cn-icon-add-knowledge-base:before {
|
||||||
content: "\e802";
|
content: "\e802";
|
||||||
}
|
}
|
||||||
@@ -21,30 +45,6 @@
|
|||||||
content: "\e803";
|
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 {
|
.cn-icon-expand-continue:before {
|
||||||
content: "\e7fc";
|
content: "\e7fc";
|
||||||
}
|
}
|
||||||
@@ -321,7 +321,7 @@
|
|||||||
content: "\e7ab";
|
content: "\e7ab";
|
||||||
}
|
}
|
||||||
|
|
||||||
.cn-icon-serach:before {
|
.cn-icon-search:before {
|
||||||
content: "\e7ac";
|
content: "\e7ac";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -627,7 +627,7 @@ export default {
|
|||||||
if (e.response.data && e.response.data.message) {
|
if (e.response.data && e.response.data.message) {
|
||||||
this.$message.error(e.response.data.message)
|
this.$message.error(e.response.data.message)
|
||||||
} else {
|
} else {
|
||||||
this.$message.error('Something went wrong...')
|
this.$message.error(this.$t('tip.somethingWentWrong'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export default {
|
|||||||
if (response.message) {
|
if (response.message) {
|
||||||
this.$message.error(response.message)
|
this.$message.error(response.message)
|
||||||
} else {
|
} else {
|
||||||
this.$message.error('Something went wrong...')
|
this.$message.error(this.$t('tip.somethingWentWrong'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ export default {
|
|||||||
if (response.message) {
|
if (response.message) {
|
||||||
this.$message.error(response.message)
|
this.$message.error(response.message)
|
||||||
} else {
|
} else {
|
||||||
this.$message.error('Something went wrong...')
|
this.$message.error(this.$t('tip.somethingWentWrong'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$emit('reload')
|
this.$emit('reload')
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ export default {
|
|||||||
if (e.response && e.response.message) {
|
if (e.response && e.response.message) {
|
||||||
this.$message.error(e.response.message)
|
this.$message.error(e.response.message)
|
||||||
} else {
|
} else {
|
||||||
this.$message.error('Something went wrong...')
|
this.$message.error(this.$t('tip.somethingWentWrong'))
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.blockOperation.save = false
|
this.blockOperation.save = false
|
||||||
|
|||||||
@@ -126,16 +126,12 @@ export default {
|
|||||||
if (response.message) {
|
if (response.message) {
|
||||||
this.$message.error(response.message)
|
this.$message.error(response.message)
|
||||||
} else {
|
} else {
|
||||||
this.$message.error('Something went wrong...')
|
this.$message.error(this.$t('tip.somethingWentWrong'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.toggleLoading(false)
|
this.toggleLoading(false)
|
||||||
if (!this.tableData || this.tableData.length === 0) {
|
this.isNoData = !this.tableData || this.tableData.length === 0
|
||||||
this.isNoData = true
|
|
||||||
} else {
|
|
||||||
this.isNoData = false
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
debounceFunc: null,
|
||||||
chartOption: {
|
chartOption: {
|
||||||
container: 'entityGraph',
|
container: 'entityGraph',
|
||||||
layout: {
|
layout: {
|
||||||
@@ -64,6 +65,8 @@ export default {
|
|||||||
nodeStrength: (d) => {
|
nodeStrength: (d) => {
|
||||||
if (d.type === nodeType.rootNode || d.type === nodeType.listNode) {
|
if (d.type === nodeType.rootNode || d.type === nodeType.listNode) {
|
||||||
return -100
|
return -100
|
||||||
|
} else if (d.type === nodeType.tempNode) {
|
||||||
|
return -300
|
||||||
}
|
}
|
||||||
return -10
|
return -10
|
||||||
},
|
},
|
||||||
@@ -77,7 +80,13 @@ export default {
|
|||||||
modes: {
|
modes: {
|
||||||
default: ['drag-canvas', 'drag-nodes', 'click-select', 'zoom-canvas']
|
default: ['drag-canvas', 'drag-nodes', 'click-select', 'zoom-canvas']
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
/* 自己实现stack操作 */
|
||||||
|
stackData: {
|
||||||
|
undo: [], // 后退
|
||||||
|
redo: [] // 前进
|
||||||
|
},
|
||||||
|
initialData: null // 初始化数据,用于重置
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -85,19 +94,26 @@ export default {
|
|||||||
this.registerElements() // 注册自定义node
|
this.registerElements() // 注册自定义node
|
||||||
const tooltip = this.buildTooltip() // tooltip组件
|
const tooltip = this.buildTooltip() // tooltip组件
|
||||||
const toolbar = this.buildToolbar() // 工具栏组装件
|
const toolbar = this.buildToolbar() // 工具栏组装件
|
||||||
this.chartOption.plugins = [tooltip] // 注册组件
|
this.chartOption.plugins = [tooltip, toolbar] // 注册组件
|
||||||
this.graph = new G6.Graph(this.chartOption)
|
this.graph = new G6.Graph(this.chartOption)
|
||||||
const initialData = await this.generateInitialData()// 初始化数据
|
try {
|
||||||
|
const initialData = await this.generateInitialData() // 备份初始数据
|
||||||
|
this.initialData = _.cloneDeep(initialData) // 初始化数据
|
||||||
this.graph.data(initialData)
|
this.graph.data(initialData)
|
||||||
this.graph.render()
|
this.graph.render()
|
||||||
const rootNode = this.graph.findById(this.entity.entityName)
|
const rootNode = this.graph.findById(this.entity.entityName)
|
||||||
this.bindEvents() // 绑定事件
|
this.bindEvents() // 绑定事件
|
||||||
this.graph.emit('node:click', { item: rootNode, target: rootNode.getKeyShape() }) // 手动触发rootNode的点击事件
|
this.graph.emit('node:click', { item: rootNode, target: rootNode.getKeyShape() }) // 手动触发rootNode的点击事件
|
||||||
|
} catch (e) {
|
||||||
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
|
} finally {
|
||||||
|
this.rightBox.loading = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
registerElements () {
|
registerElements () {
|
||||||
const _this = this
|
const _this = this
|
||||||
G6.registerNode(
|
G6.registerNode(
|
||||||
'rootNode',
|
nodeType.rootNode,
|
||||||
{
|
{
|
||||||
draw (cfg, group) {
|
draw (cfg, group) {
|
||||||
group.addShape('circle', {
|
group.addShape('circle', {
|
||||||
@@ -214,7 +230,7 @@ export default {
|
|||||||
'single-node'
|
'single-node'
|
||||||
)
|
)
|
||||||
G6.registerNode(
|
G6.registerNode(
|
||||||
'listNode',
|
nodeType.listNode,
|
||||||
{
|
{
|
||||||
draw (cfg, group) {
|
draw (cfg, group) {
|
||||||
group.addShape('circle', {
|
group.addShape('circle', {
|
||||||
@@ -324,7 +340,7 @@ export default {
|
|||||||
'single-node'
|
'single-node'
|
||||||
)
|
)
|
||||||
G6.registerNode(
|
G6.registerNode(
|
||||||
'entityNode',
|
nodeType.entityNode,
|
||||||
{
|
{
|
||||||
draw (cfg, group) {
|
draw (cfg, group) {
|
||||||
group.addShape('circle', {
|
group.addShape('circle', {
|
||||||
@@ -382,14 +398,14 @@ export default {
|
|||||||
'single-node'
|
'single-node'
|
||||||
)
|
)
|
||||||
G6.registerNode(
|
G6.registerNode(
|
||||||
'tempNode',
|
nodeType.tempNode,
|
||||||
{
|
{
|
||||||
draw (cfg, group) {
|
draw (cfg, group) {
|
||||||
group.addShape('text', {
|
group.addShape('text', {
|
||||||
attrs: {
|
attrs: {
|
||||||
text: cfg.label,
|
text: cfg.label,
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 25,
|
y: 22,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
textBaseline: 'middle',
|
textBaseline: 'middle',
|
||||||
@@ -534,7 +550,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getIconUrl (entityType, colored, isRoot) {
|
function getIconUrl (entityType, colored, isRoot) {
|
||||||
let suffix = ''
|
let suffix
|
||||||
if (entityType === 'domain' && isRoot) {
|
if (entityType === 'domain' && isRoot) {
|
||||||
suffix = '-colored2'
|
suffix = '-colored2'
|
||||||
} else {
|
} else {
|
||||||
@@ -560,10 +576,12 @@ export default {
|
|||||||
const node = e.item
|
const node = e.item
|
||||||
const nodeModel = node.get('model')
|
const nodeModel = node.get('model')
|
||||||
if (nodeModel.type !== 'tempNode') {
|
if (nodeModel.type !== 'tempNode') {
|
||||||
cleanTempNodesAndTempEdges()
|
node.setState('mySelected', true)
|
||||||
|
_this.cleanTempNodesAndTempEdges()
|
||||||
// 点击entityNode,查询数据,并根据数据生成tempNode
|
// 点击entityNode,查询数据,并根据数据生成tempNode
|
||||||
if (nodeModel.type === nodeType.entityNode) {
|
if (nodeModel.type === nodeType.entityNode) {
|
||||||
_this.rightBox.mode = 'detail'
|
_this.rightBox.loading = true
|
||||||
|
try {
|
||||||
// 若已查过数据,不重复查询
|
// 若已查过数据,不重复查询
|
||||||
if (!nodeModel.myData.relatedEntity) {
|
if (!nodeModel.myData.relatedEntity) {
|
||||||
await nodeModel.queryDetailData()
|
await nodeModel.queryDetailData()
|
||||||
@@ -581,7 +599,6 @@ export default {
|
|||||||
`${nodeModel.id}__${k}__temp`,
|
`${nodeModel.id}__${k}__temp`,
|
||||||
{
|
{
|
||||||
entityType: k,
|
entityType: k,
|
||||||
// TODO k2-k1=1+k1k2
|
|
||||||
...generateTempNodeCoordinate(nodeModel.sourceNode, e)
|
...generateTempNodeCoordinate(nodeModel.sourceNode, e)
|
||||||
},
|
},
|
||||||
nodeModel
|
nodeModel
|
||||||
@@ -593,12 +610,20 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
change && _this.graph.layout()
|
change && _this.graph.layout()
|
||||||
|
_this.rightBox.node = _.cloneDeep(nodeModel)
|
||||||
|
_this.rightBox.mode = 'detail'
|
||||||
|
} catch (e) {
|
||||||
|
_this.$message.error(_this.errorMsgHandler(e))
|
||||||
|
} finally {
|
||||||
|
_this.rightBox.loading = false
|
||||||
|
}
|
||||||
} else if (nodeModel.type === nodeType.listNode) {
|
} else if (nodeModel.type === nodeType.listNode) {
|
||||||
|
_this.rightBox.node = _.cloneDeep(nodeModel)
|
||||||
_this.rightBox.mode = 'list'
|
_this.rightBox.mode = 'list'
|
||||||
} else if (nodeModel.type === nodeType.rootNode) {
|
} else if (nodeModel.type === nodeType.rootNode) {
|
||||||
|
_this.rightBox.node = _.cloneDeep(nodeModel)
|
||||||
_this.rightBox.mode = 'detail'
|
_this.rightBox.mode = 'detail'
|
||||||
}
|
}
|
||||||
_this.rightBox.node = _.cloneDeep(nodeModel)
|
|
||||||
} else {
|
} else {
|
||||||
// 点击tempNode,根据source生成listNode和entityNode以及对应的edge。查完entityNode的接口再删除临时node和edge。
|
// 点击tempNode,根据source生成listNode和entityNode以及对应的edge。查完entityNode的接口再删除临时node和edge。
|
||||||
// 若已达第六层,则只生成listNode,不再展开entityNode
|
// 若已达第六层,则只生成listNode,不再展开entityNode
|
||||||
@@ -620,6 +645,8 @@ export default {
|
|||||||
// 判断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
|
||||||
|
try {
|
||||||
const entities = await queryRelatedEntity(nodeModel.sourceNode, listNode.myData.entityType)
|
const entities = await queryRelatedEntity(nodeModel.sourceNode, listNode.myData.entityType)
|
||||||
nodeModel.sourceNode.myData.relatedEntity[listNode.myData.entityType].list.push(...entities.list)
|
nodeModel.sourceNode.myData.relatedEntity[listNode.myData.entityType].list.push(...entities.list)
|
||||||
entities.list.forEach(entity => {
|
entities.list.forEach(entity => {
|
||||||
@@ -632,23 +659,21 @@ export default {
|
|||||||
nodes.push(entityNode)
|
nodes.push(entityNode)
|
||||||
edges.push(new Edge(listNode, entityNode))
|
edges.push(new Edge(listNode, entityNode))
|
||||||
})
|
})
|
||||||
|
} catch (e) {
|
||||||
|
_this.$message.error(_this.errorMsgHandler(e))
|
||||||
|
} finally {
|
||||||
|
_this.rightBox.loading = false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO 提示大于5层
|
// TODO 提示大于5层
|
||||||
}
|
}
|
||||||
nodes.forEach(n => {
|
_this.addItems(nodes, edges)
|
||||||
_this.graph.addItem('node', n)
|
_this.cleanTempNodesAndTempEdges()
|
||||||
})
|
|
||||||
edges.forEach(edge => {
|
|
||||||
_this.graph.addItem('edge', edge)
|
|
||||||
})
|
|
||||||
cleanTempNodesAndTempEdges()
|
|
||||||
_this.graph.layout()
|
_this.graph.layout()
|
||||||
// 手动高亮listNode
|
// 手动高亮listNode
|
||||||
const _listNode = _this.graph.findById(listNode.id)
|
const _listNode = _this.graph.findById(listNode.id)
|
||||||
_this.graph.emit('node:click', { item: _listNode, target: _listNode.getKeyShape() }) // 手动触发rootNode的点击事件
|
_this.graph.emit('node:click', { item: _listNode, target: _listNode.getKeyShape() })
|
||||||
}
|
}
|
||||||
|
|
||||||
node.setState('mySelected', true)
|
|
||||||
})
|
})
|
||||||
this.graph.on('node:mouseenter', function (e) {
|
this.graph.on('node:mouseenter', function (e) {
|
||||||
e.item.setState('hover', true)
|
e.item.setState('hover', true)
|
||||||
@@ -661,17 +686,6 @@ export default {
|
|||||||
model.fx = e.x
|
model.fx = e.x
|
||||||
model.fy = e.y
|
model.fy = e.y
|
||||||
}
|
}
|
||||||
function cleanTempNodesAndTempEdges () {
|
|
||||||
// 清除现有tempNode和tempEdge
|
|
||||||
const tempNodes = _this.graph.findAll('node', node => node.get('model').type === nodeType.tempNode)
|
|
||||||
tempNodes.forEach(n => {
|
|
||||||
_this.graph.removeItem(n, false)
|
|
||||||
})
|
|
||||||
const tempEdges = _this.graph.findAll('edge', edge => edge.get('model').isTemp)
|
|
||||||
tempEdges.forEach(n => {
|
|
||||||
_this.graph.removeItem(n, false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
function generateTempNodeCoordinate (sourceNode, event) {
|
function generateTempNodeCoordinate (sourceNode, event) {
|
||||||
const sx = sourceNode.x
|
const sx = sourceNode.x
|
||||||
const sy = sourceNode.y
|
const sy = sourceNode.y
|
||||||
@@ -683,6 +697,37 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
addItems (nodes = [], edges = [], stack = true) {
|
||||||
|
// 过滤掉已经存在的node
|
||||||
|
const _nodes = nodes.filter(n => {
|
||||||
|
return !this.graph.findById(n.id)
|
||||||
|
})
|
||||||
|
_nodes.forEach(n => {
|
||||||
|
this.graph.addItem('node', n)
|
||||||
|
})
|
||||||
|
edges.forEach(e => {
|
||||||
|
this.graph.addItem('edge', e)
|
||||||
|
})
|
||||||
|
if (stack) {
|
||||||
|
this.stackData.undo.push({ nodes: _nodes, edges })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setItemsStata (models = [], stateName, state) {
|
||||||
|
models.forEach(m => {
|
||||||
|
this.graph.setItemState(this.graph.findById(m.id), stateName, state)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cleanTempNodesAndTempEdges () {
|
||||||
|
// 清除现有tempNode和tempEdge
|
||||||
|
const tempNodes = this.graph.findAll('node', node => node.get('model').type === nodeType.tempNode)
|
||||||
|
tempNodes.forEach(n => {
|
||||||
|
this.graph.removeItem(n)
|
||||||
|
})
|
||||||
|
const tempEdges = this.graph.findAll('edge', edge => edge.get('model').isTemp)
|
||||||
|
tempEdges.forEach(n => {
|
||||||
|
this.graph.removeItem(n)
|
||||||
|
})
|
||||||
|
},
|
||||||
async generateInitialData () {
|
async generateInitialData () {
|
||||||
const nodes = []
|
const nodes = []
|
||||||
const edges = []
|
const edges = []
|
||||||
@@ -829,15 +874,59 @@ export default {
|
|||||||
className: 'toolbar__tools',
|
className: 'toolbar__tools',
|
||||||
getContent: () => {
|
getContent: () => {
|
||||||
return `<ul>
|
return `<ul>
|
||||||
<li code='zoomOut'><i class="cn-icon cn-icon-zoom-in"></i></li>
|
<li code='zoomOut'><i class="cn-icon cn-icon-zoom-out"></i></li>
|
||||||
<li code='zoomIn'><i class="cn-icon cn-icon-zoom-out"></i></li>
|
<li code='zoomIn'><i class="cn-icon cn-icon-zoom-in"></i></li>
|
||||||
<li code='undo'><i class="cn-icon cn-icon-next-step"></i></li>
|
<li code='autoZoom'><i class="cn-icon cn-icon-reset"></i></li>
|
||||||
<li code='redo'><i class="cn-icon cn-icon-pre-step"></i></li>
|
<li code='undo' id="preStep" class="toolbar--unactivated"><i class="cn-icon cn-icon-pre-step"></i></li>
|
||||||
<li code='autoZoom'><i class="cn-icon cn-icon-auto-zoom"></i></li>
|
<li code='redo' id="nextStep" class="toolbar--unactivated"><i class="cn-icon cn-icon-next-step"></i></li>
|
||||||
|
<li code='toDefault'><i class="cn-icon cn-icon-to-default"></i></li>
|
||||||
</ul>`
|
</ul>`
|
||||||
},
|
},
|
||||||
handleClick: (code, graph) => {
|
handleClick: (code, graph) => {
|
||||||
toolbar.handleDefaultOperator(code)
|
if (code === 'undo') {
|
||||||
|
const data = this.stackData.undo.pop()
|
||||||
|
data.nodes.forEach(n => {
|
||||||
|
if (n.type === nodeType.listNode) {
|
||||||
|
const listNode = this.graph.findById(n.id)
|
||||||
|
const listNodeEdges = listNode.getEdges()
|
||||||
|
listNodeEdges.forEach(e => {
|
||||||
|
e.setState('mySelected', false)
|
||||||
|
})
|
||||||
|
listNode.setState('mySelected', false)
|
||||||
|
}
|
||||||
|
this.graph.removeItem(n.id)
|
||||||
|
})
|
||||||
|
data.edges.forEach(e => {
|
||||||
|
this.graph.removeItem(e.id)
|
||||||
|
})
|
||||||
|
this.stackData.redo.push(data)
|
||||||
|
this.cleanTempNodesAndTempEdges()
|
||||||
|
this.graph.layout()
|
||||||
|
this.onCloseBlock()
|
||||||
|
} else if (code === 'redo') {
|
||||||
|
const data = this.stackData.redo.pop()
|
||||||
|
this.addItems(data.nodes, data.edges, false)
|
||||||
|
this.stackData.undo.push(data)
|
||||||
|
this.cleanTempNodesAndTempEdges()
|
||||||
|
this.graph.layout()
|
||||||
|
this.onCloseBlock()
|
||||||
|
} else if (code === 'autoZoom') {
|
||||||
|
this.graph.zoomTo(1)
|
||||||
|
this.graph.fitCenter()
|
||||||
|
} else if (code === 'zoomOut') {
|
||||||
|
const { x, y } = this.graph.getViewPortCenterPoint()
|
||||||
|
this.graph.zoomTo(this.graph.getZoom() + 0.2, { x, y })
|
||||||
|
} else if (code === 'zoomIn') {
|
||||||
|
const { x, y } = this.graph.getViewPortCenterPoint()
|
||||||
|
const currentZoom = this.graph.getZoom()
|
||||||
|
this.graph.zoomTo(currentZoom - 0.2, { x, y })
|
||||||
|
} else {
|
||||||
|
this.graph.clear()
|
||||||
|
this.graph.data(this.initialData)
|
||||||
|
this.graph.render()
|
||||||
|
const rootNode = this.graph.findById(this.entity.entityName)
|
||||||
|
this.graph.emit('node:click', { item: rootNode, target: rootNode.getKeyShape() }) // 手动触发rootNode的点击事件
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return toolbar
|
return toolbar
|
||||||
@@ -849,8 +938,12 @@ export default {
|
|||||||
const sourceModel = sourceNode.getModel()
|
const sourceModel = sourceNode.getModel()
|
||||||
const expandType = model.myData.entityType
|
const expandType = model.myData.entityType
|
||||||
if (sourceModel.myData.relatedEntity[expandType].list.length < 50) {
|
if (sourceModel.myData.relatedEntity[expandType].list.length < 50) {
|
||||||
|
this.rightBox.loading = true
|
||||||
|
try {
|
||||||
const entities = await queryRelatedEntity(sourceModel, expandType)
|
const entities = await queryRelatedEntity(sourceModel, expandType)
|
||||||
sourceModel.myData.relatedEntity[expandType].list.push(...entities.list)
|
sourceModel.myData.relatedEntity[expandType].list.push(...entities.list)
|
||||||
|
const entityNodeModels = []
|
||||||
|
const edgeModels = []
|
||||||
entities.list.forEach(entity => {
|
entities.list.forEach(entity => {
|
||||||
const entityNodeModel = new Node(nodeType.entityNode, entity.vertex, {
|
const entityNodeModel = new Node(nodeType.entityNode, entity.vertex, {
|
||||||
entityType: expandType,
|
entityType: expandType,
|
||||||
@@ -858,13 +951,20 @@ export default {
|
|||||||
x: model.x + Math.random() * 500 - 250,
|
x: model.x + Math.random() * 500 - 250,
|
||||||
y: model.y + Math.random() * 500 - 250
|
y: model.y + Math.random() * 500 - 250
|
||||||
}, model)
|
}, model)
|
||||||
this.graph.addItem('node', entityNodeModel)
|
entityNodeModels.push(entityNodeModel)
|
||||||
|
|
||||||
const edge = new Edge(model, entityNodeModel)
|
const edge = new Edge(model, entityNodeModel)
|
||||||
this.graph.addItem('edge', edge)
|
edgeModels.push(edge)
|
||||||
this.graph.layout()
|
|
||||||
this.graph.setItemState(this.graph.findById(edge.id), 'mySelected', true)
|
|
||||||
})
|
})
|
||||||
|
this.addItems(entityNodeModels, edgeModels)
|
||||||
|
this.setItemsStata(edgeModels, 'mySelected', true)
|
||||||
|
this.graph.layout()
|
||||||
this.rightBox.node = _.cloneDeep(model)
|
this.rightBox.node = _.cloneDeep(model)
|
||||||
|
} catch (e) {
|
||||||
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
|
} finally {
|
||||||
|
this.rightBox.loading = false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO 提示超过50
|
// TODO 提示超过50
|
||||||
}
|
}
|
||||||
@@ -874,11 +974,17 @@ export default {
|
|||||||
if (node) {
|
if (node) {
|
||||||
const nodeModel = node.getModel()
|
const nodeModel = node.getModel()
|
||||||
if (nodeModel.myData.relatedEntity[expandType].list.length < 50) {
|
if (nodeModel.myData.relatedEntity[expandType].list.length < 50) {
|
||||||
|
const toAddNodeModels = []
|
||||||
|
const toAddEdgeModels = []
|
||||||
|
|
||||||
|
this.rightBox.loading = true
|
||||||
|
try {
|
||||||
const entities = await queryRelatedEntity(nodeModel, expandType)
|
const entities = await queryRelatedEntity(nodeModel, expandType)
|
||||||
nodeModel.myData.relatedEntity[expandType].list.push(...entities.list)
|
nodeModel.myData.relatedEntity[expandType].list.push(...entities.list)
|
||||||
const neighbors = node.getNeighbors('target')
|
const neighbors = node.getNeighbors('target')
|
||||||
const listNode = neighbors.find(n => n.getModel().myData.entityType === expandType)
|
const listNode = neighbors.find(n => n.getModel().myData.entityType === expandType)
|
||||||
let listNodeModel = listNode.getModel()
|
let listNodeModel = listNode.getModel()
|
||||||
|
let listEdgeModel
|
||||||
// 如果listNode是tempNode,移除,并新建listNode
|
// 如果listNode是tempNode,移除,并新建listNode
|
||||||
if (listNodeModel.type === nodeType.tempNode) {
|
if (listNodeModel.type === nodeType.tempNode) {
|
||||||
// 移除tempNode和tempEdge
|
// 移除tempNode和tempEdge
|
||||||
@@ -889,10 +995,9 @@ export default {
|
|||||||
this.graph.removeItem(listNode)
|
this.graph.removeItem(listNode)
|
||||||
|
|
||||||
listNodeModel = new Node(nodeType.listNode, `${nodeModel.id}__${expandType}-list`, { entityType: expandType, x: listNodeModel.x, y: listNodeModel.y }, nodeModel)
|
listNodeModel = new Node(nodeType.listNode, `${nodeModel.id}__${expandType}-list`, { entityType: expandType, x: listNodeModel.x, y: listNodeModel.y }, nodeModel)
|
||||||
const edge = new Edge(nodeModel, listNodeModel)
|
listEdgeModel = new Edge(nodeModel, listNodeModel)
|
||||||
this.graph.addItem('node', listNodeModel)
|
toAddNodeModels.push(listNodeModel)
|
||||||
this.graph.addItem('edge', edge)
|
toAddEdgeModels.push(listEdgeModel)
|
||||||
this.graph.setItemState(this.graph.findById(edge.id), 'mySelected', true)
|
|
||||||
}
|
}
|
||||||
entities.list.forEach(entity => {
|
entities.list.forEach(entity => {
|
||||||
const entityNodeModel = new Node(nodeType.entityNode, entity.vertex, {
|
const entityNodeModel = new Node(nodeType.entityNode, entity.vertex, {
|
||||||
@@ -901,21 +1006,59 @@ export default {
|
|||||||
x: listNodeModel.x + Math.random() * 500 - 250,
|
x: listNodeModel.x + Math.random() * 500 - 250,
|
||||||
y: listNodeModel.y + Math.random() * 500 - 250
|
y: listNodeModel.y + Math.random() * 500 - 250
|
||||||
}, listNodeModel)
|
}, listNodeModel)
|
||||||
this.graph.addItem('node', entityNodeModel)
|
toAddNodeModels.push(entityNodeModel)
|
||||||
this.graph.addItem('edge', new Edge(listNodeModel, entityNodeModel))
|
toAddEdgeModels.push(new Edge(listNodeModel, entityNodeModel))
|
||||||
this.graph.layout()
|
|
||||||
})
|
})
|
||||||
|
this.addItems(toAddNodeModels, toAddEdgeModels)
|
||||||
|
if (listEdgeModel) {
|
||||||
|
this.graph.setItemState(this.graph.findById(listEdgeModel.id), 'mySelected', true)
|
||||||
|
}
|
||||||
|
this.graph.layout()
|
||||||
this.rightBox.node = _.cloneDeep(nodeModel)
|
this.rightBox.node = _.cloneDeep(nodeModel)
|
||||||
|
} catch (e) {
|
||||||
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
|
} finally {
|
||||||
|
this.rightBox.loading = false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO 提示超过50
|
// TODO 提示超过50
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
resize () {
|
||||||
|
const container = document.getElementById('entityGraph')
|
||||||
|
this.graph.changeSize(container.offsetWidth, container.offsetHeight)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
stackData: {
|
||||||
|
deep: true,
|
||||||
|
handler (n) {
|
||||||
|
if (n) {
|
||||||
|
if (n.undo.length > 0) {
|
||||||
|
document.getElementById('preStep').classList.remove('toolbar--unactivated')
|
||||||
|
console.info(n, document.getElementById('preStep').classList)
|
||||||
|
} else {
|
||||||
|
document.getElementById('preStep').classList.add('toolbar--unactivated')
|
||||||
|
}
|
||||||
|
if (n.redo.length > 0) {
|
||||||
|
document.getElementById('nextStep').classList.remove('toolbar--unactivated')
|
||||||
|
} else {
|
||||||
|
document.getElementById('nextStep').classList.add('toolbar--unactivated')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted () {
|
async mounted () {
|
||||||
if (this.entity.entityType && this.entity.entityName) {
|
if (this.entity.entityType && this.entity.entityName) {
|
||||||
await this.init()
|
await this.init()
|
||||||
}
|
}
|
||||||
|
this.debounceFunc = this.$_.debounce(this.resize, 300)
|
||||||
|
window.addEventListener('resize', this.debounceFunc)
|
||||||
|
},
|
||||||
|
unmounted () {
|
||||||
|
window.removeEventListener('resize', this.debounceFunc)
|
||||||
},
|
},
|
||||||
setup () {
|
setup () {
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -931,7 +1074,7 @@ export default {
|
|||||||
mode: 'detail', // list | detail
|
mode: 'detail', // list | detail
|
||||||
show: true,
|
show: true,
|
||||||
node: null,
|
node: null,
|
||||||
loading: false
|
loading: true
|
||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
entity,
|
entity,
|
||||||
|
|||||||
@@ -114,6 +114,9 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
node: {
|
node: {
|
||||||
type: Object
|
type: Object
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ export default {
|
|||||||
if (e.response.data && e.response.data.message) {
|
if (e.response.data && e.response.data.message) {
|
||||||
this.$message.error(e.response.data.message)
|
this.$message.error(e.response.data.message)
|
||||||
} else {
|
} else {
|
||||||
this.$message.error('Something went wrong...')
|
this.$message.error(this.$t('tip.somethingWentWrong'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -402,7 +402,7 @@ export default {
|
|||||||
if (e.response.data && e.response.data.message) {
|
if (e.response.data && e.response.data.message) {
|
||||||
this.$message.error(e.response.data.message)
|
this.$message.error(e.response.data.message)
|
||||||
} else {
|
} else {
|
||||||
this.$message.error('Something went wrong...')
|
this.$message.error(this.$t('tip.somethingWentWrong'))
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.toggleLoading(false)
|
this.toggleLoading(false)
|
||||||
|
|||||||
Reference in New Issue
Block a user