Skip to content

Commit

Permalink
feat: add toolbar plugin (#5589)
Browse files Browse the repository at this point in the history
* feat: add type define of toolbar plugin

* feat: add toolbar plugin

* docs: add toolbar demo

* test: add test case

* chore: fix typo

* fix: remove insert-css

* chore: update test case

* chore: fix cr
  • Loading branch information
hustcc authored Mar 27, 2024
1 parent 5566f74 commit fff59f2
Show file tree
Hide file tree
Showing 17 changed files with 590 additions and 136 deletions.
2 changes: 2 additions & 0 deletions packages/g6/__tests__/demo/case/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export * from './layout-radial-prevent-overlap-unstrict';
export * from './layout-radial-sort';
export * from './plugin-contextmenu';
export * from './plugin-grid-line';
export * from './plugin-toolbar-build-in';
export * from './plugin-toolbar-iconfont';
export * from './plugin-tooltip';
export * from './plugin-watermark';
export * from './plugin-watermark-image';
Expand Down
74 changes: 74 additions & 0 deletions packages/g6/__tests__/demo/case/plugin-toolbar-build-in.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { Graph } from '@/src';
import data from '@@/dataset/cluster.json';
import type { STDTestCase } from '../types';

export const pluginToolbarBuildIn: STDTestCase = async (context) => {
const graph = new Graph({
...context,
autoResize: true,
data,
layout: { type: 'd3force' },
plugins: [
{
type: 'toolbar',
position: 'top-left',
onClick: (item: string, e: MouseEvent) => {
console.log('item clicked:', item, e);
},
getItems: () => {
return [
{ id: 'zoom-in', value: 'zoom-in' },
{ id: 'zoom-out', value: 'zoom-out' },
{ id: 'redo', value: 'redo' },
{ id: 'undo', value: 'undo' },
{ id: 'edit', value: 'edit' },
{ id: 'delete', value: 'delete' },
{ id: 'auto-fit', value: 'auto-fit' },
{ id: 'export', value: 'export' },
{ id: 'reset', value: 'reset' },
];
},
},
],
});

await graph.render();

pluginToolbarBuildIn.form = (panel) => {
const config = {
position: 'top-left',
};
return [
panel
.add(config, 'position', {
'top-right': 'top-right',
'top-left': 'top-left',
'bottom-right': 'bottom-right',
'bottom-left': 'bottom-left',
'left-top': 'left-top',
'left-bottom': 'left-bottom',
'right-top': 'right-top',
'right-bottom': 'right-bottom',
})
.name('Position')
.onChange((position: string) => {
graph.setPlugins([
{
type: 'toolbar',
position,
getItems: () => {
return [
{ id: 'zoom-in', value: 'zoom-in' },
{ id: 'zoom-out', value: 'zoom-out' },
];
},
enable: true,
},
]);
graph.render();
}),
];
};

return graph;
};
37 changes: 37 additions & 0 deletions packages/g6/__tests__/demo/case/plugin-toolbar-iconfont.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Graph } from '@/src';
import data from '@@/dataset/cluster.json';
import type { STDTestCase } from '../types';

export const pluginToolbarIconfont: STDTestCase = async (context) => {
// Use iconfont for toolbar items.
const iconFont = document.createElement('script');
iconFont.src = '//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js';
document.head.appendChild(iconFont);

const graph = new Graph({
...context,
autoResize: true,
data,
layout: { type: 'd3force' },
plugins: [
{
type: 'toolbar',
position: 'right-top',
onClick: (item: string, e: MouseEvent) => {
console.log('item clicked:', item, e);
},
getItems: () => {
return [
{ id: 'icon-xinjian', value: 'new' },
{ id: 'icon-fenxiang', value: 'share' },
{ id: 'icon-chexiao', value: 'undo' },
];
},
},
],
});

await graph.render();

return graph;
};
20 changes: 20 additions & 0 deletions packages/g6/__tests__/unit/plugins/toolbar/plugin-toolbar.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { pluginToolbarBuildIn } from '@@/demo/case';
import { createDemoGraph } from '@@/utils';
import { get } from '@antv/util';

describe('plugin toolbar', () => {
it('toolbar', async () => {
const graph = await createDemoGraph(pluginToolbarBuildIn);
const container = graph.getCanvas().getContainer()!;

const el = container.querySelector('.g6-toolbar') as HTMLDivElement;

expect(graph.getPlugins().length).toBe(1);
expect(get(graph.getPlugins(), [0, 'position'])).toBe('top-left');

expect(el.querySelectorAll('.g6-toolbar-item').length).toBe(9);

await graph.destroy();
expect(container.querySelector('.g6-toolbar-item')).toBeFalsy();
});
});
63 changes: 63 additions & 0 deletions packages/g6/__tests__/unit/plugins/toolbar/util.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { parsePositionToStyle } from '@/src/plugins/toolbar/util';

describe('util', () => {
it('parsePositionToStyle', () => {
expect(parsePositionToStyle('top-left')).toEqual({
top: '8px',
right: 'unset',
bottom: 'unset',
left: '8px',
flexDirection: 'row',
});
expect(parsePositionToStyle('top-right')).toEqual({
top: '8px',
right: '8px',
bottom: 'unset',
left: 'unset',
flexDirection: 'row',
});
expect(parsePositionToStyle('bottom-left')).toEqual({
top: 'unset',
right: 'unset',
bottom: '8px',
left: '8px',
flexDirection: 'row',
});
expect(parsePositionToStyle('bottom-right')).toEqual({
top: 'unset',
right: '8px',
bottom: '8px',
left: 'unset',
flexDirection: 'row',
});

expect(parsePositionToStyle('left-top')).toEqual({
top: '8px',
right: 'unset',
bottom: 'unset',
left: '8px',
flexDirection: 'column',
});
expect(parsePositionToStyle('right-top')).toEqual({
top: '8px',
right: '8px',
bottom: 'unset',
left: 'unset',
flexDirection: 'column',
});
expect(parsePositionToStyle('left-bottom')).toEqual({
top: 'unset',
right: 'unset',
bottom: '8px',
left: '8px',
flexDirection: 'column',
});
expect(parsePositionToStyle('right-bottom')).toEqual({
top: 'unset',
right: '8px',
bottom: '8px',
left: 'unset',
flexDirection: 'column',
});
});
});
21 changes: 20 additions & 1 deletion packages/g6/__tests__/unit/utils/dom.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createPluginContainer, sizeOf } from '@/src/utils/dom';
import { createPluginContainer, insertDOM, sizeOf } from '@/src/utils/dom';

describe('sizeOf', () => {
it('should return the size of the graph container', () => {
Expand Down Expand Up @@ -37,4 +37,23 @@ describe('sizeOf', () => {
expect(el.style.overflow).not.toBe('hidden');
expect(el.style.pointerEvents).not.toBe('none');
});

it('insertDOM', () => {
insertDOM('g6-test', 'div', { color: 'red' }, 'test', document.body);

let el = document.getElementById('g6-test')!;
expect(el).toBeTruthy();
expect(el.style.color).toBe('red');
expect(el.innerHTML).toBe('test');

insertDOM('g6-test', 'div', { color: 'red' }, 'new html', document.body);

el = document.getElementById('g6-test')!;
expect(el.innerHTML).toBe('new html');

el = insertDOM('g6-test');
expect(el.tagName.toLowerCase()).toBe('div');
expect(el.innerHTML).toBe('');
expect(el.parentNode).toBe(document.body);
});
});
4 changes: 1 addition & 3 deletions packages/g6/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@
"@antv/graphlib": "^2.0.2",
"@antv/hierarchy": "latest",
"@antv/layout": "^1.2.14-beta.1",
"@antv/util": "^3.3.7",
"insert-css": "^2.0.0"
"@antv/util": "^3.3.7"
},
"devDependencies": {
"@antv/g-plugin-3d": "^1.9.34",
Expand All @@ -72,7 +71,6 @@
"@antv/g-webgl": "^1.9.37",
"@antv/layout-gpu": "^1.1.5",
"@antv/layout-wasm": "^1.4.0",
"@types/insert-css": "^2.0.1",
"@types/xmlserializer": "^0.6.6",
"jest-canvas-mock": "^2.5.1",
"jest-random-mock": "^1.0.0",
Expand Down
5 changes: 2 additions & 3 deletions packages/g6/src/plugins/contextmenu.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { insertCss } from 'insert-css';
import type { RuntimeContext } from '../runtime/types';
import type { ElementEvent } from '../types/event';
import type { Item } from '../utils/contextmenu';
import { CONTEXTMENU_CSS, getContentFromItems } from '../utils/contextmenu';
import { createPluginContainer } from '../utils/dom';
import { createPluginContainer, insertDOM } from '../utils/dom';
import type { BasePluginOptions } from './base-plugin';
import { BasePlugin } from './base-plugin';

Expand Down Expand Up @@ -77,7 +76,7 @@ export class Contextmenu extends BasePlugin<ContextmenuOptions> {
$container!.appendChild(this.$element);

// 设置样式
insertCss(CONTEXTMENU_CSS);
insertDOM('g6-contextmenu-css', 'style', {}, CONTEXTMENU_CSS, document.head);

this.update(options);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/g6/src/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
export { BasePlugin } from './base-plugin';
export { Contextmenu } from './contextmenu';
export { GridLine } from './grid-line';
export { Toolbar } from './toolbar';
export { Tooltip } from './tooltip';
export { Watermark } from './watermark';

export type { BasePluginOptions } from './base-plugin';
export type { ContextmenuOptions } from './contextmenu';
export type { GridLineOptions } from './grid-line';
export type { ToolbarOptions } from './toolbar';
export type { TooltipOptions } from './tooltip';
export type { WatermarkOptions } from './watermark';
Loading

0 comments on commit fff59f2

Please sign in to comment.