-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(behavior): hide elements when zooming, scrolling and dragging ca…
…nvas (#6054) * feat(behavior): hide elements when zooming,scrolling and dragging canvas * fix: fix cr issues * test: supplement viewport transfron test * refactor: rename ViewportEvent to IViewportEvent
- Loading branch information
Showing
13 changed files
with
4,562 additions
and
10 deletions.
There are no files selected for viewing
31 changes: 31 additions & 0 deletions
31
packages/g6/__tests__/demos/behavior-optimize-viewport-transform.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { Graph } from '@/src'; | ||
import data from '@@/dataset/cluster.json'; | ||
|
||
export const behaviorOptimizeViewportTransform: TestCase = async (context) => { | ||
const graph = new Graph({ | ||
...context, | ||
data, | ||
layout: { | ||
type: 'd3-force', | ||
}, | ||
node: { | ||
style: { | ||
iconSrc: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg', | ||
labelFontSize: 8, | ||
labelText: (datum) => datum.id, | ||
size: 20, | ||
}, | ||
}, | ||
edge: { | ||
style: { | ||
labelFontSize: 8, | ||
labelText: (datum) => datum.id, | ||
}, | ||
}, | ||
behaviors: ['drag-canvas', 'zoom-canvas', 'scroll-canvas', 'optimize-viewport-transform'], | ||
}); | ||
|
||
await graph.render(); | ||
|
||
return graph; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1,427 changes: 1,427 additions & 0 deletions
1,427
...sts__/snapshots/behaviors/optimize-viewport-transform/after-viewport-change.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1,427 changes: 1,427 additions & 0 deletions
1,427
packages/g6/__tests__/snapshots/behaviors/optimize-viewport-transform/default.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1,427 changes: 1,427 additions & 0 deletions
1,427
...6/__tests__/snapshots/behaviors/optimize-viewport-transform/viewport-change.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions
36
packages/g6/__tests__/unit/behaviors/optimize-viewport-transform.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { behaviorOptimizeViewportTransform } from '@/__tests__/demos'; | ||
import { GraphEvent, type Graph } from '@/src'; | ||
import { createDemoGraph } from '@@/utils'; | ||
|
||
describe('behavior optimize canvas', () => { | ||
let graph: Graph; | ||
|
||
beforeAll(async () => { | ||
graph = await createDemoGraph(behaviorOptimizeViewportTransform, { animation: false }); | ||
}); | ||
|
||
it('viewport', async () => { | ||
await expect(graph).toMatchSnapshot(__filename); | ||
|
||
graph.emit(GraphEvent.BEFORE_TRANSFORM, { | ||
type: GraphEvent.BEFORE_TRANSFORM, | ||
data: { | ||
mode: 'relative', | ||
translate: [0, -3], | ||
}, | ||
}); | ||
await expect(graph).toMatchSnapshot(__filename, 'viewport-change'); | ||
graph.emit(GraphEvent.AFTER_TRANSFORM, { | ||
type: GraphEvent.AFTER_TRANSFORM, | ||
data: { | ||
mode: 'relative', | ||
translate: [0, -1], | ||
}, | ||
}); | ||
await expect(graph).toMatchSnapshot(__filename, 'after-viewport-change'); | ||
}); | ||
|
||
it('destroy', () => { | ||
graph.destroy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
packages/g6/src/behaviors/optimize-viewport-transform.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import type { BaseStyleProps, DisplayObject } from '@antv/g'; | ||
import { debounce, isFunction } from '@antv/util'; | ||
import { GraphEvent } from '../constants'; | ||
import type { RuntimeContext } from '../runtime/types'; | ||
import type { IViewportEvent } from '../types/event'; | ||
import { setVisibility } from '../utils/visibility'; | ||
import type { BaseBehaviorOptions } from './base-behavior'; | ||
import { BaseBehavior } from './base-behavior'; | ||
|
||
/** | ||
* <zh/> 画布优化交互配置项 | ||
* | ||
* <en/> Canvas optimization behavior options | ||
*/ | ||
export interface OptimizeViewportTransformOptions extends BaseBehaviorOptions { | ||
/** | ||
* <zh/> 是否启用画布优化功能 | ||
* | ||
* <en/> Whether to enable canvas optimization function | ||
* @defaultValue true | ||
*/ | ||
enable?: boolean | ((event: IViewportEvent) => boolean); | ||
/** | ||
* <zh/> 始终保留的图形类名。操作画布过程中会隐藏元素reservedShapes(除了指定类名的图形),以提高性能 | ||
* | ||
* <en/> Persistently reserved shape classnames. Elements are hidden during canvas manipulation (except for shapes with specified classnames) to enhance performance. | ||
* @defaultValue `{ node: ['key'] }` | ||
*/ | ||
shapes?: { | ||
node?: string[]; | ||
edge?: string[]; | ||
combo?: string[]; | ||
}; | ||
/** | ||
* <zh/> 设置防抖时间 | ||
* | ||
* <en/> Set debounce time | ||
* @defaultValue 200 | ||
*/ | ||
debounce?: number; | ||
} | ||
|
||
/** | ||
* <zh/> 操作画布过程中隐藏元素 | ||
* | ||
* <en/> Hide elements during canvas operations (dragging, zooming, scrolling) | ||
*/ | ||
export class OptimizeViewportTransform extends BaseBehavior<OptimizeViewportTransformOptions> { | ||
static defaultOptions: Partial<OptimizeViewportTransformOptions> = { | ||
enable: true, | ||
debounce: 200, | ||
shapes: { node: ['key'] }, | ||
}; | ||
|
||
private isVisible: boolean = true; | ||
|
||
constructor(context: RuntimeContext, options: OptimizeViewportTransformOptions) { | ||
super(context, Object.assign({}, OptimizeViewportTransform.defaultOptions, options)); | ||
this.bindEvents(); | ||
} | ||
|
||
private filterShapes = (shapes: DisplayObject[], classnames?: string[]) => { | ||
return shapes.filter((shape) => shape.className && !classnames?.includes(shape.className)); | ||
}; | ||
|
||
private setElementsVisibility = ( | ||
elements: DisplayObject[], | ||
visibility: BaseStyleProps['visibility'], | ||
excludedClassnames?: string[], | ||
) => { | ||
elements.forEach((element) => { | ||
setVisibility( | ||
element, | ||
visibility, | ||
excludedClassnames && ((shapes) => this.filterShapes(shapes, excludedClassnames)), | ||
); | ||
}); | ||
}; | ||
|
||
private hideShapes = (event: IViewportEvent) => { | ||
if (!this.validate(event) || !this.isVisible) return; | ||
|
||
const { element } = this.context; | ||
const { shapes = {} } = this.options; | ||
this.setElementsVisibility(element!.getNodes(), 'hidden', shapes.node); | ||
this.setElementsVisibility(element!.getEdges(), 'hidden', shapes.edge); | ||
this.setElementsVisibility(element!.getCombos(), 'hidden', shapes.combo); | ||
this.isVisible = false; | ||
}; | ||
|
||
private showShapes = debounce((event: IViewportEvent) => { | ||
if (!this.validate(event) || this.isVisible) return; | ||
|
||
const { element } = this.context; | ||
this.setElementsVisibility(element!.getNodes(), 'visible'); | ||
this.setElementsVisibility(element!.getEdges(), 'visible'); | ||
this.setElementsVisibility(element!.getCombos(), 'visible'); | ||
this.isVisible = true; | ||
}, this.options.debounce); | ||
|
||
private bindEvents() { | ||
const { graph } = this.context; | ||
|
||
graph.on(GraphEvent.BEFORE_TRANSFORM, this.hideShapes); | ||
graph.on(GraphEvent.AFTER_TRANSFORM, this.showShapes); | ||
} | ||
|
||
private unbindEvents() { | ||
const { graph } = this.context; | ||
|
||
graph.off(GraphEvent.BEFORE_TRANSFORM, this.hideShapes); | ||
graph.off(GraphEvent.AFTER_TRANSFORM, this.showShapes); | ||
} | ||
|
||
private validate(event: IViewportEvent) { | ||
if (this.destroyed) return false; | ||
|
||
const { enable } = this.options; | ||
if (isFunction(enable)) return enable(event); | ||
return !!enable; | ||
} | ||
|
||
public destroy() { | ||
this.unbindEvents(); | ||
super.destroy(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Graph } from '@antv/g6'; | ||
|
||
const graph = new Graph({ | ||
container: 'container', | ||
layout: { | ||
type: 'grid', | ||
}, | ||
data: { | ||
nodes: [{ id: 'node1' }, { id: 'node2' }, { id: 'node3' }, { id: 'node4' }, { id: 'node5' }], | ||
edges: [ | ||
{ source: 'node1', target: 'node2' }, | ||
{ source: 'node1', target: 'node3' }, | ||
{ source: 'node1', target: 'node4' }, | ||
{ source: 'node2', target: 'node3' }, | ||
{ source: 'node3', target: 'node4' }, | ||
{ source: 'node4', target: 'node5' }, | ||
], | ||
}, | ||
node: { | ||
style: { | ||
labelText: (datum) => datum.id, | ||
}, | ||
}, | ||
behaviors: ['zoom-canvas', 'drag-canvas', 'scroll-canvas', 'optimize-viewport-transform'], | ||
}); | ||
|
||
graph.render(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Graph } from '@antv/g6'; | ||
|
||
const graph = new Graph({ | ||
container: 'container', | ||
layout: { | ||
type: 'grid', | ||
}, | ||
data: { | ||
nodes: [{ id: 'node1' }, { id: 'node2' }, { id: 'node3' }, { id: 'node4' }, { id: 'node5' }], | ||
edges: [ | ||
{ source: 'node1', target: 'node2' }, | ||
{ source: 'node1', target: 'node3' }, | ||
{ source: 'node1', target: 'node4' }, | ||
{ source: 'node2', target: 'node3' }, | ||
{ source: 'node3', target: 'node4' }, | ||
{ source: 'node4', target: 'node5' }, | ||
], | ||
}, | ||
behaviors: ['zoom-canvas'], | ||
}); | ||
|
||
graph.render(); |