@devexperts/dxcharts-lite
Version:
225 lines (224 loc) • 7.27 kB
JavaScript
/*
* 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();
}
}