Skip to content

Commit

Permalink
refactor: toDataURL support export overall mode (#5648)
Browse files Browse the repository at this point in the history
* feat(canvas): toDataURL support by overall graph

* test: update snapshots

* test: add test case

* refactor: adjust code
  • Loading branch information
Aarebecca authored Apr 16, 2024
1 parent cd073f7 commit 65425ea
Show file tree
Hide file tree
Showing 15 changed files with 83 additions and 25 deletions.
11 changes: 8 additions & 3 deletions packages/g6/__tests__/demos/graph-to-data-url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ export const graphToDataURL: TestCase = async (context) => {
graphToDataURL.form = (panel) => {
const config = {
toDataURL: () => {
graph.toDataURL().then((url) => {
graph.toDataURL({ mode: config.mode } as any).then((url) => {
navigator.clipboard.writeText(url);
alert('The data URL has been copied to the clipboard');
});
},
mode: 'viewport',
download: async () => {
const dataURL = await graph.toDataURL();
const dataURL = await graph.toDataURL({ mode: config.mode } as any);
const [head, content] = dataURL.split(',');
const contentType = head.match(/:(.*?);/)![1];

Expand All @@ -43,7 +44,11 @@ export const graphToDataURL: TestCase = async (context) => {
a.click();
},
};
return [panel.add(config, 'toDataURL'), panel.add(config, 'download').name('Download')];
return [
panel.add(config, 'toDataURL'),
panel.add(config, 'mode', ['viewport', 'overall']),
panel.add(config, 'download').name('Download'),
];
};

await graph.render();
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/g6/__tests__/snapshots/layouts/mindmap/h-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/g6/__tests__/snapshots/plugins/tooltip/edge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/g6/__tests__/snapshots/plugins/tooltip/hover.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/g6/__tests__/snapshots/plugins/tooltip/node.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions packages/g6/__tests__/unit/runtime/graph/graph.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,10 @@ describe('Graph', () => {
});

it('toDataURL', async () => {
const url = await graph.toDataURL();
expect(url).toBeDefined();
expect(await graph.toDataURL()).toBeDefined();
expect(await graph.toDataURL({ mode: 'overall' })).toBeDefined();
expect((await graph.toDataURL({ type: 'image/jpeg' })).startsWith('data:image/jpeg')).toBe(true);
expect((await graph.toDataURL({ type: 'image/png' })).startsWith('data:image/png')).toBe(true);
});

it('resize', () => {
Expand Down
51 changes: 43 additions & 8 deletions packages/g6/src/runtime/canvas.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type {
Cursor,
DataURLOptions,
DisplayObject,
CanvasConfig as GCanvasConfig,
DataURLOptions as GDataURLOptions,
IAnimation,
IRenderer,
PointLike,
Expand All @@ -13,14 +13,27 @@ import { Plugin as DragNDropPlugin } from '@antv/g-plugin-dragndrop';
import { createDOM, isFunction, isString } from '@antv/util';
import type { CanvasOptions } from '../spec/canvas';
import type { CanvasLayer } from '../types/canvas';
import { getCombinedBBox } from '../utils/bbox';
import { getBBoxSize, getCombinedBBox } from '../utils/bbox';

export interface CanvasConfig
extends Pick<GCanvasConfig, 'container' | 'devicePixelRatio' | 'width' | 'height' | 'cursor'> {
renderer?: CanvasOptions['renderer'];
background?: string;
}

export interface DataURLOptions extends GDataURLOptions {
/**
* <zh/> 导出模式
* - viewport: 导出视口内容
* - overall: 导出整个画布
*
* <en/> export mode
* - viewport: export the content of the viewport
* - overall: export the entire canvas
*/
mode?: 'viewport' | 'overall';
}

/**
* @deprecated this canvas will be replace by layered canvas
*/
Expand Down Expand Up @@ -173,7 +186,7 @@ export class Canvas {
Object.values(this.canvas)
.map((canvas) => canvas.document.documentElement)
.filter((el) => el.childNodes.length > 0)
.map((el) => el.getBounds()),
.map((el) => el.getRenderBounds()),
);
}

Expand Down Expand Up @@ -211,7 +224,21 @@ export class Canvas {

public async toDataURL(options: Partial<DataURLOptions> = {}) {
const devicePixelRatio = window.devicePixelRatio || 1;
const { width, height } = this.config;
const { mode = 'viewport', ...restOptions } = options;

let startX = 0;
let startY = 0;
let width = 0;
let height = 0;

if (mode === 'viewport') {
[width, height] = [this.config.width || 0, this.config.height || 0];
} else if (mode === 'overall') {
const bounds = this.getBounds();
const size = getBBoxSize(bounds);
[startX, startY] = bounds.min;
[width, height] = size;
}

const container: HTMLElement = createDOM('<div id="virtual-image"></div>');

Expand Down Expand Up @@ -244,15 +271,23 @@ export class Canvas {

const camera = this.main.getCamera();
const offscreenCamera = offscreenCanvas.getCamera();
offscreenCamera.setZoom(camera.getZoom());
offscreenCamera.setPosition(camera.getPosition());
offscreenCamera.setFocalPoint(camera.getFocalPoint());

if (mode === 'viewport') {
offscreenCamera.setZoom(camera.getZoom());
offscreenCamera.setPosition(camera.getPosition());
offscreenCamera.setFocalPoint(camera.getFocalPoint());
} else if (mode === 'overall') {
const [x, y, z] = offscreenCamera.getPosition();
const [fx, fy, fz] = offscreenCamera.getFocalPoint();
offscreenCamera.setPosition([x + startX, y + startY, z]);
offscreenCamera.setFocalPoint([fx + startX, fy + startY, fz]);
}

const contextService = offscreenCanvas.getContextService();

return new Promise<string>((resolve) => {
offscreenCanvas.on(CanvasEvent.AFTER_RENDER, async () => {
const url = await contextService.toDataURL(options);
const url = await contextService.toDataURL(restOptions);
resolve(url);
});
});
Expand Down
18 changes: 17 additions & 1 deletion packages/g6/src/runtime/graph.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import EventEmitter from '@antv/event-emitter';
import type { AABB, BaseStyleProps, DataURLOptions } from '@antv/g';
import type { AABB, BaseStyleProps } from '@antv/g';
import type { ID } from '@antv/graphlib';
import { debounce, isEqual, isFunction, isNumber, isObject, isString, omit } from '@antv/util';
import { COMBO_KEY, GraphEvent } from '../constants';
Expand Down Expand Up @@ -49,6 +49,7 @@ import { zIndexOf } from '../utils/style';
import { subtract } from '../utils/vector';
import { BatchController } from './batch';
import { BehaviorController } from './behavior';
import type { DataURLOptions } from './canvas';
import { Canvas } from './canvas';
import type { HierarchyKey } from './data';
import { DataController } from './data';
Expand Down Expand Up @@ -1051,6 +1052,21 @@ export class Graph extends EventEmitter {
else if (elementType === 'combo') this.updateComboData([{ id, style: { collapsed } }]);
}

/**
* <zh/> 导出画布内容为 DataURL
*
* <en/> Export canvas content as DataURL
* @param options - <zh/> 导出配置 | <en/> export configuration
* @param mode
* <zh/> 导出模式
* - viewport: 导出视口内容
* - overall: 导出整个画布
*
* <en/> export mode
* - viewport: export the content of the viewport
* - overall: export the entire canvas
* @returns <zh/> DataURL | <en/> DataURL
*/
public async toDataURL(options: Partial<DataURLOptions> = {}): Promise<string> {
return this.context.canvas!.toDataURL(options);
}
Expand Down

0 comments on commit 65425ea

Please sign in to comment.