import { injectable, inject } from 'inversify'; import EventEmitter from '@antv/event-emitter'; import { FACTORY } from '../../constants'; import { Component, ComponentConfig, ComponentPlugin } from '../component'; import { generateUuid } from '../utils'; import { CANVAS_EVENT } from './constants'; import type { Layouts } from '../app'; import type { CanvasConfig } from './types'; @injectable() export class Canvas extends EventEmitter { config: CanvasConfig; components: Component[]; focusedComponent: Component; @inject(FACTORY.Component) private _createComponent: (config: ComponentConfig) => Component; init(config: CanvasConfig) { this.config = config; this.components = config.components.map((componentConfig) => this._createComponent(componentConfig)); } addComponent(componentPlugin: ComponentPlugin): ComponentConfig['id'] { const component = this._createComponent({ id: generateUuid('component'), type: componentPlugin.type, datasetId: '', config: {}, layout: { x: 0, y: 0, w: 1, h: 1 }, }); this.components.push(component); this.emit(CANVAS_EVENT.AddComponent, component); return component.config.id; } get layouts(): Layouts { return this.components.map((component) => ({ i: component.config.id, ...component.config.layout, // Set maxH to avoid height being expanded maxH: 12, })); } set layouts(newLayouts: Layouts) { newLayouts.forEach((newLayout) => { this.components.forEach((component) => { if (newLayout.i === component.config.id) { const { x, y, w, h } = newLayout; component.config.layout = { x, y, w, h, }; } }); }); this.emit(CANVAS_EVENT.UpdateLayouts); } getAllDataset() { this.components.forEach((component) => { component.getDataset(); }); } focusComponent(componentId: string) { this.components.forEach((component) => { if (component.config.id === componentId) { this.focusedComponent = component; component.focus(); this.emit(CANVAS_EVENT.FocusComponent); } else { component.blur(); } }); } blurComponent() { this.components.forEach((component) => { component.blur(); }); this.emit(CANVAS_EVENT.BlurComponent); this.focusedComponent = null; } }