nope/resources/ui/graph/helpers/data.handlers.ts

202 lines
5.6 KiB
TypeScript
Raw Normal View History

2020-10-25 20:14:51 +00:00
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-03-12 11:57:20
2020-10-29 18:20:42 +00:00
* @modify date 2020-10-29 09:30:19
2020-10-25 20:14:51 +00:00
* @desc [description]
*/
2020-10-29 18:20:42 +00:00
import { v4 as generateID } from 'uuid';
import { dynamicSort } from '../../../../lib/helpers/arrayMethods';
2020-10-25 20:14:51 +00:00
import { deepClone } from '../../../../lib/helpers/objectMethods';
import { replaceAll } from '../../../../lib/helpers/stringMethods';
2020-10-29 18:20:42 +00:00
import { IBaseEdgeOptions } from '../interfaces/IBaseEdgeOptions';
import { IBaseNodeOptions } from '../interfaces/IBaseNodeOptions';
import { IBaseGraph } from '../interfaces/IGraph';
import { ITemplate } from '../interfaces/ITemplate';
2020-10-25 20:14:51 +00:00
/**
* Function to Adapt the IDS of a Template
* @param template The Template which should be adapted
* @param useExistingNodesForEdges Flag, to determine, whether to use unfound Elements or not
*/
export function adaptIDS<N extends IBaseNodeOptions, E extends IBaseEdgeOptions>(template : ITemplate<N | IBaseNodeOptions, E | IBaseEdgeOptions>, useExistingNodesForEdges = false) {
const ids = {};
const ret = deepClone(template);
for (const node of template.nodes) {
if (!node.id) {
node.id = generateID();
}
ids[node.id] = generateID();
}
const availableIDs = template.nodes.map(node => node.id);
// Extract the IDS of all Subelements
for (const node of template.nodes) {
// Check if the Id is assembled like parent.connector,
// Then, make shure, only the Parent has been removed
for (const id of availableIDs){
if (node.id.startsWith(id)){
ids[node.id] = node.id.replace(id, ids[id]);
break;
}
}
}
if (!useExistingNodesForEdges) {
ret.edges = ret.edges.filter(edge => {
if (ids[edge.from] === undefined || ids[edge.to] === undefined) {
return;
}
return edge;
});
}
// Adapt the Edges
for (const edge of ret.edges) {
edge.id = generateID();
if (!useExistingNodesForEdges && (ids[edge.from] === undefined || ids[edge.to] === undefined)) {
throw Error('Template contains different IDS');
}
if (ids[edge.from]) {
edge.from = ids[edge.from];
}
if (ids[edge.to]) {
edge.to = ids[edge.to];
}
}
// Adapt the Nodes
for (const node of ret.nodes) {
node.id = ids[node.id];
// Replace the Node ID.
if (node.data.path){
node.data.path == replaceAll(node.data.path, node.parent, ids[node.parent])
}
if (node.parent && ids[node.parent] === undefined) {
throw Error('Template contains different IDS')
} else if (node.parent) {
node.parent = ids[node.parent];
}
}
return ret;
}
/**
* Tool To Adapt the Position of a Template
* @param template The Template
* @param pos The Position to Use.
*/
export function adaptPositions<N extends IBaseNodeOptions, E extends IBaseEdgeOptions>(template: ITemplate<N | IBaseNodeOptions,E | IBaseEdgeOptions>, pos: { x: number, y: number }) {
if (template.nodes.length > 0) {
const deltaX = pos.x - template.nodes[0].x;
const deltaY = pos.y - template.nodes[0].y;
for (const node of template.nodes) {
node.x += deltaX;
node.y += deltaY;
}
}
return template;
}
/**
* Function to Flatten nested Data.
* @param options F
*/
export function flattenData<N extends IBaseNodeOptions>(options) {
const list = new Array<{ index: number, element: N }>();
for (const node of options) {
_flattenDataRecursive(node, list, 0);
}
/** Sort the List based on the Porperty */
return list.sort(dynamicSort('index')).map(data => data.element);
}
function _flattenDataRecursive<N extends IBaseNodeOptions, E extends IBaseEdgeOptions>(options, list = new Array<{ index: number, element: IBaseNodeOptions }>(), index = 0) {
/** Check if some Connectors are provided or not */
if (options.connectors) {
for (const connector of options.connectors) {
/** Make shure it is marked as Connector */
connector.isConnector = true;
_flattenDataRecursive(connector, list, index + 1);
}
options.connectors = undefined;
}
if (options.children) {
for (const child of options.children) {
child.parent = options.id;
_flattenDataRecursive(child, list, index + 1);
}
options.children = undefined;
}
/** Push the Own Element to the List */
list.push({
index,
element: options
});
return list;
}
2020-10-29 18:20:42 +00:00
/**
* Get All Subelements
*
* @export
* @template N
* @template E
* @param {IBaseGraph<N,E>} network
* @param {boolean} [considerChildern=false]
* @return {*}
*/
export function getSubElements<N, E>(network: IBaseGraph<N,E>, considerChildern = false){
2020-10-25 20:14:51 +00:00
const selected = network.network.getSelectedNodes();
if (selected.length === 1){
const parentID = selected[0];
2020-10-29 18:20:42 +00:00
const ret: IBaseNodeOptions<N>[] = [network.data.nodes.get(parentID)];
2020-10-25 20:14:51 +00:00
const selection = network.data.nodes.get({
2020-10-29 18:20:42 +00:00
filter(node: IBaseNodeOptions<N>) {
2020-10-25 20:14:51 +00:00
if (node.parent === parentID) {
if (considerChildern) {
return node;
} else if (node.isConnector || node.isResizer){
return node;
}
}
}
});
ret.push(...selection);
return ret;
}
return [];
}