11import { Component , ElementRef , Input , Output , ViewChild , EventEmitter , ChangeDetectorRef } from '@angular/core' ;
22import { CommonModule } from "@angular/common" ;
33import { Subject } from "rxjs" ;
4+ import { sum } from "@/util" ;
45
56interface Dimensions {
6- width ? : number ;
7- height ? : number ;
7+ width : number ;
8+ height : number ;
89}
910
1011@Component ( {
@@ -45,15 +46,15 @@ export class TableauTerm {
4546 @Output ( )
4647 public onSize = new EventEmitter < Dimensions > ( ) ;
4748
48- padding : number = 5 ;
49- height : number = 20 ;
49+ padding = 5 ;
50+ height = 20 ;
5051
51- idxW : number = 0 ;
52- termX : number = 0 ;
53- termW : number = 0 ;
54- labelX : number = 0 ;
55- labelW : number = 0 ;
56- totalW : number = 0 ;
52+ idxW = 0 ;
53+ termX = 0 ;
54+ termW = 0 ;
55+ labelX = 0 ;
56+ labelW = 0 ;
57+ totalW = 0 ;
5758
5859 ngAfterViewChecked ( ) {
5960 this . idxW = this . idxText ? this . idxText . nativeElement . getComputedTextLength ( ) + this . padding : 0 ;
@@ -63,11 +64,13 @@ export class TableauTerm {
6364 this . labelX = this . termX + this . termW + this . padding ;
6465 this . totalW = this . termText ? this . labelW + this . idxW + this . termText . nativeElement . getComputedTextLength ( ) : 0 ;
6566
66- this . onSize . emit ( { width : this . totalW } ) ;
67+ this . onSize . emit ( { width : this . totalW , height : this . height } ) ;
6768 }
6869
6970}
7071
72+ const LEVEL_HEIGHT = 40 ;
73+
7174@Component ( {
7275 selector : "[tableau-tree]" ,
7376 standalone : true ,
@@ -78,17 +81,15 @@ export class TableauTree {
7881 @Input ( )
7982 tree : any ;
8083
81- levelHeight = 40 ;
82-
8384 /* Width of the tree node, has to be determined dynamically via onSize events from terms */
84- width : number = 0 ;
85+ width = 0 ;
8586 /* Height isn't stored in a member variable, because it can be computed as needed */
8687
8788 /* Dimensions of the biggest subtree.
8889 Width is used to align all subtrees.
8990 Height is used to determine the overall height of the tree. */
90- subWidth : number = 0 ;
91- subHeight : number = 0 ;
91+ subWidth = 0 ;
92+ subHeight = 0 ;
9293
9394 @Output ( )
9495 public onSize = new EventEmitter < Dimensions > ( ) ;
@@ -124,23 +125,24 @@ export class TableauTree {
124125 // move to end of current node
125126 `M 0 ${ this . totalNodeHeight ( ) - 15 } ` ,
126127 // curve to half-way to subtree
127- `q 0 ${ this . levelHeight / 2 } ${ this . subtreePosition ( idx ) / 2 } ${ this . levelHeight / 2 } ` ,
128+ `q 0 ${ LEVEL_HEIGHT / 2 } ${ this . subtreePosition ( idx ) / 2 } ${ LEVEL_HEIGHT / 2 } ` ,
128129 // curve from half-way to subtree, to subtree position
129- `q ${ this . subtreePosition ( idx ) / 2 } 0 ${ this . subtreePosition ( idx ) / 2 } ${ this . levelHeight / 2 } `
130+ `q ${ this . subtreePosition ( idx ) / 2 } 0 ${ this . subtreePosition ( idx ) / 2 } ${ LEVEL_HEIGHT / 2 } `
130131 ] . join ( ' ' ) ;
131132 }
132133
133134 nodeHeight ( node : any ) {
135+ // note that in this case height includes bottom padding for the node
134136 return node . rule ? 60 : 40 ;
135137 }
136138
137139 totalNodeHeight ( ) {
138- return this . tree . nodes . map ( this . nodeHeight ) . reduce ( ( sum : number , h : number ) => sum + h , 0 ) ;
140+ return sum ( this . tree . nodes . map ( this . nodeHeight ) ) ;
139141 }
140142
141143 nodeY ( idx : number ) {
142144 // y position of a given node is the sum of heights of all preceeding nodes
143- return this . tree . nodes . slice ( 0 , idx ) . map ( this . nodeHeight ) . reduce ( ( sum : number , h : number ) => sum + h , 0 ) ;
145+ return sum ( this . tree . nodes . slice ( 0 , idx ) . map ( this . nodeHeight ) ) ;
144146 }
145147}
146148
@@ -154,7 +156,7 @@ export class TableauTree {
154156} )
155157export class TableauSVG {
156158
157- treeDimensions$ : Subject < Dimensions > = new Subject ( ) ;
159+ treeDimensions$ = new Subject < Dimensions > ( ) ;
158160 treeDimensions : Dimensions = { width :0 , height : 0 } ;
159161
160162 constructor ( private cdref : ChangeDetectorRef ) { }
0 commit comments