feat: support tile size configuring

This commit is contained in:
Yanyan-Wang 2023-09-12 09:43:51 +08:00
parent b5af9c4894
commit e7d984bbd2
7 changed files with 77 additions and 39 deletions

View File

@ -214,9 +214,12 @@ export class ItemController {
graphCore: GraphCore;
theme: ThemeSpecification;
transientCanvas: Canvas;
tileOptimize?: {
tileFirstRender?: boolean | number;
tileFirstRenderSize?: number;
};
}) {
const { graphCore, theme = {}, transientCanvas, tileFirstRender } = param;
const { graphCore, theme = {}, transientCanvas, tileOptimize = {} } = param;
const { graph } = this;
// 0. clear groups on canvas, and create new groups
@ -269,9 +272,9 @@ export class ItemController {
edges: graphCore.getAllEdges(),
});
await this.renderNodes(nodes, theme.node, tileFirstRender);
await this.renderNodes(nodes, theme.node, tileOptimize);
this.renderCombos(combos, theme.combo, graphCore);
await this.renderEdges(edges, theme.edge, tileFirstRender);
await this.renderEdges(edges, theme.edge, tileOptimize);
this.sortByComboTree(graphCore);
// collapse the combos which has 'collapsed' in initial data
if (graphCore.hasTreeStructure('combo')) {
@ -1016,10 +1019,14 @@ export class ItemController {
private async renderNodes(
models: NodeModel[],
nodeTheme: NodeThemeSpecifications = {},
tileFirstRender?: boolean | number,
tileOptimize?: {
tileFirstRender?: boolean | number;
tileFirstRenderSize?: number;
},
): Promise<any> {
const { nodeExtensions, nodeGroup, nodeDataTypeSet, graph } = this;
const { dataTypeField = '' } = nodeTheme;
const { tileFirstRender, tileFirstRenderSize = 1000 } = tileOptimize || {};
const zoom = graph.getZoom();
const delayFirstDraw = isNumber(tileFirstRender)
? models.length > tileFirstRender
@ -1072,11 +1079,13 @@ export class ItemController {
});
if (delayFirstDraw) {
let requestId;
const size = 1000;
const items = itemsInView.concat(itemsOutView);
const sectionNum = Math.ceil(items.length / size);
const sectionNum = Math.ceil(items.length / tileFirstRenderSize);
const sections = Array.from({ length: sectionNum }, (v, i) =>
items.slice(i * size, i * size + size),
items.slice(
i * tileFirstRenderSize,
i * tileFirstRenderSize + tileFirstRenderSize,
),
);
const update = (resolve) => {
if (!sections.length) {
@ -1175,10 +1184,14 @@ export class ItemController {
private renderEdges(
models: EdgeModel[],
edgeTheme: EdgeThemeSpecifications = {},
tileFirstRender?: boolean | number,
tileOptimize?: {
tileFirstRender?: boolean | number;
tileFirstRenderSize?: number;
},
) {
const { edgeExtensions, edgeGroup, itemMap, edgeDataTypeSet, graph } = this;
const { dataTypeField = '' } = edgeTheme;
const { tileFirstRender, tileFirstRenderSize = 1000 } = tileOptimize || {};
const zoom = graph.getZoom();
const nodeMap = filterItemMapByType(itemMap, 'node') as Map<ID, Node>;
const delayFirstDraw = isNumber(tileFirstRender)
@ -1235,10 +1248,12 @@ export class ItemController {
if (delayFirstDraw) {
let requestId;
const size = 2000;
const sectionNum = Math.ceil(items.length / size);
const sectionNum = Math.ceil(items.length / tileFirstRenderSize);
const sections = Array.from({ length: sectionNum }, (v, i) =>
items.slice(i * size, i * size + size),
items.slice(
i * tileFirstRenderSize,
i * tileFirstRenderSize + tileFirstRenderSize,
),
);
const update = (resolve) => {
if (!sections.length) {

View File

@ -364,8 +364,10 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
return {
...spec,
optimize: {
behavior: 2000,
tileBehavior: 2000,
tileBehaviorSize: 1000,
tileFirstRender: 10000,
tileFirstRenderSize: 1000,
...spec.optimize,
},
};
@ -418,14 +420,18 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
* @group Data
*/
public async read(data: DataConfig) {
const { tileFirstRender } = this.specification.optimize || {};
const { tileFirstRender, tileFirstRenderSize } =
this.specification.optimize || {};
this.hooks.datachange.emit({ data, type: 'replace' });
const emitRender = async () => {
await this.hooks.render.emitLinearAsync({
graphCore: this.dataController.graphCore,
theme: this.themeController.specification,
transientCanvas: this.transientCanvas,
tileOptimize: {
tileFirstRender,
tileFirstRenderSize,
},
});
this.emit('afterrender');
@ -474,13 +480,17 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
data: DataConfig,
type: 'replace' | 'mergeReplace' = 'mergeReplace',
) {
const { tileFirstRender } = this.specification.optimize || {};
const { tileFirstRender, tileFirstRenderSize } =
this.specification.optimize || {};
this.hooks.datachange.emit({ data, type });
this.hooks.render.emit({
graphCore: this.dataController.graphCore,
theme: this.themeController.specification,
transientCanvas: this.transientCanvas,
tileOptimize: {
tileFirstRender,
tileFirstRenderSize,
},
});
this.emit('afterrender');

View File

@ -134,7 +134,7 @@ export class DragCanvas extends Behavior {
private hideShapes() {
const { graph } = this;
const { behavior: graphBehaviorOptimize } =
const { tileBehavior: graphBehaviorOptimize, tileBehaviorSize = 1000 } =
graph.getSpecification().optimize || {};
const optimize = this.options.enableOptimize || graphBehaviorOptimize;
const shouldOptimize = isNumber(optimize)
@ -152,10 +152,12 @@ export class DragCanvas extends Behavior {
.filter((id) => graph.getItemVisible(id) === true);
let requestId;
const hiddenIds = [...this.hiddenNodeIds];
const size = 1000;
const sectionNum = Math.ceil(hiddenIds.length / size);
const sectionNum = Math.ceil(hiddenIds.length / tileBehaviorSize);
const sections = Array.from({ length: sectionNum }, (v, i) =>
hiddenIds.slice(i * size, i * size + size),
hiddenIds.slice(
i * tileBehaviorSize,
i * tileBehaviorSize + tileBehaviorSize,
),
);
const update = () => {
if (!sections.length) {
@ -260,7 +262,7 @@ export class DragCanvas extends Behavior {
this.dragging = false;
const { graph, hiddenNodeIds, hiddenEdgeIds = [] } = this;
const { behavior: graphBehaviorOptimize } =
const { tileBehavior: graphBehaviorOptimize, tileBehaviorSize = 1000 } =
graph.getSpecification().optimize || {};
const optimize = this.options.enableOptimize || graphBehaviorOptimize;
const shouldOptimize = isNumber(optimize)
@ -271,10 +273,12 @@ export class DragCanvas extends Behavior {
if (hiddenNodeIds) {
let requestId;
const hiddenIds = [...hiddenNodeIds, ...hiddenEdgeIds];
const size = 1000;
const sectionNum = Math.ceil(hiddenIds.length / size);
const sectionNum = Math.ceil(hiddenIds.length / tileBehaviorSize);
const sections = Array.from({ length: sectionNum }, (v, i) =>
hiddenIds.slice(i * size, i * size + size),
hiddenIds.slice(
i * tileBehaviorSize,
i * tileBehaviorSize + tileBehaviorSize,
),
);
const update = () => {
if (!sections.length) {

View File

@ -115,7 +115,7 @@ export class ZoomCanvas extends Behavior {
private hideShapes() {
const { graph } = this;
const { behavior: graphBehaviorOptimize } =
const { tileBehavior: graphBehaviorOptimize, tileBehaviorSize = 1000 } =
graph.getSpecification().optimize || {};
const optimize = this.options.enableOptimize || graphBehaviorOptimize;
const shouldOptimzie = isNumber(optimize)
@ -133,10 +133,12 @@ export class ZoomCanvas extends Behavior {
let requestId;
const hiddenIds = [...this.hiddenNodeIds];
const size = 1000;
const sectionNum = Math.ceil(hiddenIds.length / size);
const sectionNum = Math.ceil(hiddenIds.length / tileBehaviorSize);
const sections = Array.from({ length: sectionNum }, (v, i) =>
hiddenIds.slice(i * size, i * size + size),
hiddenIds.slice(
i * tileBehaviorSize,
i * tileBehaviorSize + tileBehaviorSize,
),
);
const update = () => {
if (!sections.length) {
@ -155,7 +157,7 @@ export class ZoomCanvas extends Behavior {
private endZoom() {
const { graph, hiddenEdgeIds = [], hiddenNodeIds } = this;
const { behavior: graphBehaviorOptimize } =
const { tileBehavior: graphBehaviorOptimize, tileBehaviorSize = 1000 } =
graph.getSpecification().optimize || {};
const optimize = this.options.enableOptimize || graphBehaviorOptimize;
const shouldOptimzie = isNumber(optimize)
@ -166,10 +168,12 @@ export class ZoomCanvas extends Behavior {
if (hiddenNodeIds) {
let requestId;
const hiddenIds = [...hiddenNodeIds, ...hiddenEdgeIds];
const size = 1000;
const sectionNum = Math.ceil(hiddenIds.length / size);
const sectionNum = Math.ceil(hiddenIds.length / tileBehaviorSize);
const sections = Array.from({ length: sectionNum }, (v, i) =>
hiddenIds.slice(i * size, i * size + size),
hiddenIds.slice(
i * tileBehaviorSize,
i * tileBehaviorSize + tileBehaviorSize,
),
);
const update = () => {
if (!sections.length) {

View File

@ -5,14 +5,14 @@ import { Command } from '../stdlib/plugin/history/command';
import { Hooks } from '../types/hook';
import { CameraAnimationOptions } from './animate';
import { BehaviorOptionsOf, BehaviorRegistry } from './behavior';
import { ComboDisplayModel, ComboModel, ComboUserModel } from './combo';
import { ComboModel, ComboUserModel } from './combo';
import { Padding, Point } from './common';
import { GraphData } from './data';
import { EdgeDisplayModel, EdgeModel, EdgeUserModel } from './edge';
import { EdgeModel, EdgeUserModel } from './edge';
import type { StackType } from './history';
import { ITEM_TYPE, SHAPE_TYPE } from './item';
import { LayoutOptions } from './layout';
import { NodeDisplayModel, NodeModel, NodeUserModel } from './node';
import { NodeModel, NodeUserModel } from './node';
import { RendererName } from './render';
import { Specification } from './spec';
import { ThemeOptionsOf, ThemeRegistry } from './theme';

View File

@ -53,7 +53,10 @@ export interface Hooks {
graphCore: GraphCore;
theme: ThemeSpecification;
transientCanvas: Canvas;
tileFirstRender?: number | boolean;
tileOptimize?: {
tileFirstRender?: boolean | number;
tileFirstRenderSize?: number;
};
}>; // TODO: define param template
layout: IHook<{
graphCore: GraphCore;

View File

@ -48,8 +48,10 @@ export interface Specification<
};
zoom?: number;
optimize?: {
tileFirstRender: boolean | number;
behavior: boolean | number;
tileFirstRender?: boolean | number;
tileFirstRenderSize?: number;
tileBehavior?: boolean | number;
tileBehaviorSize?: number;
};
autoFit?:
| 'view'