yanweiyuan3
2023-08-09 588bc7829387dfc761cc25f06f77d4c81818bd10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
 * Row data are defined as name and (immediate) parent only.
 * DataHierarchyProvider class is able to query recursively to infer all ancestors.
 */
export interface DataHierarchy {
  Name: string;
  ParentKey: string;
  NameKey: string;
  OndrawImageName?: string;
}
 
/**
 * Provider class to get all ancestor row names by passing in the target child row.
 */
export class DataHierarchyProvider {
  private readonly store: Map<string, DataHierarchy> = new Map();
 
  public constructor(data: Record<string, DataHierarchy>) {
    for (const t of Object.keys(data)) {
      const a = data[t];
      this.store.set(a.NameKey, a); // Stores row data and its immediate parent
    }
  }
 
  /**
   * Given a row name, infer the ancestor rows.
   *
   * @param key Row name.
   * @returns Tuple containing row name and all ancestors.
   */
  public getHierarchy(key: DataHierarchy): [DataHierarchy, DataHierarchy[]] {
    // Recursive get all ancestor rows
    const ancestor = this.store.get(key.NameKey);
    let ancestorArr: DataHierarchy[] = [];
    ancestorArr = this.recursiveGetAncestor(ancestor!, ancestorArr);
    return [key, ancestorArr];
  }
 
  private recursiveGetAncestor(ancestor: DataHierarchy, ancestorArr: DataHierarchy[]): DataHierarchy[] {
    const hasParent = ancestor !== undefined && ancestor.ParentKey !== '';
    if (hasParent) {
      const ancestorName = this.store.get(ancestor.ParentKey);
      if (ancestorName) {
        ancestorArr = [ancestorName].concat(ancestorArr); // Put ancestor to the front of array
        ancestorArr = this.recursiveGetAncestor(ancestorName, ancestorArr);
      } else {
        throw(TypeError(`No Ancestor: ${ancestor.ParentKey} to be found.`));
      }
    }
    return ancestorArr;
  }
}