UNPKG

@devexperts/dxcharts-lite

Version:
225 lines (224 loc) 7.27 kB
/* * Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { BehaviorSubject } from 'rxjs'; import { ChartBaseElement } from '../../model/chart-base-element'; import { LinkedList, ListNode } from '../../utils/linkedList.utils'; export class DynamicObjectsModel extends ChartBaseElement { constructor(canvasModel) { super(); this.canvasModel = canvasModel; this.modelIdToObjectMap = new Map(); this._uniqueObjects = {}; this._objects = new BehaviorSubject({}); } /** * @returns the `DynamicObject` itself and pane `LinkedList` where the object is stored. * */ getObjectInfoById(id) { const obj = this.modelIdToObjectMap.get(id); if (!obj) { return undefined; } const paneId = obj.paneId; const objects = this.objects; const paneList = objects[paneId]; if (!paneList) { return undefined; } return [obj, paneList]; } /** * @returns `DynamicObject` position in associated pane `LinkedList` * @returns `-1` if an object was not found * */ getObjectPosition(id) { const objInfo = this.getObjectInfoById(id); if (!objInfo) { return -1; } const [obj, paneList] = objInfo; const targetNode = new ListNode(obj); return paneList.getNodePosition(targetNode); } /** * Adds an object from outside chart-core into model * @param obj */ addObject(obj) { var _a, _b; const paneId = obj.paneId; const objects = this.objects; const paneList = (_a = objects[paneId]) !== null && _a !== void 0 ? _a : new LinkedList(); if (!Object.keys(objects).find(pane => pane === paneId)) { objects[paneId] = paneList; } paneList.insertAtEnd(obj); this.modelIdToObjectMap.set(obj.id, obj); if (!this.uniqueObjects[paneId]) { this.uniqueObjects[paneId] = new Set(); } this.uniqueObjects[paneId].add((_b = obj.parentId) !== null && _b !== void 0 ? _b : obj.id); this.setDynamicObjects(objects); } /** * Removes an object from model * @param id */ removeObject(id) { var _a; const objInfo = this.getObjectInfoById(id); if (!objInfo) { return; } const [obj, paneList] = objInfo; const targetNode = new ListNode(obj); const targetPos = paneList.getNodePosition(targetNode); paneList.removeAt(targetPos); this.modelIdToObjectMap.delete(id); if (this.uniqueObjects[obj.paneId]) { this.uniqueObjects[obj.paneId].delete((_a = obj.parentId) !== null && _a !== void 0 ? _a : obj.id); } if (paneList.size() === 0) { delete this.objects[obj.paneId]; } this.setDynamicObjects(this.objects); } /** * Updates an object * @param obj */ updateObject(obj) { const objInfo = this.getObjectInfoById(obj.id); if (!objInfo) { return; } const [oldObj] = objInfo; this.removeObject(oldObj.id); this.addObject(obj); } /** * Moves the object inside the associated LinkedList to the specified position */ moveToPosition(id, position) { const objInfo = this.getObjectInfoById(id); if (!objInfo) { return; } const [obj, paneList] = objInfo; const node = new ListNode(obj); const currentPos = paneList.getNodePosition(node); if (currentPos === position) { return; } if (currentPos < position) { paneList.insertAt(position, obj); paneList.removeAt(currentPos); } else { paneList.removeAt(currentPos); paneList.insertAt(position, obj); } this.setDynamicObjects(this.objects); } /** * Moves the object inside the drawing order so it's being drawn before the other elements * @param paneId * @param listNode */ bringToFront(id) { const objInfo = this.getObjectInfoById(id); if (!objInfo) { return; } const [obj, paneList] = objInfo; const targetNode = new ListNode(obj); const targetPos = paneList.getNodePosition(targetNode); if (targetPos >= 0 && targetPos < paneList.size()) { paneList.removeAt(targetPos); paneList.insertAtEnd(obj); this.setDynamicObjects(this.objects); } } /** * Moves the object inside the drawing order so it's being drawn after the other elements * @param paneId * @param listNode */ bringToBack(id) { const objInfo = this.getObjectInfoById(id); if (!objInfo) { return; } const [obj, paneList] = objInfo; const targetNode = new ListNode(obj); const targetPos = paneList.getNodePosition(targetNode); if (targetPos > 0 && targetPos <= paneList.size()) { paneList.removeAt(targetPos); paneList.insertAt(0, obj); this.setDynamicObjects(this.objects); } } /** * Moves the object inside the drawing order so it's being drawn one layer ahead * @param obj * @param paneId */ moveForward(id) { const objInfo = this.getObjectInfoById(id); if (!objInfo) { return; } const [obj, paneList] = objInfo; const targetNode = new ListNode(obj); const targetPos = paneList.getNodePosition(targetNode); if (targetPos >= 0 && targetPos + 1 < paneList.size()) { paneList.removeAt(targetPos); paneList.insertAt(targetPos + 1, obj); this.setDynamicObjects(this.objects); } } /** * Moves the object inside the drawing order so it's being drawn one layer closer to the back * @param obj * @param paneId */ moveBackwards(id) { const objInfo = this.getObjectInfoById(id); if (!objInfo) { return; } const [obj, paneList] = objInfo; const targetNode = new ListNode(obj); const targetPos = paneList.getNodePosition(targetNode); if (targetPos > 0 && targetPos < paneList.size()) { paneList.removeAt(targetPos); paneList.insertAt(targetPos - 1, obj); this.setDynamicObjects(this.objects); } } /** * Getter for the objects */ get objects() { return this._objects.getValue(); } /** * Getter for the unique objects, unique object is an entity which is either dynamic object itself, or its parent */ get uniqueObjects() { return this._uniqueObjects; } /** * Sets the objects * @param objects */ setDynamicObjects(objects) { this._objects.next(objects); this.canvasModel.fireDraw(); } }