Skip to content

Commit

Permalink
Merge pull request #340 from makimenko/dagre-improvements
Browse files Browse the repository at this point in the history
Dagre layout improvements
  • Loading branch information
makimenko authored Feb 7, 2021
2 parents 418946b + 2bb0095 commit b89b4fb
Show file tree
Hide file tree
Showing 23 changed files with 653 additions and 157 deletions.
56 changes: 53 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"snyk": "^1.445.0",
"three": "^0.124.0",
"three.meshline": "^1.3.0",
"uuid": "^8.3.2",
"zone.js": "~0.11.3"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import { provideParent } from '../../../util';
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="5" [translateX]="translateLabelX" [rotateZ]="(90 | deg2rad)"
<atft-text-mesh [centered]="true" [text]="label" size="5" [translateX]="translateLabelX" [rotateZ]="(90 | deg2rad)"
materialColor="0xE0E0E0">
</atft-text-mesh>
</atft-plane-mesh>
`
})
export class LayerActorComponent extends EmptyComponent {
@Input() name: string;
@Input() label: string;

@Input()
set width(width: number) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,45 +1,57 @@
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {Component, EventEmitter, Injector, Input, OnDestroy, OnInit, Optional, Output, SkipSelf} from '@angular/core';
import {provideParent} from '../../../util';
import {EmptyComponent} from '../../../object';
import {AbstractObject3D, EmptyComponent} from '../../../object';
import {RendererService} from '../../../renderer';
import {DagreLayoutComponent} from './dagre-layout.component';

@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"
<atft-text-mesh [centered]="true" [text]="label" size="3" [translateY]="translateLabelY"
materialColor="0xE0E0E0">
</atft-text-mesh>
</atft-plane-mesh>
`
})
export class DagreCompositionComponent extends EmptyComponent {
export class DagreCompositionComponent extends EmptyComponent implements OnInit, OnDestroy {

@Input() name: string;
@Input() label: string;

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

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;
public color = 0xA0A0A0;
public translateLabelY: number;
protected dagreLayout: DagreLayoutComponent;

translateLabelY: number;
constructor(
protected rendererService: RendererService,
@SkipSelf() @Optional() protected parent: AbstractObject3D<any>,
protected injector: Injector
) {
super(rendererService, parent);

this.dagreLayout = this.injector.get<DagreLayoutComponent>(DagreLayoutComponent);
if (!this.dagreLayout) {
console.warn('DagreCompositionComponent.constructor: atft-dagre-layout not found!');
}
}

public onSelected() {
this.color = 0xA4A4A4;
Expand All @@ -53,4 +65,49 @@ export class DagreCompositionComponent extends EmptyComponent {
this.color = 0xA0A0A0;
}

ngOnInit() {
super.ngOnInit();
this.addNode();
}


protected addNode() {
if (this.dagreLayout && this.dagreLayout.getGraphModel()) {
// console.log('DagreCompositionComponent.addNode', this.name);

// Register as layout children
this.dagreLayout.getChildren().push(this);

// Create Graph Node
this.dagreLayout.getGraphModel().nodes.push({
name: this.name,
label: this.name
});

// Update Graph Layout
this.dagreLayout.refreshLayout();
}
}


ngOnDestroy() {
super.ngOnDestroy();
this.removeNode();
}

protected removeNode() {
if (this.dagreLayout && this.dagreLayout.getGraphModel()) {
// console.log('DagreCompositionComponent.removeNode', this.name);

// Remove from layout
this.dagreLayout.removeChildByName(this.name);

// Remove from model
this.dagreLayout.getGraphModel().nodes = this.dagreLayout.getGraphModel().nodes.filter(i => i.name !== this.name);

// Update Graph Layout
this.dagreLayout.refreshLayout();
}
}

}
Original file line number Diff line number Diff line change
@@ -1,28 +1,103 @@
import {Component} from '@angular/core';
import {MeshLineConnectorComponent} from '../../../object';
import {Component, Injector, Input, OnDestroy, OnInit, Optional, SkipSelf} from '@angular/core';
import {AbstractObject3D, MeshLineConnectorComponent} from '../../../object';
import {provideParent} from '../../../util';
import * as THREE from 'three';
import {RendererService} from '../../../renderer';
import {DagreLayoutComponent} from './dagre-layout.component';
import {AnimationService} from '../../../animation';

@Component({
selector: 'atft-dagre-edge',
providers: [provideParent(DagreEdgeComponent)],
template: '<ng-content></ng-content>'
})
export class DagreEdgeComponent extends MeshLineConnectorComponent {
export class DagreEdgeComponent extends MeshLineConnectorComponent implements OnInit, OnDestroy {

@Input() animated = true;
@Input() from: string;
@Input() to: string;

public positions: Array<number>;
protected dagreLayout: DagreLayoutComponent;


public animated = true;
constructor(
protected rendererService: RendererService,
@SkipSelf() @Optional() protected parent: AbstractObject3D<any>,
protected 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!');
}
}


protected getLineGeometry(): THREE.BufferGeometry {
if (!this.source || !this.target) {
throw new Error('DagreCompositionComponent: source or target inputs are missing!');
if (this.source || this.target) {
console.warn('DagreEdgeComponent.getLineGeometry source/target inputs ignored. Please use from/to instead');
}
if (!this.from || !this.to) {
throw new Error('DagreEdgeComponent: from or to inputs are missing!');
}
// console.log('DagreCompositionComponent.getLineGeometry', this.positions);
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(this.positions, 3));
return geometry;
}


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();
}
}

ngOnDestroy() {
super.ngOnDestroy();
this.removeEdge();
}

protected removeEdge() {
if (this.dagreLayout && this.dagreLayout.getGraphModel()) {
// console.log('DagreNodeComponent.removeNode', this.name);

// 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();
}
}


}
Loading

0 comments on commit b89b4fb

Please sign in to comment.