Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 🐛 optimize contextmenu tools #1391

Merged
merged 1 commit into from
Oct 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 49 additions & 33 deletions examples/x6-example-features/src/pages/tools/contextmenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@ class ContextMenuTool extends ToolsView.ToolItem<
ContextMenuToolOptions
> {
private knob: HTMLDivElement
private timer: number

render() {
super.render()
this.knob = ToolsView.createElement('div', false) as HTMLDivElement
this.knob.style.position = 'absolute'
this.container.appendChild(this.knob)
this.updatePosition(this.options)
setTimeout(() => {
this.toggleContextMenu(true)
})
if (!this.knob) {
this.knob = ToolsView.createElement('div', false) as HTMLDivElement
this.knob.style.position = 'absolute'
this.container.appendChild(this.knob)
}
return this
}

Expand All @@ -41,9 +39,10 @@ class ContextMenuTool extends ToolsView.ToolItem<
}
}

private updatePosition(pos?: { x: number; y: number }) {
private updatePosition(e?: MouseEvent) {
const style = this.knob.style
if (pos) {
if (e) {
const pos = this.graph.clientToGraph(e.clientX, e.clientY)
style.left = `${pos.x}px`
style.top = `${pos.y}px`
} else {
Expand All @@ -52,15 +51,30 @@ class ContextMenuTool extends ToolsView.ToolItem<
}
}

private onMouseDown = (e: MouseEvent) => {
setTimeout(() => {
private onMouseDown = () => {
this.timer = window.setTimeout(() => {
this.updatePosition()
this.toggleContextMenu(false)
if (this.options.onHide) {
this.options.onHide.call(this)
}
}, 200)
}

private onContextMenu({ e }: { e: MouseEvent }) {
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()
}

protected onRemove() {
this.cellView.off('cell:contextmenu', this.onContextMenu, this)
}
}

ContextMenuTool.config({
Expand All @@ -69,10 +83,7 @@ ContextMenuTool.config({
})

export interface ContextMenuToolOptions extends ToolsView.ToolItem.Options {
x: number
y: number
menu?: Menu | (() => Menu)
onHide?: (this: ContextMenuTool) => void
menu: React.ReactElement
}

Graph.registerEdgeTool('contextmenu', ContextMenuTool, true)
Expand All @@ -87,7 +98,7 @@ const menu = (
3rd menu item
</a>
</Menu.Item>
<Menu.Item key="4" danger="true">
<Menu.Item key="4" danger>
a danger item
</Menu.Item>
</Menu>
Expand Down Expand Up @@ -121,6 +132,14 @@ export default class Example extends React.Component {
strokeWidth: 1,
},
},
tools: [
{
name: 'contextmenu',
args: {
menu,
},
},
],
})

const target = graph.addNode({
Expand All @@ -135,6 +154,14 @@ export default class Example extends React.Component {
strokeWidth: 1,
},
},
tools: [
{
name: 'contextmenu',
args: {
menu,
},
},
],
})

graph.addEdge({
Expand All @@ -146,26 +173,15 @@ export default class Example extends React.Component {
strokeWidth: 1,
},
},
})

graph.on('cell:contextmenu', ({ cell, e }) => {
const p = graph.clientToGraph(e.clientX, e.clientY)
cell.addTools([
tools: [
{
name: 'contextmenu',
args: {
menu,
x: p.x,
y: p.y,
onHide() {
this.cell.removeTools()
},
},
},
])
],
})

graph.zoomTo(0.8)
}

refContainer = (container: HTMLDivElement) => {
Expand Down
109 changes: 54 additions & 55 deletions examples/x6-example-features/src/pages/tools/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,53 @@ import { Graph, ToolsView, EdgeView } from '@antv/x6'
import '../index.less'

class TooltipTool extends ToolsView.ToolItem<EdgeView, TooltipToolOptions> {
private delay = 100
private timer: number
private knob: HTMLDivElement
private tooltipVisible: boolean

render() {
super.render()
this.knob = ToolsView.createElement('div', false) as HTMLDivElement
this.knob.style.position = 'absolute'
this.container.appendChild(this.knob)
this.updatePosition()
document.addEventListener('mousemove', this.onMouseMove)

if (!this.knob) {
this.knob = ToolsView.createElement('div', false) as HTMLDivElement
this.knob.style.position = 'absolute'
this.container.appendChild(this.knob)
}
return this
}

private toggleTooltip(visible: boolean) {
ReactDom.unmountComponentAtNode(this.knob)

if (visible) {
ReactDom.render(
<Tooltip title={this.options.tooltip} visible={true}>
<Tooltip
title={this.options.tooltip}
visible={true}
destroyTooltipOnHide
>
<div />
</Tooltip>,
this.knob,
)
}
this.tooltipVisible = visible
}

private onMosueEnter({ e }: { e: MouseEvent }) {
this.updatePosition(e)
this.toggleTooltip(true)
}

private onMouseLeave() {
this.updatePosition()
this.toggleTooltip(false)
}

private 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()
}

private updatePosition(e?: MouseEvent) {
Expand All @@ -49,31 +68,10 @@ class TooltipTool extends ToolsView.ToolItem<EdgeView, TooltipToolOptions> {
}
}

private onMouseLeave() {
this.updatePosition()
window.clearTimeout(this.timer)
window.setTimeout(() => this.toggleTooltip(false), this.delay)
document.removeEventListener('mousemove', this.onMouseMove)
}

private onMouseMove = (e: MouseEvent) => {
window.clearTimeout(this.timer)
this.updatePosition(e)
this.timer = window.setTimeout(() => {
if (this.tooltipVisible) {
this.toggleTooltip(false)
}
this.toggleTooltip(true)
}, this.delay)
}

delegateEvents() {
this.cellView.on('cell:mouseleave', this.onMouseLeave, this)
return super.delegateEvents()
}

protected onRemove() {
this.cellView.off('cell:mouseenter', this.onMosueEnter, this)
this.cellView.off('cell:mouseleave', this.onMouseLeave, this)
this.cellView.off('cell:mousemove', this.onMouseMove, this)
}
}

Expand All @@ -86,8 +84,8 @@ export interface TooltipToolOptions extends ToolsView.ToolItem.Options {
tooltip?: string
}

Graph.registerNodeTool('tooltip', TooltipTool, true)
Graph.registerEdgeTool('tooltip', TooltipTool, true)
Graph.registerNodeTool('tooltip', TooltipTool, true)

export default class Example extends React.Component {
private container: HTMLDivElement
Expand All @@ -114,6 +112,14 @@ export default class Example extends React.Component {
strokeWidth: 1,
},
},
tools: [
{
name: 'tooltip',
args: {
tooltip: 'tooltip content',
},
},
],
})

const target = graph.addNode({
Expand All @@ -128,6 +134,14 @@ export default class Example extends React.Component {
strokeWidth: 1,
},
},
tools: [
{
name: 'tooltip',
args: {
tooltip: 'tooltip content',
},
},
],
})

graph.addEdge({
Expand All @@ -137,31 +151,16 @@ export default class Example extends React.Component {
line: {
stroke: '#a0a0a0',
strokeWidth: 1,
targetMarker: {
name: 'classic',
size: 7,
},
},
},
})

graph.on('cell:mouseenter', ({ cell }) => {
cell.addTools([
tools: [
{
name: 'tooltip',
args: {
tooltip: cell.isNode()
? cell === source
? 'source tooltip'
: 'target tooltip '
: 'edge tooltip',
tooltip: 'tooltip content',
},
},
])
})

graph.on('cell:mouseleave', ({ cell }) => {
cell.removeTools()
],
})
}

Expand Down
Loading