UNPKG

@gravity-ui/graph

Version:

Modern graph editor component

120 lines (119 loc) 4.96 kB
import { batch } from "@preact/signals-core"; import { selectBlockById } from "../store/block/selectors"; import { selectConnectionById } from "../store/connection/selectors"; import { getUsableRectByBlockIds, startAnimation } from "../utils/functions"; import { ESelectionStrategy } from "../utils/types/types"; export class PublicGraphApi { constructor(graph) { this.graph = graph; // noop } zoomToBlocks(blockIds, zoomConfig) { const blocksRect = getUsableRectByBlockIds(this.graph.rootStore.blocksList.$blocks.value, blockIds); this.zoomToRect(blocksRect, zoomConfig); } /** * Zooms to fit all blocks in the viewport. This method is asynchronous and waits * for the usableRect to be ready before performing the zoom operation. * * @param zoomConfig - Configuration for zoom transition and padding * @returns Promise that resolves when zoom operation is complete */ zoomToViewPort(zoomConfig) { this.graph.hitTest.waitUsableRectUpdate((rect) => { this.zoomToRect(rect, zoomConfig); }); } zoomToRect(rect, zoomConfig) { const transition = zoomConfig?.transition || 0; const padding = zoomConfig?.padding || 0; const cameraRectInit = this.graph.cameraService.getCameraRect(); const cameraScaleInit = this.graph.cameraService.getCameraScale(); const endScale = this.graph.cameraService.getScaleRelativeDimensions(rect.width + padding * 2, rect.height + padding * 2); const xyPosition = this.graph.cameraService.getXYRelativeCenterDimensions({ x: rect.x - padding, y: rect.y - padding, width: rect.width + padding * 2, height: rect.height + padding * 2, }, endScale); if (!transition) { this.graph.cameraService.set({ ...xyPosition, scale: endScale }); return; } startAnimation(transition, (progress) => { const x = cameraRectInit.x + (xyPosition.x - cameraRectInit.x) * progress; const y = cameraRectInit.y + (xyPosition.y - cameraRectInit.y) * progress; const scale = cameraScaleInit + (endScale - cameraScaleInit) * progress; this.graph.cameraService.set({ x, y, scale }); }); } getGraphColors() { return this.graph.graphColors; } updateGraphColors(colors) { this.graph.setColors(colors); } getGraphConstants() { return this.graph.graphConstants; } updateGraphConstants(constants) { this.graph.setConstants(constants); } isGraphEmpty() { return this.graph.rootStore.blocksList.$blocksMap.value.size === 0; } setSetting(flagPath, value) { this.graph.rootStore.settings.setConfigFlag(flagPath, value); } setCurrentConfigurationName(newName) { this.graph.rootStore.configurationName = newName; } deleteSelected() { batch(() => { this.graph.rootStore.connectionsList.deleteSelectedConnections(); this.graph.rootStore.blocksList.deleteSelectedBlocks(); }); } selectBlocks(blockIds, selected, strategy = ESelectionStrategy.REPLACE) { this.graph.rootStore.blocksList.updateBlocksSelection(blockIds, selected, strategy); } updateBlock(block) { const blockStore = selectBlockById(this.graph, block.id); blockStore?.updateBlock(block); } addBlock(block, selectionOptions) { const newBlockId = this.graph.rootStore.blocksList.addBlock(block); if (selectionOptions !== undefined) { this.graph.rootStore.blocksList.updateBlocksSelection([newBlockId], selectionOptions.selected !== undefined ? selectionOptions.selected : true, selectionOptions.strategy); } return newBlockId; } setAnchorSelection(blockId, anchorId, selected) { this.graph.rootStore.blocksList.setAnchorSelection(blockId, anchorId, selected); } selectConnections(connectionIds, selected, strategy = ESelectionStrategy.REPLACE) { batch(() => { this.graph.rootStore.connectionsList.setConnectionsSelection(connectionIds, selected, strategy); }); } updateConnection(id, connection) { const connectionStore = selectConnectionById(this.graph, id); connectionStore.updateConnection(connection); } addConnection(connection) { return this.graph.rootStore.connectionsList.addConnection(connection); } getBlockById(blockId) { return selectBlockById(this.graph, blockId)?.asTBlock(); } getUsableRect() { return this.graph.hitTest.getUsableRect(); } unsetSelection() { batch(() => { this.graph.rootStore.blocksList.resetSelection(); this.graph.rootStore.groupsList.resetSelection(); this.graph.rootStore.connectionsList.resetSelection(); }); } }