Skip to content

Commit

Permalink
refactor: refactor canvas, support switch renderer (#6034)
Browse files Browse the repository at this point in the history
* chore: update pnpm workspace

* refactor(runtime): refactor canvas, support setRenderer

* refactor(runtime): graph adpat canvas, remove get/set background

* refactor: adjust $layer property

* refactor: refactor fullscreen plugin

* refactor: base-element add context property

* refactor: canvas add getRenderer API
  • Loading branch information
Aarebecca authored Jul 15, 2024
1 parent 5b993b0 commit 0e911c2
Show file tree
Hide file tree
Showing 18 changed files with 210 additions and 291 deletions.
4 changes: 1 addition & 3 deletions packages/cli/template-extension/__tests__/utils/create.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { IRenderer } from '@antv/g';
import { resetEntityCounter } from '@antv/g';
import { Renderer as CanvasRenderer } from '@antv/g-canvas';
import { Renderer as SVGRenderer } from '@antv/g-svg';
Expand Down Expand Up @@ -41,12 +40,11 @@ export function createGraphCanvas(
} as unknown as HTMLCanvasElement;
const context = new OffscreenCanvasContext(offscreenNodeCanvas);

const instance = getRenderer(renderer) as any as IRenderer;
return {
container,
width,
height,
renderer: () => instance,
renderer: () => getRenderer(renderer),
document: container.ownerDocument,
offscreenCanvas: offscreenNodeCanvas,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ export async function toMatchSnapshot(
detail?: string,
options: ToMatchSVGSnapshotOptions = {},
) {
return await toMatchSVGSnapshot(Object.values(graph.getCanvas().canvas), ...getSnapshotDir(dir, detail), options);
return await toMatchSVGSnapshot(
Object.values(graph.getCanvas().getLayers()),
...getSnapshotDir(dir, detail),
options,
);
}

export async function toMatchAnimation(
Expand All @@ -126,7 +130,7 @@ export async function toMatchAnimation(
animation.currentTime = frame;
await sleep(32);
const result = await toMatchSVGSnapshot(
Object.values(graph.getCanvas().canvas),
Object.values(graph.getCanvas().getCanvases().canvas),
...getSnapshotDir(dir, `${detail}-${frame}`),
options,
);
Expand Down
2 changes: 1 addition & 1 deletion packages/g6-extension-3d/src/elements/base-node-3d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export abstract class BaseNode3D<S extends BaseNode3DStyleProps> extends BaseNod
public type = 'node-3d';

protected get plugin() {
const renderer = this.attributes.context!.canvas.renderers['main'];
const renderer = this.context.canvas.getRenderer('main');
const plugin = renderer.getPlugin('device-renderer');
return plugin as unknown as Plugin;
}
Expand Down
8 changes: 4 additions & 4 deletions packages/g6/__tests__/demos/case-indented-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const caseIndentedTree: TestCase = async (context) => {
}

protected get childrenData() {
return this.attributes.context!.model.getChildrenData(this.id);
return this.context!.model.getChildrenData(this.id);
}

protected getKeyStyle(attributes: Required<IndentedNodeStyleProps>): RectStyleProps {
Expand Down Expand Up @@ -147,7 +147,7 @@ export const caseIndentedTree: TestCase = async (context) => {

this.forwardEvent(btn, CommonEvent.CLICK, (event: IPointerEvent) => {
event.stopPropagation();
attributes.context!.graph.emit(TreeEvent.COLLAPSE_EXPAND, {
this.context.graph.emit(TreeEvent.COLLAPSE_EXPAND, {
id: this.id,
collapsed: false,
});
Expand Down Expand Up @@ -184,7 +184,7 @@ export const caseIndentedTree: TestCase = async (context) => {

this.forwardEvent(btn, CommonEvent.CLICK, (event: IPointerEvent) => {
event.stopPropagation();
attributes.context!.graph.emit(TreeEvent.COLLAPSE_EXPAND, {
this.context.graph.emit(TreeEvent.COLLAPSE_EXPAND, {
id: this.id,
collapsed: !attributes.collapsed,
});
Expand Down Expand Up @@ -221,7 +221,7 @@ export const caseIndentedTree: TestCase = async (context) => {

this.forwardEvent(btn, CommonEvent.CLICK, (event: IPointerEvent) => {
event.stopPropagation();
attributes.context!.graph.emit(TreeEvent.ADD_CHILD, { id: this.id });
this.context.graph.emit(TreeEvent.ADD_CHILD, { id: this.id });
});
}

Expand Down
2 changes: 1 addition & 1 deletion packages/g6/__tests__/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ async function render() {
// render
const { Renderer, Demo, Animation, Theme } = options;
const canvas = createGraphCanvas($container, 500, 500, Renderer);
await canvas.init();
await canvas.ready;
const testCase = demos[Demo as keyof typeof demos];
if (!testCase) return;

Expand Down
6 changes: 1 addition & 5 deletions packages/g6/__tests__/unit/runtime/canvas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ import { createGraphCanvas } from '@@/utils';
describe('Canvas', () => {
const svg = createGraphCanvas(null, 500, 500, 'svg');
beforeAll(async () => {
await svg.init();
});

it('getRendererType', () => {
expect(svg.getRendererType()).toBe('svg');
await svg.ready;
});

it('context', () => {
Expand Down
4 changes: 0 additions & 4 deletions packages/g6/__tests__/unit/runtime/graph/graph.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ describe('Graph', () => {
});
});

it('setBackground/getBackground', () => {
expect(graph.getBackground()).toEqual('#ffffff');
});

it('getSize', () => {
expect(graph.getSize()).toEqual([500, 500]);
});
Expand Down
4 changes: 1 addition & 3 deletions packages/g6/__tests__/utils/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Graph } from '@/src';
import { Circle } from '@/src/elements';
import { Canvas } from '@/src/runtime/canvas';
import type { Node, Point } from '@/src/types';
import type { IRenderer } from '@antv/g';
import { resetEntityCounter } from '@antv/g';
import { Renderer as CanvasRenderer } from '@antv/g-canvas';
import { Renderer as SVGRenderer } from '@antv/g-svg';
Expand Down Expand Up @@ -60,12 +59,11 @@ export function createGraphCanvas(
} as unknown as HTMLCanvasElement;
const context = new OffscreenCanvasContext(offscreenNodeCanvas);

const instance = getRenderer(renderer) as any as IRenderer;
return new Canvas({
container,
width,
height,
renderer: () => instance,
renderer: () => getRenderer(renderer),
...extraOptions,
});
}
Expand Down
13 changes: 7 additions & 6 deletions packages/g6/__tests__/utils/to-match-svg-snapshot.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Graph, IAnimateEvent } from '@/src';
import type { CanvasLayer } from '@/src/types';
import type { Canvas, IAnimation } from '@antv/g';
import chalk from 'chalk';
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
Expand All @@ -21,7 +22,7 @@ const formatSVG = (svg: string, keepSVGElementId: boolean) => {

// @see https://jestjs.io/docs/26.x/expect#expectextendmatchers
export async function toMatchSVGSnapshot(
gCanvas: Canvas | Canvas[],
gCanvas: Record<CanvasLayer, Canvas>,
dir: string,
name: string,
options: ToMatchSVGSnapshotOptions = {},
Expand All @@ -32,15 +33,15 @@ export async function toMatchSVGSnapshot(
const namePath = join(dir, name);
const actualPath = join(dir, `${name}-actual.${fileFormat}`);
const expectedPath = join(dir, `${name}.${fileFormat}`);
const gCanvases = Array.isArray(gCanvas) ? gCanvas : [gCanvas];

let actual: string = '';

// Clone <svg>
const svg = (gCanvases[0].getContextService().getDomElement() as unknown as SVGElement).cloneNode(true) as SVGElement;
const svg = (gCanvas.main.getContextService().getDomElement() as unknown as SVGElement).cloneNode(true) as SVGElement;
const gRoot = svg.querySelector('#g-root');

gCanvases.slice(1).forEach((gCanvas) => {
Object.entries(gCanvas).forEach(([key, gCanvas]) => {
if (key === 'main') return;
const dom = (gCanvas.getContextService().getDomElement() as unknown as SVGElement).cloneNode(true) as SVGElement;
// @ts-expect-error dom is SVGElement
gRoot?.append(...(dom.querySelector('#g-root')?.childNodes || []));
Expand Down Expand Up @@ -99,7 +100,7 @@ export async function toMatchSnapshot(
detail?: string,
options: ToMatchSVGSnapshotOptions = {},
) {
return await toMatchSVGSnapshot(Object.values(graph.getCanvas().canvas), ...getSnapshotDir(dir, detail), options);
return await toMatchSVGSnapshot(graph.getCanvas().getLayers(), ...getSnapshotDir(dir, detail), options);
}

export async function toMatchAnimation(
Expand Down Expand Up @@ -127,7 +128,7 @@ export async function toMatchAnimation(

await sleep(32);
const result = await toMatchSVGSnapshot(
Object.values(graph.getCanvas().canvas),
graph.getCanvas().getLayers(),
...getSnapshotDir(dir, `${detail}-${frame}`),
options,
);
Expand Down
3 changes: 1 addition & 2 deletions packages/g6/src/behaviors/drag-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,11 +376,10 @@ export class DragElement extends BaseBehavior<DragElementOptions> {
} else {
this.shadow = new Rect({
style: {
$layer: 'transient',
...shadowStyle,
...positionStyle,
pointerEvents: 'none',
// @ts-expect-error $layer is not in the type definition
$layer: 'transient',
},
});
this.context.canvas.appendChild(this.shadow);
Expand Down
12 changes: 8 additions & 4 deletions packages/g6/src/elements/base-element.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { IAnimation } from '@antv/g';
import { Keyframe } from '../types';
import type { BaseShapeStyleProps } from './shapes';
import type { IAnimation } from '@antv/g';
import type { RuntimeContext } from '../runtime/types';
import type { BaseElementStyleProps, Keyframe } from '../types';
import { BaseShape } from './shapes';

export abstract class BaseElement<T extends BaseShapeStyleProps> extends BaseShape<T> {
export abstract class BaseElement<T extends BaseElementStyleProps> extends BaseShape<T> {
protected get context(): RuntimeContext {
return this.attributes.context!;
}

protected get parsedAttributes() {
return this.attributes as Required<T>;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/g6/src/elements/combos/base-combo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export abstract class BaseCombo<S extends BaseComboStyleProps = BaseComboStylePr
}

protected getComboZIndex(attributes: Required<S>): number {
const ancestors = attributes.context!.model.getAncestorsData(this.id, COMBO_KEY) || [];
const ancestors = this.context.model.getAncestorsData(this.id, COMBO_KEY) || [];
return ancestors.length;
}

Expand Down Expand Up @@ -231,7 +231,7 @@ export abstract class BaseCombo<S extends BaseComboStyleProps = BaseComboStylePr
Object.assign(this.style, comboStyle);
// Sync combo position to model
const { x, y } = comboStyle;
attributes.context!.model.syncComboDatum({ id: this.id, style: { x, y } });
this.context.model.syncComboDatum({ id: this.id, style: { x, y } });
}

public render(attributes: Required<S>, container: Group = this) {
Expand Down
10 changes: 3 additions & 7 deletions packages/g6/src/elements/nodes/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class HTML extends BaseNode<HTMLStyleProps> {
private rootPointerEvent = new FederatedPointerEvent(null);

private get eventService() {
return this.attributes.context!.canvas.context.eventService;
return this.context.canvas.context.eventService;
}

private get events() {
Expand Down Expand Up @@ -105,7 +105,7 @@ export class HTML extends BaseNode<HTMLStyleProps> {
}

private forwardEvents = (nativeEvent: PointerEvent) => {
const canvas = this.attributes.context!.canvas.main;
const canvas = this.context.canvas;
const iCanvas = canvas.context.renderingContext.root!.ownerDocument!.defaultView!;

const normalizedEvents = this.normalizeToPointerEvent(nativeEvent, iCanvas);
Expand Down Expand Up @@ -232,11 +232,7 @@ export class HTML extends BaseNode<HTMLStyleProps> {
let x: number;
let y: number;
const { offsetX, offsetY, clientX, clientY } = nativeEvent;
if (
this.attributes.context?.canvas.main.context.config.supportsCSSTransform &&
!isNil(offsetX) &&
!isNil(offsetY)
) {
if (this.context.canvas.context.config.supportsCSSTransform && !isNil(offsetX) && !isNil(offsetY)) {
x = offsetX;
y = offsetY;
} else {
Expand Down
12 changes: 12 additions & 0 deletions packages/g6/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import '@antv/g';

declare module '@antv/g' {
interface BaseStyleProps {
/**
* <zh/> 图形所在的图层,默认为 'main'。
*
* <en/> The layer where the shape is located, default is 'main'.
*/
$layer?: string;
}
}
17 changes: 16 additions & 1 deletion packages/g6/src/plugins/fullscreen/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ export class Fullscreen extends BasePlugin<FullscreenOptions> {

private shortcut: Shortcut;

private style: HTMLStyleElement;

private $el = this.context.canvas.getContainer()!;

private graphSize: [number, number] = [0, 0];

constructor(context: RuntimeContext, options: FullscreenOptions) {
Expand All @@ -68,7 +71,13 @@ export class Fullscreen extends BasePlugin<FullscreenOptions> {

this.bindEvents();

this.$el.style.backgroundColor = this.context.graph.getBackground()!;
this.style = document.createElement('style');
document.head.appendChild(this.style);
this.style.innerHTML = `
:not(:root):fullscreen::backdrop {
background: transparent;
}
`;
}

private bindEvents() {
Expand Down Expand Up @@ -150,6 +159,12 @@ export class Fullscreen extends BasePlugin<FullscreenOptions> {
super.update(options);
this.bindEvents();
}

public destroy(): void {
this.exit();
this.style.remove();
super.destroy();
}
}

/**
Expand Down
Loading

0 comments on commit 0e911c2

Please sign in to comment.