mirror of
https://gitee.com/antv/g6.git
synced 2024-12-02 11:48:29 +08:00
feat: add autoResize option on graph (#5362)
* feat: add autoResize option on graph * test: add test cases
This commit is contained in:
parent
08de942823
commit
bb847876c3
@ -5,6 +5,7 @@ import { GraphChange, ID } from '@antv/graphlib';
|
||||
import {
|
||||
clone,
|
||||
createDOM,
|
||||
debounce,
|
||||
groupBy,
|
||||
isArray,
|
||||
isEmpty,
|
||||
@ -35,6 +36,7 @@ import { FitViewRules, GraphTransformOptions } from '../types/view';
|
||||
import { getCombinedCanvasesBounds } from '../utils/bbox';
|
||||
import { changeRenderer, createCanvas } from '../utils/canvas';
|
||||
import { cloneJSON, isEmptyGraph } from '../utils/data';
|
||||
import { sizeOf } from '../utils/dom';
|
||||
import { error, warn } from '../utils/invariant';
|
||||
import { getLayoutBounds } from '../utils/layout';
|
||||
import { formatPadding } from '../utils/shape';
|
||||
@ -79,7 +81,7 @@ export class Graph<B extends BehaviorRegistry = any, T extends ThemeSolverRegist
|
||||
private themeController: ThemeController;
|
||||
private pluginController: PluginController;
|
||||
|
||||
private defaultSpecification = {
|
||||
private defaultSpecification: Specification = {
|
||||
theme: {
|
||||
type: 'spec',
|
||||
base: 'light',
|
||||
@ -109,6 +111,9 @@ export class Graph<B extends BehaviorRegistry = any, T extends ThemeSolverRegist
|
||||
// TODO: handle multiple type data configs
|
||||
this.read(data as GraphData);
|
||||
}
|
||||
|
||||
// Listening window.resize to autoResize.
|
||||
this.specification.autoResize && window.addEventListener('resize', this.onResize);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2530,6 +2535,16 @@ export class Graph<B extends BehaviorRegistry = any, T extends ThemeSolverRegist
|
||||
// this.themeController.destroy();
|
||||
// this.itemController.destroy();
|
||||
|
||||
window.removeEventListener('resize', this.onResize);
|
||||
|
||||
this.destroyed = true;
|
||||
}
|
||||
|
||||
private onResize = debounce(() => {
|
||||
const { width, height } = this.specification;
|
||||
const [w, h] = sizeOf(this.container);
|
||||
if (width !== w || height !== h) {
|
||||
this.setSize([w, h]);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
@ -26,6 +26,10 @@ export interface Specification<B extends BehaviorRegistry, T extends ThemeSolver
|
||||
transientLabelCanvas?: Canvas;
|
||||
width?: number;
|
||||
height?: number;
|
||||
/**
|
||||
* Auto resize canvas by listening `resize` event. Default is False.
|
||||
*/
|
||||
autoResize?: boolean;
|
||||
renderer?:
|
||||
| RendererName
|
||||
| {
|
||||
|
44
packages/g6/src/utils/dom.ts
Normal file
44
packages/g6/src/utils/dom.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { isNumber } from '@antv/util';
|
||||
|
||||
const parseInt10 = (d: string) => (d ? parseInt(d) : 0);
|
||||
|
||||
/**
|
||||
* Get the container's bounding size.
|
||||
* @param container dom element.
|
||||
* @returns the container width and height
|
||||
*/
|
||||
function getContainerSize(container: HTMLElement): [number, number] {
|
||||
const style = getComputedStyle(container);
|
||||
|
||||
const wrapperWidth = container.clientWidth || parseInt10(style.width);
|
||||
const wrapperHeight = container.clientHeight || parseInt10(style.height);
|
||||
|
||||
const widthPadding = parseInt10(style.paddingLeft) + parseInt10(style.paddingRight);
|
||||
const heightPadding = parseInt10(style.paddingTop) + parseInt10(style.paddingBottom);
|
||||
|
||||
return [wrapperWidth - widthPadding, wrapperHeight - heightPadding];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of Graph.
|
||||
* @param container container of Graph
|
||||
* @returns Size of Graph
|
||||
*/
|
||||
export function sizeOf(container: HTMLElement): [number, number] {
|
||||
let effectiveWidth = 640;
|
||||
let effectiveHeight = 480;
|
||||
|
||||
const [containerWidth, containerHeight] = getContainerSize(container);
|
||||
effectiveWidth = containerWidth || effectiveWidth;
|
||||
effectiveHeight = containerHeight || effectiveHeight;
|
||||
|
||||
/** Minimum width */
|
||||
const MIN_CHART_WIDTH = 1;
|
||||
/** Minimum height */
|
||||
const MIN_CHART_HEIGHT = 1;
|
||||
|
||||
return [
|
||||
Math.max(isNumber(effectiveWidth) ? effectiveWidth : MIN_CHART_WIDTH, MIN_CHART_WIDTH),
|
||||
Math.max(isNumber(effectiveHeight) ? effectiveHeight : MIN_CHART_HEIGHT, MIN_CHART_HEIGHT),
|
||||
];
|
||||
}
|
52
packages/g6/tests/integration/auto-resize.spec.ts
Normal file
52
packages/g6/tests/integration/auto-resize.spec.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { Graph } from '../../src';
|
||||
import { createContext, sleep } from './utils';
|
||||
import './utils/useSnapshotMatchers';
|
||||
|
||||
const dir = `${__dirname}/snapshots/auto-resize`;
|
||||
|
||||
describe('Auto Resize', () => {
|
||||
it('autoResize trigger by window.resize', (done) => {
|
||||
const { backgroundCanvas, canvas, container, labelCanvas, transientCanvas, transientLabelCanvas } = createContext(
|
||||
500,
|
||||
500,
|
||||
);
|
||||
|
||||
const graph = new Graph({
|
||||
width: 500,
|
||||
height: 500,
|
||||
autoResize: true,
|
||||
container,
|
||||
backgroundCanvas,
|
||||
canvas,
|
||||
labelCanvas,
|
||||
transientCanvas,
|
||||
transientLabelCanvas,
|
||||
layout: {
|
||||
type: 'grid',
|
||||
},
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', data: {} },
|
||||
{ id: 'node2', data: {} },
|
||||
{ id: 'node3', data: {} },
|
||||
{ id: 'node4', data: {} },
|
||||
],
|
||||
edges: [{ id: 'edge1', source: 'node1', target: 'node2', data: {} }],
|
||||
},
|
||||
});
|
||||
|
||||
graph.on('afterlayout', async () => {
|
||||
container.style.display = 'block';
|
||||
container.style.width = '400px';
|
||||
container.style.height = '400px';
|
||||
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
|
||||
await sleep(500); // auto resize debounce is 300ms.
|
||||
await expect(canvas).toMatchSVGSnapshot(dir, 'auto-resize');
|
||||
|
||||
graph.destroy();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,95 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="400"
|
||||
height="400"
|
||||
style="background: transparent; position: absolute; outline: none;"
|
||||
color-interpolation-filters="sRGB"
|
||||
tabindex="1"
|
||||
>
|
||||
<defs />
|
||||
<g id="g-svg-camera" transform="matrix(1,0,0,1,0,0)">
|
||||
<g id="g-root" fill="none" transform="matrix(1,0,0,1,0,0)">
|
||||
<g id="combo-group" fill="none" transform="matrix(1,0,0,1,0,0)" />
|
||||
<g id="edge-group" fill="none" transform="matrix(1,0,0,1,0,0)">
|
||||
<g id="g-svg-24" fill="none" transform="matrix(1,0,0,1,0,0)">
|
||||
<g transform="matrix(1,0,0,1,141,125)">
|
||||
<line
|
||||
id="keyShape"
|
||||
fill="none"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="218"
|
||||
y2="0"
|
||||
stroke-width="1"
|
||||
stroke="rgba(153,173,209,1)"
|
||||
/>
|
||||
<line
|
||||
id="keyShape"
|
||||
fill="none"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="0"
|
||||
y2="0"
|
||||
stroke-width="3"
|
||||
stroke="transparent"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="node-group" fill="none" transform="matrix(1,0,0,1,0,0)">
|
||||
<g id="g-svg-12" fill="none" transform="matrix(1,0,0,1,125,125)">
|
||||
<g transform="matrix(1,0,0,1,0,0)">
|
||||
<circle
|
||||
id="keyShape"
|
||||
fill="rgba(34,126,255,1)"
|
||||
transform="translate(-16,-16)"
|
||||
cx="16"
|
||||
cy="16"
|
||||
r="16"
|
||||
stroke-width="0"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="g-svg-15" fill="none" transform="matrix(1,0,0,1,375,125)">
|
||||
<g transform="matrix(1,0,0,1,0,0)">
|
||||
<circle
|
||||
id="keyShape"
|
||||
fill="rgba(34,126,255,1)"
|
||||
transform="translate(-16,-16)"
|
||||
cx="16"
|
||||
cy="16"
|
||||
r="16"
|
||||
stroke-width="0"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="g-svg-18" fill="none" transform="matrix(1,0,0,1,125,375)">
|
||||
<g transform="matrix(1,0,0,1,0,0)">
|
||||
<circle
|
||||
id="keyShape"
|
||||
fill="rgba(34,126,255,1)"
|
||||
transform="translate(-16,-16)"
|
||||
cx="16"
|
||||
cy="16"
|
||||
r="16"
|
||||
stroke-width="0"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="g-svg-21" fill="none" transform="matrix(1,0,0,1,375,375)">
|
||||
<g transform="matrix(1,0,0,1,0,0)">
|
||||
<circle
|
||||
id="keyShape"
|
||||
fill="rgba(34,126,255,1)"
|
||||
transform="translate(-16,-16)"
|
||||
cx="16"
|
||||
cy="16"
|
||||
r="16"
|
||||
stroke-width="0"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
Loading…
Reference in New Issue
Block a user