Can build ascending tree
This commit is contained in:
		@@ -122,7 +122,10 @@ export function FamilyMemberTreeRoute(): React.ReactElement {
 | 
				
			|||||||
        {currTab === CurrTab.BasicTree ? (
 | 
					        {currTab === CurrTab.BasicTree ? (
 | 
				
			||||||
          <BasicFamilyTree tree={tree!} />
 | 
					          <BasicFamilyTree tree={tree!} />
 | 
				
			||||||
        ) : (
 | 
					        ) : (
 | 
				
			||||||
          <ComplexFamilyTree tree={tree!} />
 | 
					          <ComplexFamilyTree
 | 
				
			||||||
 | 
					            tree={tree!}
 | 
				
			||||||
 | 
					            isUp={currMode === TreeMode.Ascending}
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
        )}
 | 
					        )}
 | 
				
			||||||
      </Paper>
 | 
					      </Paper>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,16 +2,17 @@ import React from "react";
 | 
				
			|||||||
import f3, { f3Data } from "family-chart";
 | 
					import f3, { f3Data } from "family-chart";
 | 
				
			||||||
import "./family-chart.css";
 | 
					import "./family-chart.css";
 | 
				
			||||||
import { FamilyTreeNode } from "../../utils/family_tree";
 | 
					import { FamilyTreeNode } from "../../utils/family_tree";
 | 
				
			||||||
import { fmtDate } from "../../api/MemberApi";
 | 
					import { Member, fmtDate } from "../../api/MemberApi";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function ComplexFamilyTree(p: {
 | 
					export function ComplexFamilyTree(p: {
 | 
				
			||||||
  tree: FamilyTreeNode;
 | 
					  tree: FamilyTreeNode;
 | 
				
			||||||
 | 
					  isUp: boolean;
 | 
				
			||||||
}): React.ReactElement {
 | 
					}): React.ReactElement {
 | 
				
			||||||
  const refCb = (container: HTMLDivElement) => {
 | 
					  const refCb = (container: HTMLDivElement) => {
 | 
				
			||||||
    if (!container) return;
 | 
					    if (!container) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const store = f3.createStore({
 | 
					    const store = f3.createStore({
 | 
				
			||||||
        data: treeToF3Data(p.tree),
 | 
					        data: treeToF3Data(p.tree, p.isUp),
 | 
				
			||||||
        node_separation: 250,
 | 
					        node_separation: 250,
 | 
				
			||||||
        level_separation: 150,
 | 
					        level_separation: 150,
 | 
				
			||||||
      }),
 | 
					      }),
 | 
				
			||||||
@@ -48,12 +49,14 @@ export function ComplexFamilyTree(p: {
 | 
				
			|||||||
  return <div className="f3" id="FamilyChart" ref={refCb}></div>;
 | 
					  return <div className="f3" id="FamilyChart" ref={refCb}></div>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function treeToF3Data(node: FamilyTreeNode): f3Data[] {
 | 
					function treeToF3Data(node: FamilyTreeNode, isUp: boolean): f3Data[] {
 | 
				
			||||||
  const availableMembers = new Set<number>();
 | 
					  const availableMembers = new Set<number>();
 | 
				
			||||||
  getAvailableMembers(node, availableMembers);
 | 
					  getAvailableMembers(node, availableMembers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const list: f3Data[] = [];
 | 
					  const list: f3Data[] = [];
 | 
				
			||||||
  treeToF3DataRecurse(node, list, availableMembers);
 | 
					  if (isUp) {
 | 
				
			||||||
 | 
					    treeToF3DataUpRecurse(node, list, availableMembers);
 | 
				
			||||||
 | 
					  } else treeToF3DataDownRecurse(node, list, availableMembers);
 | 
				
			||||||
  console.info(list);
 | 
					  console.info(list);
 | 
				
			||||||
  return list;
 | 
					  return list;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -69,7 +72,57 @@ function getAvailableMembers(t: FamilyTreeNode, s: Set<number>) {
 | 
				
			|||||||
  t.down?.forEach((e) => getAvailableMembers(e, s));
 | 
					  t.down?.forEach((e) => getAvailableMembers(e, s));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function treeToF3DataRecurse(
 | 
					function memberData(m: Member): f3.f3DataData {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    first_name: m.first_name ?? "_",
 | 
				
			||||||
 | 
					    last_name: m.last_name ?? "_",
 | 
				
			||||||
 | 
					    gender: m.sex ?? "M",
 | 
				
			||||||
 | 
					    avatar: m.thumbnailURL ?? undefined,
 | 
				
			||||||
 | 
					    birthday: m.dateOfBirth ? fmtDate(m.dateOfBirth) : undefined,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function treeToF3DataUpRecurse(
 | 
				
			||||||
 | 
					  node: FamilyTreeNode,
 | 
				
			||||||
 | 
					  array: f3Data[],
 | 
				
			||||||
 | 
					  availableMembers: Set<number>,
 | 
				
			||||||
 | 
					  child?: number,
 | 
				
			||||||
 | 
					  spouses?: number[]
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					  array.push({
 | 
				
			||||||
 | 
					    data: memberData(node.member),
 | 
				
			||||||
 | 
					    id: node.member.id.toString(),
 | 
				
			||||||
 | 
					    rels: {
 | 
				
			||||||
 | 
					      father:
 | 
				
			||||||
 | 
					        node.member.father && availableMembers.has(node.member.father)
 | 
				
			||||||
 | 
					          ? node.member.father.toString()
 | 
				
			||||||
 | 
					          : undefined,
 | 
				
			||||||
 | 
					      mother:
 | 
				
			||||||
 | 
					        node.member.mother && availableMembers.has(node.member.mother)
 | 
				
			||||||
 | 
					          ? node.member.mother.toString()
 | 
				
			||||||
 | 
					          : undefined,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      spouses: spouses
 | 
				
			||||||
 | 
					        ?.filter((c) => c !== node.member.id)
 | 
				
			||||||
 | 
					        .map((c) => c.toString()),
 | 
				
			||||||
 | 
					      children: child ? [child.toString()] : undefined,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const parentSpouses = node.down?.map((c) => c.member.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  node.down?.forEach((d) =>
 | 
				
			||||||
 | 
					    treeToF3DataUpRecurse(
 | 
				
			||||||
 | 
					      d,
 | 
				
			||||||
 | 
					      array,
 | 
				
			||||||
 | 
					      availableMembers,
 | 
				
			||||||
 | 
					      node.member.id,
 | 
				
			||||||
 | 
					      parentSpouses
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function treeToF3DataDownRecurse(
 | 
				
			||||||
  node: FamilyTreeNode,
 | 
					  node: FamilyTreeNode,
 | 
				
			||||||
  array: f3Data[],
 | 
					  array: f3Data[],
 | 
				
			||||||
  availableMembers: Set<number>
 | 
					  availableMembers: Set<number>
 | 
				
			||||||
@@ -81,15 +134,7 @@ function treeToF3DataRecurse(
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  array.push({
 | 
					  array.push({
 | 
				
			||||||
    data: {
 | 
					    data: memberData(node.member),
 | 
				
			||||||
      first_name: node.member.first_name ?? "_",
 | 
					 | 
				
			||||||
      last_name: node.member.last_name ?? "_",
 | 
					 | 
				
			||||||
      gender: node.member.sex ?? "M",
 | 
					 | 
				
			||||||
      avatar: node.member.thumbnailURL ?? undefined,
 | 
					 | 
				
			||||||
      birthday: node.member.dateOfBirth
 | 
					 | 
				
			||||||
        ? fmtDate(node.member.dateOfBirth)
 | 
					 | 
				
			||||||
        : undefined,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    id: node.member.id.toString(),
 | 
					    id: node.member.id.toString(),
 | 
				
			||||||
    rels: {
 | 
					    rels: {
 | 
				
			||||||
      father:
 | 
					      father:
 | 
				
			||||||
@@ -106,20 +151,14 @@ function treeToF3DataRecurse(
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  node?.down?.forEach((e) => treeToF3DataRecurse(e, array, availableMembers));
 | 
					  node?.down?.forEach((e) =>
 | 
				
			||||||
 | 
					    treeToF3DataDownRecurse(e, array, availableMembers)
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (node.couples) {
 | 
					  if (node.couples) {
 | 
				
			||||||
    for (const c of node.couples) {
 | 
					    for (const c of node.couples) {
 | 
				
			||||||
      array.push({
 | 
					      array.push({
 | 
				
			||||||
        data: {
 | 
					        data: memberData(c.member),
 | 
				
			||||||
          first_name: c.member.first_name ?? "_",
 | 
					 | 
				
			||||||
          last_name: c.member.last_name ?? "_",
 | 
					 | 
				
			||||||
          gender: c.member.sex ?? "M",
 | 
					 | 
				
			||||||
          avatar: c.member.thumbnailURL ?? undefined,
 | 
					 | 
				
			||||||
          birthday: c.member.dateOfBirth
 | 
					 | 
				
			||||||
            ? fmtDate(c.member.dateOfBirth)
 | 
					 | 
				
			||||||
            : undefined,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        id: c.member.id.toString(),
 | 
					        id: c.member.id.toString(),
 | 
				
			||||||
        rels: {
 | 
					        rels: {
 | 
				
			||||||
          father:
 | 
					          father:
 | 
				
			||||||
@@ -135,7 +174,9 @@ function treeToF3DataRecurse(
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      c.down.forEach((e) => treeToF3DataRecurse(e, array, availableMembers));
 | 
					      c.down.forEach((e) =>
 | 
				
			||||||
 | 
					        treeToF3DataDownRecurse(e, array, availableMembers)
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user