Skip to content

Commit

Permalink
Dagre composition
Browse files Browse the repository at this point in the history
  • Loading branch information
makimenko committed Feb 6, 2021
1 parent 83deb1b commit a7db5ad
Show file tree
Hide file tree
Showing 11 changed files with 269 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {ServerCompactActorComponent} from './server/server-compact-actor.compone
import {ServerIconActorComponent} from './server/server-icon-actor.component';
import {WorkstationActorComponent} from './server/workstation-actor.component';
import {GridActorComponent} from './layer/grid-actor.component';
import {DagreEdgeComponent, DagreLayoutComponent} from './layout';
import {DagreCompositionComponent, DagreEdgeComponent, DagreLayoutComponent, DagreNodeComponent} from './layout';

@NgModule({
imports: [
Expand All @@ -24,7 +24,9 @@ import {DagreEdgeComponent, DagreLayoutComponent} from './layout';
WorkstationActorComponent,
GridActorComponent,
DagreLayoutComponent,
DagreEdgeComponent
DagreEdgeComponent,
DagreCompositionComponent,
DagreNodeComponent
],
exports: [
LayerActorComponent,
Expand All @@ -35,7 +37,9 @@ import {DagreEdgeComponent, DagreLayoutComponent} from './layout';
WorkstationActorComponent,
GridActorComponent,
DagreLayoutComponent,
DagreEdgeComponent
DagreEdgeComponent,
DagreCompositionComponent,
DagreNodeComponent
]
})
export class AtftDataCenterActorModule {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {provideParent} from '../../../util';
import {EmptyComponent} from '../../../object';

@Component({
selector: 'atft-dagre-composition',
providers: [provideParent(DagreCompositionComponent)],
template: `
<atft-plane-mesh atft-raycaster-group [width]="width" [height]="height" [materialColor]="color" (mouseEnter)="onSelected()"
(mouseExit)="onDeselected()">
<atft-text-mesh [centered]="true" [text]="name" size="3" [translateY]="translateLabelY"
materialColor="0xE0E0E0">
</atft-text-mesh>
</atft-plane-mesh>
`
})
export class DagreCompositionComponent extends EmptyComponent {

@Input() name: string;

private _height: number;
@Input()
set height(hight: number) {
this._height = hight;
this.translateLabelY = this._height / 2 - 5;
}

get height(): number {
return this._height;
}

@Input() width: number;



@Output() render = new EventEmitter<void>();
@Output() selected = new EventEmitter<void>();
@Output() deselected = new EventEmitter<void>();

color = 0xA0A0A0;

translateLabelY: number;

public onSelected() {
this.color = 0xA4A4A4;
}

public onDeselected() {
this.color = 0xA0A0A0;
}

public onClick() {
this.color = 0xA0A0A0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export class DagreEdgeComponent extends MeshLineConnectorComponent {

protected getLineGeometry(): THREE.BufferGeometry {
if (!this.source || !this.target) {
throw new Error('DagreEdgeComponent: source or target inputs are missing!');
throw new Error('DagreCompositionComponent: source or target inputs are missing!');
}
// console.log('DagreEdgeComponent.getLineGeometry', this.positions);
// console.log('DagreCompositionComponent.getLineGeometry', this.positions);
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(this.positions, 3));
return geometry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {RendererService} from '../../../renderer';
import {AbstractObject3D} from '../../../object';
import {DagreEdgeComponent} from './dagre-edge.component';
import * as dagre from 'dagre';
import {DagreNodeComponent} from './dagre-node.component';
import {DagreCompositionComponent} from './dagre-composition.component';


@Component({
Expand Down Expand Up @@ -39,34 +41,57 @@ export class DagreLayoutComponent extends EmptyComponent implements AfterViewIni
this.graphModel = {
layout: {},
nodes: [],
edges: []
edges: [],
composition: []
};
}

public addChild(object: AbstractObject3D<any>): void {
super.addChild(object);
// console.log('DagreLayoutComponent.addChild', object);
this.processDagreChild(object);
}

protected processDagreChild(object: AbstractObject3D<any>) {
if (object instanceof DagreEdgeComponent) {
// ============== 1) EDGE:
// console.log('DagreLayoutComponent.addChild as Edge', object);
const edgeObject: DagreEdgeComponent = object;
if (edgeObject.source && edgeObject.source.getObject() && edgeObject.target && edgeObject.target.getObject()) {
this.graphModel.edges.push({
uuid: edgeObject.getObject().uuid,
from: edgeObject.source.getObject().uuid,
to: edgeObject.target.getObject().uuid
});
} else {
console.warn('DagreLayoutComponent.addChild: edge source/target is undefined');
}
this.addEdge(object);
} else {
// ============== 2) NODE:
// console.log('DagreLayoutComponent.addChild as Node', object);
this.graphModel.nodes.push({
id: object.getObject().uuid,
label: '?',
this.addNode(object);
}
}

protected addEdge(edge: DagreEdgeComponent) {
// console.log('DagreLayoutComponent.addEdge', edge);
const edgeObject: DagreEdgeComponent = edge;
if (edgeObject.source && edgeObject.source.getObject() && edgeObject.target && edgeObject.target.getObject()) {
this.graphModel.edges.push({
uuid: edgeObject.getObject().uuid,
from: edgeObject.source.getObject().uuid,
to: edgeObject.target.getObject().uuid
});
} else {
console.warn('DagreLayoutComponent.addChild: edge source/target is undefined');
}
}


protected addNode(object: AbstractObject3D<any>) {
// console.log('DagreLayoutComponent.addNode', object);
this.graphModel.nodes.push({
id: object.getObject().uuid,
label: object.getObject().uuid,
});

if (object instanceof DagreNodeComponent) {
const node: DagreNodeComponent = object;
if (node.composition) {
// console.log('DagreLayoutComponent.addNode to composition', node.composition);
this.graphModel.composition.push({
parent: node.composition.getObject().uuid,
child: node.getObject().uuid
});
}
}

}

ngAfterViewInit() {
Expand All @@ -76,21 +101,20 @@ export class DagreLayoutComponent extends EmptyComponent implements AfterViewIni

public layout() {
// console.log('DagreLayoutComponent.layout');

this.graphModel.layout.align = this.align;
this.graphModel.layout.rankdir = this.rankdir;
this.graphModel.layout.nodesep = this.nodesep;
this.graphModel.layout.edgesep = this.edgesep;
this.graphModel.layout.ranksep = this.ranksep;
this.graphModel.layout.marginx = this.marginx;
this.graphModel.layout.marginy = this.marginy;
this.graphModel.layout.ranker = this.ranker;

this.graphModel.layout = {
align: this.align,
rankdir: this.rankdir,
nodesep: this.nodesep,
edgesep: this.edgesep,
ranksep: this.ranksep,
marginx: this.marginx,
marginy: this.marginy,
ranker: this.ranker
};
const g = DagreUtils.modelToGraph(this.graphModel);
// console.log('DagreLayoutComponent.layout: g', g);
this.syncGraphNodes(g);
this.syncGraphEdges(g);

this.rendererService.render();
}

Expand All @@ -108,6 +132,14 @@ export class DagreLayoutComponent extends EmptyComponent implements AfterViewIni
object.translateY = node.y;
object.applyTranslation();

if (object instanceof DagreCompositionComponent) {
// console.log('DagreLayoutComponent.layout: Update composition', node);
const composition: DagreCompositionComponent = object;
composition.width = node.width;
composition.height = node.height;

}

} else {
console.warn('DagreLayoutComponent.layout: Object not found by uuid', uuid);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {Component, Input} from '@angular/core';
import {AbstractObject3D, EmptyComponent} from '../../../object';
import {provideParent} from '../../../util';

@Component({
selector: 'atft-dagre-node',
providers: [provideParent(DagreNodeComponent)],
template: '<ng-content></ng-content>'
})
export class DagreNodeComponent extends EmptyComponent {

@Input() composition: AbstractObject3D<any>;

@Input() translateZ = 1;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as dagre from 'dagre';


export interface Node {
id: string;
label: string;
Expand All @@ -24,6 +23,9 @@ export interface GraphModel {
composition?: Array<Composition>;
}

/**
* WIKI: https://github.com/dagrejs/dagre/wiki
*/
export class DagreUtils {

public static modelToGraph(model: GraphModel): dagre.graphlib.Graph {
Expand Down
2 changes: 2 additions & 0 deletions projects/atft/src/lib/actor/data-center/layout/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export * from './dagre-layout.component';
export * from './dagre-node.component';
export * from './dagre-edge.component';
export * from './dagre-composition.component';

19 changes: 17 additions & 2 deletions projects/atft/src/lib/object/abstract-object-3d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export abstract class AbstractObject3D<T extends THREE.Object3D> implements Afte
protected afterInit() {
}

protected removeChild(object: AbstractObject3D<any>): void {
public removeChild(object: AbstractObject3D<any>): void {
if (this.object && object) {

// Remove from children:
Expand All @@ -183,9 +183,24 @@ export abstract class AbstractObject3D<T extends THREE.Object3D> implements Afte
public findByUuid(uuid: string) {
// console.log('AbstractObject3D.findByUuid: Searching uuid', uuid);
// console.log('AbstractObject3D.findByUuid: children', this.childlren);
const res = this.childlren.filter(i => i.object && i.object.uuid === uuid)[0];
// const res = this.childlren.filter(i => i.object && i.object.uuid === uuid)[0];
const res = this.getNodeByUuid(this, uuid);
// console.log('AbstractObject3D.findByUuid: result', res);
return res;
}

protected getNodeByUuid(currentNode: AbstractObject3D<any>, uuid) {
if (currentNode.object && currentNode.object.uuid === uuid) {
return currentNode;
}
let node;
currentNode.childlren.some(child => node = this.getNodeByUuid(child, uuid));
return node;
}


public getChildren() {
return this.childlren;
}

}
42 changes: 36 additions & 6 deletions projects/atft/src/lib/object/mesh/plane-mesh.component.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Component, Input, Optional, SkipSelf } from '@angular/core';
import {Component, Input, OnChanges, Optional, SimpleChanges, SkipSelf} from '@angular/core';
import * as THREE from 'three';
import { RendererService } from '../../renderer/renderer.service';
import { provideParent } from '../../util';
import { AbstractObject3D } from '../abstract-object-3d';
import { AbstractMesh } from './abstract-mesh-3d';
import {RendererService} from '../../renderer/renderer.service';
import {provideParent} from '../../util';
import {AbstractObject3D} from '../abstract-object-3d';
import {AbstractMesh} from './abstract-mesh-3d';

@Component({
selector: 'atft-plane-mesh',
providers: [provideParent(PlaneMeshComponent)],
template: '<ng-content></ng-content>'
})
export class PlaneMeshComponent extends AbstractMesh {
export class PlaneMeshComponent extends AbstractMesh implements OnChanges {

/**
* Width; that is, the length of the edges parallel to the X axis. Optional; defaults to 1.
Expand Down Expand Up @@ -51,4 +51,34 @@ export class PlaneMeshComponent extends AbstractMesh {
return mesh;
}


public ngOnChanges(changes: SimpleChanges) {
// console.log('AbstractObject3D.ngOnChanges', this.uuid);
if (!this.object) {
return;
}
super.ngOnChanges(changes);

let modified = false;

if (['width', 'height', 'widthSegments', 'heightSegments'].some(propName => propName in changes)) {
if (this.getObject() instanceof THREE.Mesh) {
const mesh: THREE.Mesh = this.getObject();

if (mesh.geometry instanceof THREE.PlaneBufferGeometry) {
const currentGeometry: THREE.PlaneBufferGeometry = mesh.geometry;
const newGeometry = new THREE.PlaneBufferGeometry(this.width, this.height, this.widthSegments, this.heightSegments);
currentGeometry.attributes = newGeometry.attributes;
}
}
modified = true;
}

if (modified) {
this.changed.emit();
this.rendererService.render();
}

}

}
Loading

0 comments on commit a7db5ad

Please sign in to comment.