2

I want to display organization structure using angular material tree with position, salary, year of services as properties.

class Employee {
  name: string;
  position: string;
  salary: number;
  yearofServices: number;
  reports: Employee[];
 }

For example,

[ 
  {id: 1,
   name:'employee1',
   position: 'president',
   salary: 250000,
   yearofServices: 20,
   reports: [
    {
      id: 2,
      name:'employee2',
      position: 'manager',
      salary: 200000,
       yearofServices: 10,
    },
   {
      id: 3,
      name:'employee3',
      position: 'manager',
      salary: 190000,
       yearofServices: 15,
    }
   ];
]

We want to display four columns:

Name Position Salary YearOfService

Name column is a tree structure according to organization reports hierarchy. For example, if a manager has three reports, the manager node will have three sub nodes.

Is it possible to do this using angular material tree control?

user3097695
  • 1,152
  • 2
  • 16
  • 42
  • I was posting an answer but then I thought it was a bit unclear what you where asking `mat-tree` is for displaying a tree so of course you can have sub nodes that have sub nodes that have sub nodes and so on. Only problem is what do you want to display into your name column? only names inside reports or all of the informations. Why do you need columns why don't you just use a single tree structure? – JSmith Oct 08 '19 at 22:39
  • @JSmith I have a requirement to display each record in a row in a table like structure. For first column, it looks more like a tree structure. Users can expand or shrank the rows. – user3097695 Oct 08 '19 at 22:43

2 Answers2

4

It is possible, see an example here: https://stackblitz.com/edit/angular-m77g7e-semvxp?file=app%2Ftable-basic-example.html

Referenced in https://github.com/angular/components/issues/15187.

Another option is to have two mat-tree components, one for traversing the hierarchy, the other for the fixed columns. You can use the treeControl.isExpanded(node) to toggle visibility on both components. (This will work for the cdk-tree component too.)

Avi Kaminetzky
  • 1,489
  • 2
  • 19
  • 42
3

Of course it's possible! It's just a directive that allows HTML.

enter image description here

I didn't stub one all the way out but the gist of it is really simple:

  const TREE_DATA: Employee[] = [
  {
    name: 'Bob',
    position:'President of Lattes'    
  }, {
    name: 'Becky',
    position: 'Manager Of Latte Presidents',
    reports: [{
        name: 'Bob',
        position:'President of Lattes'  
      }, {
        name: 'Steve',
        position: 'President of Mocha-Locha'
      },
      {
        name: 'Arnie',
        position: 'President of Tepid-Teas',
        reports: [
           {
              name: 'Mick',
              position: 'Loose orders for loose leaf'
           },
           {
              name: 'Michelle',
              position: 'The First With The Green'
           }
        ]
      }
      ]
  },
];

And the HTML

<mat-tree [dataSource]="dataSource" [treeControl]="treeControl" class="example-tree">


<!-- This is the tree node template for leaf nodes -->
  <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
    <li class="mat-tree-node">
      <!-- use a disabled button to provide padding for tree leaf -->
      <button mat-icon-button disabled></button>
      <div class="container-fluid">
          <div class="row">
              <div class="col">{{node.name}}</div>
              <div class="col">{{node.position}}</div>
              <div class="col">salary here</div>
              <div class="col">Years of Service</div>
          </div>
        </div>
    </li>
  </mat-tree-node>
  <!-- This is the tree node template for expandable nodes -->
  <mat-nested-tree-node *matTreeNodeDef="let node; when: hasChild">
    <li>
      <div class="mat-tree-node ">
        <button mat-icon-button matTreeNodeToggle
                [attr.aria-label]="'toggle ' + node.name">
          <mat-icon class="mat-icon-rtl-mirror">
            {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
          </mat-icon>
        </button>
        <div class="container-fluid">
          <div class="row">
              <div class="col">{{node.name}}</div>
              <div class="col">{{node.position}}</div>
              <div class="col">salary</div>
              <div class="col">0</div>
          </div>
        </div>
      </div>
      <ul [class.example-tree-invisible]="!treeControl.isExpanded(node)">
        <ng-container matTreeNodeOutlet></ng-container>
      </ul>
    </li>
  </mat-nested-tree-node>
</mat-tree>

And to really see it, you can check out the StackBlitz

Austin T French
  • 5,022
  • 1
  • 22
  • 40
  • The problem is that column is not aligned vertically. I got a similar display using left-margin. – user3097695 Oct 08 '19 at 22:59
  • @user3097695 I would agree that is a problem out of the box. However you didn't ask that **at all** in your original question. Please take a second to reflect on what you actually asked and not what you meant. I'd suggest asking a more complete question for that (since it appears you meant something else) rather than moving the goal-posts on your current question... (And closing / accepting / deleting this one as you see fit) – Austin T French Oct 08 '19 at 23:02
  • 1
    Thanks for coming up a solution so quickly. I up voted your solution. But, I still need to solve my problem. – user3097695 Oct 08 '19 at 23:14
  • @user3097695 I get that for sure! I'd ask a question for how to align columns nested in a tree with your current code. That way people can attempt to answer your actual problem – Austin T French Oct 08 '19 at 23:23