contextMenu右键菜单
代码如下(示例):
<template>
<div class="graph-container">
<div ref="graph" id="graph" />
</div>
</template>
<script>
import Vue from 'vue'
import { Graph, ToolsView } from '@antv/x6'
import { DropdownItem } from 'element-ui'
class ContextMenuTool extends ToolsView.ToolItem {
knob = null
timer = null
dropdownMenuDom = null
dropdownMenuComp = null
render() {
if (!this.knob) {
this.knob = ToolsView.createElement('div', false)
this.knob.style.position = 'absolute'
this.dropdownMenuDom = ToolsView.createElement('div', false)
this.knob.appendChild(this.dropdownMenuDom)
this.container.appendChild(this.knob)
}
return this
}
toggleContextMenu(visible) {
if (this.dropdownMenuComp) {
this.dropdownMenuComp.$destroy()
this.knob.innerHTML = ''
this.knob.appendChild(this.dropdownMenuDom)
this.dropdownMenuComp = null
}
document.removeEventListener('mousedown', this.onMouseDown)
if (visible) {
const that = this
this.dropdownMenuComp = new Vue({
el: this.dropdownMenuDom,
render() {
return (
<ul
class='el-dropdown-menu el-popper'
x-placement='bottom-end'
style='width: max-content; z-index: 1000; border-radius: 4px'
>
{that.options.menu.map(it => <DropdownItem><span onClick={that.handleClick}>{it.label}</span></DropdownItem>)}
</ul>
)
}
})
document.addEventListener('mousedown', this.onMouseDown)
}
}
handleClick = (e) => {
console.log(e.target.innerText, this)
}
updatePosition(e) {
const style = this.knob.style
if (e) {
const pos = this.graph.clientToGraph(e.clientX, e.clientY)
style.left = `${pos.x}px`
style.top = `${pos.y}px`
} else {
style.left = '-1000px'
style.top = '-1000px'
}
}
onMouseDown = () => {
this.timer = setTimeout(() => {
this.updatePosition()
this.toggleContextMenu(false)
}, 200)
}
onContextMenu({ e }) {
if (this.timer) {
clearTimeout(this.timer)
this.timer = 0
}
this.updatePosition(e)
this.toggleContextMenu(true)
}
delegateEvents() {
this.cellView.on('cell:contextmenu', this.onContextMenu, this)
return super.delegateEvents()
}
onRemove() {
this.cellView.off('cell:contextmenu', this.onContextMenu, this)
}
}
ContextMenuTool.config({
tagName: 'div',
isSVGElement: false,
})
Graph.registerNodeTool('contextmenu', ContextMenuTool, true)
// Graph.registerEdgeTool('contextmenu', ContextMenuTool, true)
export default {
data() {
return {
graphData: {
nodes: [{
id: 'node1',
x: 40,
y: 40,
width: 80,
height: 40,
label: 'hello',
tools: [{
name: 'contextmenu',
args: {
menu: [
{ label: '跳过' },
{ label: '重执行' },
{ label: '结束' }
]
}
}]
}, {
id: 'node2',
x: 160,
y: 180,
width: 80,
height: 40,
label: 'world',
tools: [{
name: 'contextmenu',
args: {
menu: [
{ label: '跳过' },
{ label: '重执行' },
{ label: '结束' }
]
}
}]
}],
// 边
edges: [{
source: 'node1', // String,必须,起始节点 id
target: 'node2', // String,必须,目标节点 id
}]
}
}
},
mounted() {
const graph = new Graph({
container: this.$refs.graph,
autoResize: true,
grid: true
})
graph.fromJSON(this.graphData)
graph.centerContent()
}
}
</script>
<style lang="scss" scoped>
.graph-container {
width: 100%;
height: 100%;
display: flex;
#graph {
flex: 1
}
}
</style>
tooltip提示框
代码如下(示例):
<template>
<div class="graph-container">
<div ref="graph" id="graph" />
</div>
</template>
<script>
import Vue from 'vue'
import { Graph, ToolsView } from '@antv/x6'
import { Tooltip } from 'element-ui'
class TooltipTool extends ToolsView.ToolItem {
knob = null
tooltipDom = null
tooltipComp = null
render() {
if (!this.knob) {
this.knob = ToolsView.createElement('div', false)
this.knob.style.position = 'absolute'
this.tooltipDom = ToolsView.createElement('div', false)
this.knob.appendChild(this.tooltipDom)
this.container.appendChild(this.knob)
}
return this
}
toggleTooltip(visible) {
if (this.tooltipComp) {
this.tooltipComp.$destroy()
this.knob.innerHTML = ''
this.knob.appendChild(this.tooltipDom)
this.tooltipComp = null
}
if (visible) {
const that = this
this.tooltipComp = new Vue({
el: this.tooltipDom,
render() {
return (
// 假如遇到effect不生效,就用style去调样式
<Tooltip value={true} effect='dark'>
<div />
<div slot="content" style={{
color: '#fff',
backgroundColor: 'rgb(0, 0, 0, .7)',
padding: '10px',
borderRadius: '4px'
}}>
标题:{that.options.content}
</div>
</Tooltip>
)
}
})
}
}
updatePosition(e) {
const style = this.knob.style
if (e) {
const p = this.graph.clientToGraph(e.clientX, e.clientY)
style.display = 'block'
style.left = `${p.x}px`
style.top = `${p.y}px`
} else {
style.display = 'none'
style.left = '-1000px'
style.top = '-1000px'
}
}
onMosueEnter({ e }) {
this.updatePosition(e)
this.toggleTooltip(true)
}
onMouseLeave() {
this.updatePosition()
this.toggleTooltip(false)
}
onMouseMove() {
this.updatePosition()
this.toggleTooltip(false)
}
delegateEvents() {
this.cellView.on('cell:mouseenter', this.onMosueEnter, this)
this.cellView.on('cell:mouseleave', this.onMouseLeave, this)
this.cellView.on('cell:mousemove', this.onMouseMove, this)
return super.delegateEvents()
}
onRemove() {
this.toggleTooltip(false)
this.cellView.off('cell:mouseenter', this.onMosueEnter, this)
this.cellView.off('cell:mouseleave', this.onMouseLeave, this)
this.cellView.off('cell:mousemove', this.onMouseMove, this)
}
}
TooltipTool.config({
tagName: 'div',
isSVGElement: false,
})
Graph.registerNodeTool('tooltip', TooltipTool, true)
// Graph.registerEdgeTool('tooltip', TooltipTool, true)
export default {
data() {
return {
graphData: {
nodes: [{
id: 'node1',
x: 40,
y: 40,
width: 80,
height: 40,
label: 'hello',
tools: [{
name: 'tooltip',
args: {
content: '测试tooltip'
}
}]
}, {
id: 'node2',
x: 160,
y: 180,
width: 80,
height: 40,
label: 'world',
tools: [{
name: 'tooltip',
args: {
content: '测试tooltip'
}
}]
}],
// 边
edges: [{
source: 'node1', // String,必须,起始节点 id
target: 'node2', // String,必须,目标节点 id
}]
}
}
},
mounted() {
const graph = new Graph({
container: this.$refs.graph,
autoResize: true,
grid: true
})
graph.fromJSON(this.graphData)
graph.centerContent()
}
}
</script>
<style lang="scss" scoped>
.graph-container {
width: 100%;
height: 100%;
display: flex;
#graph {
flex: 1
}
}
</style>