src/app/model/d3/d3.graph.ts
Graph class with D3.js compatability.
Properties |
|
Methods |
|
Public
constructor(name, description: string)
|
|||||||||
Defined in src/app/model/d3/d3.graph.ts:12
|
|||||||||
Parameters :
|
Public Readonly description |
Type : string
|
Default value : ''
|
Defined in src/app/model/d3/d3.graph.ts:16
|
Public Readonly links |
Type : D3Link[]
|
Default value : []
|
Defined in src/app/model/d3/d3.graph.ts:12
|
Public Readonly name |
Default value : `graph_${Date.now().toString()}`
|
Defined in src/app/model/d3/d3.graph.ts:15
|
Public Readonly nodes |
Type : D3Node[]
|
Default value : []
|
Defined in src/app/model/d3/d3.graph.ts:11
|
Public createLink | |||||||||||||||
createLink(sourceId: string, targetId: string, relations?: string[], functions?: string[])
|
|||||||||||||||
Defined in src/app/model/d3/d3.graph.ts:66
|
|||||||||||||||
Parameters :
Returns :
Promise<D3Link>
|
Public createNode | ||||||||||||||||||
createNode(id: string, relations?: string[], constants?: string[], x?: number, y?: number)
|
||||||||||||||||||
Defined in src/app/model/d3/d3.graph.ts:52
|
||||||||||||||||||
Parameters :
Returns :
Promise<D3Node>
|
Public createNodeWithGeneratedId |
createNodeWithGeneratedId(x?: number, y?: number)
|
Defined in src/app/model/d3/d3.graph.ts:44
|
Returns :
Promise<D3Node>
|
Static Async fromDomainGraph | ||||||
fromDomainGraph(domainGraph: FOLGraph)
|
||||||
Defined in src/app/model/d3/d3.graph.ts:19
|
||||||
Parameters :
Returns :
Promise<D3Graph>
|
Private Static functionsAreValid | ||||||
functionsAreValid(functions?: string[])
|
||||||
Defined in src/app/model/d3/d3.graph.ts:30
|
||||||
Parameters :
Returns :
boolean
|
Private Static relationsAreValid | ||||||
relationsAreValid(relations?: string[])
|
||||||
Defined in src/app/model/d3/d3.graph.ts:26
|
||||||
Parameters :
Returns :
boolean
|
Public removeLink | ||||||
removeLink(link: D3Link)
|
||||||
Defined in src/app/model/d3/d3.graph.ts:109
|
||||||
Parameters :
Returns :
Promise<D3Link>
|
Public removeNode | ||||||
removeNode(node: D3Node)
|
||||||
Defined in src/app/model/d3/d3.graph.ts:93
|
||||||
Parameters :
Returns :
Promise<>
|
Public toDomainGraph |
toDomainGraph()
|
Defined in src/app/model/d3/d3.graph.ts:34
|
Returns :
FOLGraph
|
import { D3Link, ApolloLink } from 'src/app/model/d3/d3.link';
import { D3Node, ApolloNode } from 'src/app/model/d3/d3.node';
import { FOLEdge } from 'src/app/model/domain/fol.edge';
import { FOLGraph } from 'src/app/model/domain/fol.graph';
import { FOLNode } from 'src/app/model/domain/fol.node';
/**
* Graph class with D3.js compatability.
*/
export default class D3Graph {
public readonly nodes: D3Node[] = [];
public readonly links: D3Link[] = [];
public constructor(
public readonly name = `graph_${Date.now().toString()}`,
public readonly description = '',
) {}
public static async fromDomainGraph(domainGraph: FOLGraph): Promise<D3Graph> {
const graph = new D3Graph(domainGraph.name, domainGraph.description);
await Promise.all(domainGraph.nodes.map((node) => graph.createNode(node.name, node.relations, node.constants)));
await Promise.all(domainGraph.edges.map((edge) => graph.createLink(edge.source, edge.target, edge.relations, edge.functions)));
return Promise.resolve(graph);
}
private static relationsAreValid(relations?: string[]): boolean {
return relations?.every((rel) => rel.charAt(0) === rel.charAt(0).toUpperCase()) ?? true;
}
private static functionsAreValid(functions?: string[]): boolean {
return functions?.every((fun) => fun.charAt(0) === fun.charAt(0).toLowerCase()) ?? true;
}
public toDomainGraph(): FOLGraph {
return {
name: this.name,
description: this.description,
lastEdit: Date.now(),
nodes: this.nodes.map<FOLNode>((node) => ({ name: node.id, relations: [...node.relations], constants: [...node.constants] })),
edges: this.links.map<FOLEdge>((link) => ({ source: link.source.id, target: link.target.id, relations: [...link.relations], functions: [...link.functions] })),
};
}
public createNodeWithGeneratedId(x?: number, y?: number): Promise<D3Node> {
const highestCurrentId = this.nodes
.map((node) => +node.id)
.filter((id) => !isNaN(id))
.reduce((prev, curr) => (prev >= curr ? prev : curr), -1);
return this.createNode(`${highestCurrentId + 1}`, undefined, undefined, x, y);
}
public createNode(id: string, relations?: string[], constants?: string[], x?: number, y?: number): Promise<D3Node> {
if (this.nodes.some((n) => n.id === id)) {
return Promise.reject({ key: 'validation.node.duplicate', params: { node: id } });
} else if (!D3Graph.relationsAreValid(relations)) {
return Promise.reject({ key: 'validation.node.invalid-relations', params: { node: id } });
} else if (!D3Graph.functionsAreValid(constants)) {
return Promise.reject({ key: 'validation.node.invalid-constants', params: { node: id } });
}
const node = new ApolloNode(id, relations, constants, x, y);
this.nodes.push(node);
return Promise.resolve(node);
}
public createLink(sourceId: string, targetId: string, relations?: string[], functions?: string[]): Promise<D3Link> {
const existingLink = this.links.find((l) => l.source.id === sourceId && l.target.id === targetId);
if (existingLink !== undefined) {
return Promise.reject(existingLink);
}
const source = this.nodes.find((node) => node.id === sourceId);
if (source === undefined) {
return Promise.reject({ key: 'validation.node.missing', params: { node: sourceId } });
}
const target = this.nodes.find((node) => node.id === targetId);
if (target === undefined) {
return Promise.reject({ key: 'validation.node.missing', params: { node: targetId } });
}
if (!D3Graph.relationsAreValid(relations)) {
return Promise.reject({ key: 'validation.edge.invalid-relations', params: { source: sourceId, target: targetId } });
} else if (!D3Graph.functionsAreValid(functions)) {
return Promise.reject({ key: 'validation.edge.invalid-functions', params: { source: sourceId, target: targetId } });
}
const link = new ApolloLink(source, target, relations, functions);
this.links.push(link);
return Promise.resolve(link);
}
public removeNode(node: D3Node): Promise<[D3Node, D3Link[]]> {
const nodeIndex = this.nodes.findIndex((n) => n.id === node.id);
if (nodeIndex === -1) {
return Promise.reject('validation.node.missing');
}
this.nodes.splice(nodeIndex, 1);
const attachedLinks = this.links.filter((link) => link.source.id === node.id || link.target.id === node.id);
attachedLinks.forEach((link) => {
const linkIndex = this.links.indexOf(link, 0);
this.links.splice(linkIndex, 1);
});
return Promise.resolve([node, attachedLinks]);
}
public removeLink(link: D3Link): Promise<D3Link> {
const linkIndex = this.links.findIndex((l) => l.source.id === link.source.id && l.target.id === link.target.id);
if (linkIndex === -1) {
return Promise.reject('validation.edge.missing');
}
this.links.splice(linkIndex, 1);
return Promise.resolve(link);
}
}