projects/atft/src/lib/actor/data-center/layout/dagre-edge.component.ts
OnInit
OnDestroy
providers |
provideParent(DagreEdgeComponent)
|
selector | atft-dagre-edge |
template |
|
Properties |
Methods |
|
Inputs |
Outputs |
Accessors |
constructor(rendererService: RendererService, parent: AbstractObject3D<any>, animationService: AnimationService, injector: Injector)
|
|||||||||||||||
Parameters :
|
endType | |
Type : LineEndType
|
|
Default value : LineEndType.arrow
|
|
from | |
Type : string
|
|
startType | |
Type : LineEndType
|
|
Default value : LineEndType.circle
|
|
to | |
Type : string
|
|
type | |
Type : EdgeType
|
|
animated | |
Type : boolean
|
|
Default value : true
|
|
Inherited from
LineConnectorComponent
|
|
Defined in
LineConnectorComponent:33
|
dashSize | |
Type : number
|
|
Default value : 3
|
|
Inherited from
LineConnectorComponent
|
|
Defined in
LineConnectorComponent:28
|
gapSize | |
Type : number
|
|
Default value : 0.5
|
|
Inherited from
LineConnectorComponent
|
|
Defined in
LineConnectorComponent:29
|
lineType | |
Type : LineType
|
|
Default value : LineType.dashed
|
|
Inherited from
LineConnectorComponent
|
|
Defined in
LineConnectorComponent:31
|
lineWidth | |
Type : number
|
|
Default value : 2
|
|
Inherited from
LineConnectorComponent
|
|
Defined in
LineConnectorComponent:27
|
materialColor | |
Type : number
|
|
Default value : 0xFFFFFF
|
|
Inherited from
LineConnectorComponent
|
|
Defined in
LineConnectorComponent:25
|
opacity | |
Type : number
|
|
Default value : 1
|
|
Inherited from
LineConnectorComponent
|
|
Defined in
LineConnectorComponent:30
|
solid | |
Type : boolean
|
|
Default value : false
|
|
Inherited from
LineConnectorComponent
|
|
Defined in
LineConnectorComponent:26
|
source | |
Type : AbstractObject3D<THREE.Object3D>
|
|
Inherited from
AbstractConnector
|
|
Defined in
AbstractConnector:10
|
target | |
Type : AbstractObject3D<THREE.Object3D>
|
|
Inherited from
AbstractConnector
|
|
Defined in
AbstractConnector:13
|
layer | |
Type : number
|
|
Default value : 0
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:42
|
name | |
Type : string
|
|
Default value : uuidv4()
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:40
|
rotateX | |
Type : number
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:24
|
|
Rotation in Euler angles (radians) with order X, Y, Z. |
rotateY | |
Type : number
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:25
|
rotateZ | |
Type : number
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:26
|
scaleX | |
Type : number
|
|
Default value : 1
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:36
|
scaleY | |
Type : number
|
|
Default value : 1
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:37
|
scaleZ | |
Type : number
|
|
Default value : 1
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:38
|
translateX | |
Type : number
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:31
|
|
Translate the geometry. This is typically done as a one time operation, and not during a loop. |
translateY | |
Type : number
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:32
|
translateZ | |
Type : number
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:33
|
changed | |
Type : EventEmitter
|
|
Inherited from
AbstractObject3D
|
|
Defined in
AbstractObject3D:44
|
Protected addEdge |
addEdge()
|
Returns :
void
|
Protected appendLineEnds | ||||||
appendLineEnds(lineObject: THREE.Object3D)
|
||||||
Parameters :
Returns :
void
|
Protected getConnectorEndGeometry | ||||||
getConnectorEndGeometry(type: LineEndType)
|
||||||
Parameters :
Returns :
THREE.BufferGeometry | undefined
|
Protected getPositions |
getPositions()
|
Inherited from
LineConnectorComponent
|
Defined in
LineConnectorComponent:264
|
Returns :
number[]
|
Protected newObject3DInstance |
newObject3DInstance()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:99
|
Returns :
THREE.Object3D
|
ngOnDestroy |
ngOnDestroy()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:181
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:152
|
Returns :
void
|
Protected removeEdge |
removeEdge()
|
Returns :
void
|
Protected syncGraph |
syncGraph()
|
Returns :
void
|
Protected syncGraphEdges | ||||||
syncGraphEdges(g: dagre.graphlib.Graph)
|
||||||
Parameters :
Returns :
void
|
Private updateEnd | ||||||||||||
updateEnd(lineSide: THREE.Mesh, prevPoint: THREE.Vector3, endPoint: THREE.Vector3)
|
||||||||||||
Parameters :
Returns :
void
|
Private updateEnds |
updateEnds()
|
Returns :
void
|
Private animate |
animate()
|
Inherited from
LineConnectorComponent
|
Defined in
LineConnectorComponent:114
|
Returns :
void
|
Public createLineMesh |
createLineMesh()
|
Inherited from
AbstractConnector
|
Defined in
AbstractConnector:50
|
Returns :
Line2
|
Public ngOnChanges | ||||||
ngOnChanges(changes: SimpleChanges)
|
||||||
Inherited from
AbstractObject3D
|
||||||
Defined in
AbstractObject3D:127
|
||||||
Parameters :
Returns :
void
|
updateLineGeometry |
updateLineGeometry()
|
Inherited from
AbstractConnector
|
Defined in
AbstractConnector:85
|
Returns :
void
|
Private watchObjects |
watchObjects()
|
Inherited from
AbstractConnector
|
Defined in
AbstractConnector:26
|
Returns :
void
|
Public addChild | ||||||
addChild(object: AbstractObject3D<any>)
|
||||||
Inherited from
AbstractObject3D
|
||||||
Defined in
AbstractObject3D:143
|
||||||
Parameters :
Returns :
void
|
Protected afterInit |
afterInit()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:156
|
Returns :
void
|
Public applyRotation |
applyRotation()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:118
|
Returns :
void
|
Public applyScale |
applyScale()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:135
|
Returns :
void
|
Public applyTranslation |
applyTranslation()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:127
|
Returns :
void
|
Public findByName | ||||||
findByName(name: string)
|
||||||
Inherited from
AbstractObject3D
|
||||||
Defined in
AbstractObject3D:185
|
||||||
Parameters :
Returns :
any
|
Public getChildren |
getChildren()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:202
|
Returns :
Array<AbstractObject3D<any>>
|
Public getObject |
getObject()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:175
|
Returns :
T
|
Public ngAfterViewInit |
ngAfterViewInit()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:181
|
Returns :
void
|
Protected recursionByName | |||||||||
recursionByName(currentNode: AbstractObject3D<any>, name: string)
|
|||||||||
Inherited from
AbstractObject3D
|
|||||||||
Defined in
AbstractObject3D:192
|
|||||||||
Parameters :
Returns :
any
|
Public removeChild | ||||||
removeChild(object: AbstractObject3D<any>)
|
||||||
Inherited from
AbstractObject3D
|
||||||
Defined in
AbstractObject3D:160
|
||||||
Parameters :
Returns :
void
|
Public removeChildByName | ||||||
removeChildByName(name: string)
|
||||||
Inherited from
AbstractObject3D
|
||||||
Defined in
AbstractObject3D:206
|
||||||
Parameters :
Returns :
void
|
Public updateParent |
updateParent()
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:111
|
Returns :
void
|
Protected dagreLayout |
Type : DagreLayoutComponent
|
Protected graphUpdated |
Type : Subscription
|
Protected lineEnd |
Type : THREE.Mesh
|
Protected lineStart |
Type : THREE.Mesh
|
Protected positions |
Type : Array<number>
|
Protected animation |
Type : Subscription
|
Inherited from
LineConnectorComponent
|
Defined in
LineConnectorComponent:34
|
Protected clock |
Default value : new THREE.Clock()
|
Inherited from
LineConnectorComponent
|
Defined in
LineConnectorComponent:37
|
Protected line |
Type : Line2
|
Inherited from
LineConnectorComponent
|
Defined in
LineConnectorComponent:39
|
Private matLine |
Type : LineMaterial
|
Inherited from
LineConnectorComponent
|
Defined in
LineConnectorComponent:40
|
Protected time |
Type : number
|
Default value : 0
|
Inherited from
LineConnectorComponent
|
Defined in
LineConnectorComponent:35
|
Protected timeScale |
Type : number
|
Default value : 5
|
Inherited from
LineConnectorComponent
|
Defined in
LineConnectorComponent:36
|
Protected sourceSub |
Type : Subscription
|
Inherited from
AbstractConnector
|
Defined in
AbstractConnector:15
|
Protected targetSub |
Type : Subscription
|
Inherited from
AbstractConnector
|
Defined in
AbstractConnector:16
|
Protected childlren |
Type : Array<AbstractObject3D<any>>
|
Default value : []
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:46
|
Protected object |
Type : T
|
Inherited from
AbstractObject3D
|
Defined in
AbstractObject3D:48
|
type | ||||||
settype(val: EdgeType)
|
||||||
Parameters :
Returns :
void
|
import {Component, Injector, Input, OnDestroy, OnInit, Optional, SkipSelf} from '@angular/core';
import * as dagre from 'dagre';
import {Subscription} from 'rxjs';
import * as THREE from 'three';
import {AnimationService} from '../../../animation';
import {AbstractObject3D, LineConnectorComponent} from '../../../object';
import {RendererService} from '../../../renderer';
import {provideParent} from '../../../util';
import {DagreLayoutComponent} from './dagre-layout.component';
export enum LineEndType {
none = 'none',
circle = 'circle',
arrow = 'arrow'
}
export enum EdgeType {
sequence = 'sequence',
association = 'association',
message = 'message',
line = 'line'
}
@Component({
selector: 'atft-dagre-edge',
providers: [provideParent(DagreEdgeComponent)],
template: '<ng-content></ng-content>'
})
export class DagreEdgeComponent extends LineConnectorComponent implements OnInit, OnDestroy {
@Input() from!: string;
@Input() to!: string;
@Input() startType: LineEndType = LineEndType.circle;
@Input() endType: LineEndType = LineEndType.arrow;
@Input()
set type(val: EdgeType) {
switch (val) {
case EdgeType.association:
this.animated = false;
this.solid = false;
this.startType = LineEndType.none;
this.endType = LineEndType.arrow;
break;
case EdgeType.message:
this.animated = true;
this.solid = false;
this.dashSize = 1;
this.startType = LineEndType.circle;
this.endType = LineEndType.arrow;
break;
case EdgeType.line:
this.animated = false;
this.solid = true;
this.startType = LineEndType.none;
this.endType = LineEndType.none;
break;
case EdgeType.sequence:
this.animated = false;
this.solid = true;
this.startType = LineEndType.none;
this.endType = LineEndType.arrow;
break;
default:
this.animated = true;
this.solid = false;
this.dashSize = 4;
this.startType = LineEndType.circle;
this.endType = LineEndType.arrow;
}
}
protected lineStart!: THREE.Mesh;
protected lineEnd!: THREE.Mesh;
protected positions!: Array<number>;
protected dagreLayout: DagreLayoutComponent;
protected graphUpdated: Subscription;
constructor(
protected override rendererService: RendererService,
@SkipSelf() @Optional() protected override parent: AbstractObject3D<any>,
protected override animationService: AnimationService,
protected injector: Injector
) {
super(rendererService, parent, animationService);
this.dagreLayout = this.injector.get<DagreLayoutComponent>(DagreLayoutComponent);
if (!this.dagreLayout) {
console.warn('DagreEdgeComponent.constructor: atft-dagre-layout not found!');
}
this.syncGraph = this.syncGraph.bind(this);
this.graphUpdated = this.dagreLayout.updated.subscribe(this.syncGraph);
}
protected override newObject3DInstance(): THREE.Object3D {
const lineObject = super.newObject3DInstance();
// console.log('DagreEdgeComponent.newObject3DInstance');
this.appendLineEnds(lineObject);
return lineObject;
}
protected appendLineEnds(lineObject: THREE.Object3D) {
// 1. Init Material
const material = new THREE.MeshBasicMaterial({
color: this.materialColor,
opacity: this.opacity,
transparent: this.opacity < 1,
depthWrite: true
});
// 2. Create start
const startGeometry = this.getConnectorEndGeometry(this.startType);
if (startGeometry) {
this.lineStart = new THREE.Mesh(startGeometry, material);
lineObject.add(this.lineStart);
}
// 3. Create end
const endGeometry = this.getConnectorEndGeometry(this.endType);
if (endGeometry) {
this.lineEnd = new THREE.Mesh(endGeometry, material);
lineObject.add(this.lineEnd);
}
}
protected getConnectorEndGeometry(type: LineEndType): THREE.BufferGeometry | undefined {
switch (type) {
case LineEndType.circle:
return new THREE.CircleGeometry(0.7, 16);
break;
case LineEndType.arrow:
// eslint-disable-next-line no-case-declarations
const shape = new THREE.Shape();
shape.moveTo(0, -0.5);
shape.lineTo(1, 2);
shape.lineTo(0, 1.7);
shape.lineTo(-1, 2);
return new THREE.ShapeGeometry(shape);
break;
default:
return undefined;
}
}
override ngOnInit() {
super.ngOnInit();
this.addEdge();
}
protected addEdge() {
if (this.dagreLayout && this.dagreLayout.getGraphModel()) {
// console.log('DagreEdgeComponent.addEdge', this.name);
// Register as layout children
this.dagreLayout.getChildren().push(this);
// Create Graph edge:
if (this.from && this.to) {
this.dagreLayout.getGraphModel().edges?.push({
name: this.name,
from: this.from,
to: this.to
});
} else {
console.warn('DagreEdgeComponent.addChild: edge source/target is undefined');
}
// Update Graph Layout
this.dagreLayout.refreshLayout();
}
}
override ngOnDestroy() {
super.ngOnDestroy();
this.removeEdge();
}
protected removeEdge() {
if (this.dagreLayout && this.dagreLayout.getGraphModel()) {
// console.log('DagreNodeComponent.removeNode', this.name);
// Unsubscribe from graph update events
this.graphUpdated?.unsubscribe();
// Remove from layout
this.dagreLayout.removeChildByName(this.name);
// Remove from model
this.dagreLayout.getGraphModel().edges = this.dagreLayout.getGraphModel().edges?.filter(i => i.name !== this.name);
// Update Graph Layout
this.dagreLayout.refreshLayout();
}
}
protected syncGraph() {
// console.log('DagreEdgeComponent.update');
if (this.object) {
this.syncGraphEdges(this.dagreLayout.getGraph());
}
}
protected syncGraphEdges(g: dagre.graphlib.Graph) {
// console.log('DagreEdgeComponent.syncGraphEdges');
g.edges().forEach((e) => {
const edge: dagre.GraphEdge = g.edge(e);
// console.log('DagreEdgeComponent.syncGraphEdges: edge', edge);
if (edge["name"] === this.name) {
this.positions = [];
// console.log('DagreEdgeComponent.syncGraphEdges: edge.points', edge.points);
edge.points.forEach(p => {
if (!Number.isNaN(p.x) && !Number.isNaN(p.y)) {
// console.log('x=' + p.x + ', y=' + p.y);
this.positions.push(p.x, p.y, 0.1);
}
});
this.updateEnds();
this.updateLineGeometry();
}
});
}
private updateEnds() {
const p = this.positions;
if (p?.length >= 9) {
// Beginning / Start of the line
this.updateEnd(this.lineStart,
new THREE.Vector3(p[3], p[4], p[5]),
new THREE.Vector3(p[0], p[1], p[2])
);
// Target / End of the line
this.updateEnd(this.lineEnd,
new THREE.Vector3(p[p.length - 6], p[p.length - 5], p[p.length - 4]),
new THREE.Vector3(p[p.length - 3], p[p.length - 2], p[p.length - 1])
);
}
}
private updateEnd(lineSide: THREE.Mesh, prevPoint: THREE.Vector3, endPoint: THREE.Vector3) {
if (lineSide) {
const direction = prevPoint.clone().sub(endPoint);
let angle = direction.angleTo(new THREE.Vector3(0, 1, 0));
angle = prevPoint.x < endPoint.x ? angle : -angle;
lineSide.rotation.set(0, 0, angle);
lineSide.position.set(
endPoint.x || 0,
endPoint.y || 0,
endPoint.z || 0
);
}
}
protected override getPositions(): number[] {
if (this.positions) {
return this.positions;
} else {
return [0, 0, 0, 0, 0, 0];
}
}
}