kuni 2 weeks ago
parent
commit
aeccc2b2d4

+ 5
- 2
src/app/models/familytreenode.ts View File

1
 import { Family } from "./family";
1
 import { Family } from "./family";
2
+import { Kakocho } from "./kakocho";
2
 
3
 
3
 export interface FamilyTreeNode {
4
 export interface FamilyTreeNode {
4
   family: Family;
5
   family: Family;
5
 
6
 
6
-  spouses: FamilyTreeNode[];
7
+  kakocho?: Kakocho;   // ★追加(ここが核心)
7
 
8
 
8
-  children: FamilyTreeNode[];
9
+  isDeceased: boolean; // ★追加
9
 
10
 
11
+  spouses: FamilyTreeNode[];
12
+  children: FamilyTreeNode[];
10
   parents: FamilyTreeNode[];
13
   parents: FamilyTreeNode[];
11
 }
14
 }

+ 9
- 1
src/app/pages/danka-detail/danka-detail.ts View File

72
 
72
 
73
   @ViewChild('familyTreeSvg')
73
   @ViewChild('familyTreeSvg')
74
   familyTreeSvg?: ElementRef<SVGSVGElement>;
74
   familyTreeSvg?: ElementRef<SVGSVGElement>;
75
+  @ViewChild('familyTreeSvg')
76
+  set svg(el: ElementRef<SVGSVGElement> | undefined) {
77
+    if (!el) return;
78
+
79
+    this.familyTreeSvg = el;
80
+    this.initializePanZoom();
81
+  }
75
   private panZoomInstance: any;
82
   private panZoomInstance: any;
76
 
83
 
77
   readonly PERSON_WIDTH = 90;
84
   readonly PERSON_WIDTH = 90;
132
     this.treeNodes =
139
     this.treeNodes =
133
       this.familyTreeBuilder.build(
140
       this.familyTreeBuilder.build(
134
         this.families,
141
         this.families,
135
-        this.marriageRelations
142
+        this.marriageRelations,
143
+        this.kakocholist
136
       );
144
       );
137
 
145
 
138
     const units =
146
     const units =

+ 60
- 168
src/app/services/family-tree-builder.ts View File

1
 import { Injectable } from '@angular/core';
1
 import { Injectable } from '@angular/core';
2
-
3
 import { Family } from '../models/family';
2
 import { Family } from '../models/family';
4
 import { MarriageRelation } from '../models/marriage-relation';
3
 import { MarriageRelation } from '../models/marriage-relation';
4
+import { Kakocho } from '../models/kakocho';
5
 import { FamilyUnit } from '../models/family-unit';
5
 import { FamilyUnit } from '../models/family-unit';
6
 import { FamilyUnitNode } from '../models/family-unit-node';
6
 import { FamilyUnitNode } from '../models/family-unit-node';
7
 
7
 
8
+
8
 export interface FamilyTreeNode {
9
 export interface FamilyTreeNode {
9
   family: Family;
10
   family: Family;
10
-
11
-  parents: FamilyTreeNode[];
12
-
13
-  children: FamilyTreeNode[];
11
+  kakocho?: Kakocho;
12
+  isDeceased: boolean;
14
 
13
 
15
   spouses: FamilyTreeNode[];
14
   spouses: FamilyTreeNode[];
15
+  children: FamilyTreeNode[];
16
+  parents: FamilyTreeNode[];
16
 }
17
 }
17
 
18
 
18
 @Injectable({
19
 @Injectable({
23
   build(
24
   build(
24
     families: Family[],
25
     families: Family[],
25
     marriages: MarriageRelation[],
26
     marriages: MarriageRelation[],
27
+    kakocholist: Kakocho[]
26
   ): FamilyTreeNode[] {
28
   ): FamilyTreeNode[] {
27
 
29
 
28
     const nodeMap = new Map<string, FamilyTreeNode>();
30
     const nodeMap = new Map<string, FamilyTreeNode>();
29
 
31
 
30
-    //
31
-    // ノード生成
32
-    //
32
+    const kakochoMap = new Map(
33
+      kakocholist.map(k => [k.familyId, k])
34
+    );
35
+
36
+    // -----------------------------
37
+    // ① ノード生成(ここで統合)
38
+    // -----------------------------
33
     families.forEach((family) => {
39
     families.forEach((family) => {
34
 
40
 
41
+      const kakocho = kakochoMap.get(family.id);
42
+
35
       nodeMap.set(family.id, {
43
       nodeMap.set(family.id, {
36
         family,
44
         family,
45
+        kakocho,
46
+        isDeceased: !!kakocho,
47
+
37
         parents: [],
48
         parents: [],
38
         children: [],
49
         children: [],
39
         spouses: [],
50
         spouses: [],
41
 
52
 
42
     });
53
     });
43
 
54
 
44
-    //
45
-    // 親子関係生成
46
-    //
55
+    // -----------------------------
56
+    // 親子関係
57
+    // -----------------------------
47
     families.forEach((family) => {
58
     families.forEach((family) => {
48
 
59
 
49
       const childNode = nodeMap.get(family.id);
60
       const childNode = nodeMap.get(family.id);
61
+      if (!childNode) return;
50
 
62
 
51
-      if (!childNode) {
52
-        return;
53
-      }
54
-
55
-      //
56
-      // 父
57
-      //
58
       if (family.fatherId) {
63
       if (family.fatherId) {
59
-
60
-        const fatherNode =
61
-          nodeMap.get(family.fatherId);
62
-
63
-        if (fatherNode) {
64
-
65
-          fatherNode.children.push(childNode);
66
-
67
-          childNode.parents.push(fatherNode);
64
+        const father = nodeMap.get(family.fatherId);
65
+        if (father) {
66
+          father.children.push(childNode);
67
+          childNode.parents.push(father);
68
         }
68
         }
69
       }
69
       }
70
 
70
 
71
-      //
72
-      // 母
73
-      //
74
       if (family.motherId) {
71
       if (family.motherId) {
75
-
76
-        const motherNode =
77
-          nodeMap.get(family.motherId);
78
-
79
-        if (motherNode) {
80
-
81
-          motherNode.children.push(childNode);
82
-
83
-          childNode.parents.push(motherNode);
72
+        const mother = nodeMap.get(family.motherId);
73
+        if (mother) {
74
+          mother.children.push(childNode);
75
+          childNode.parents.push(mother);
84
         }
76
         }
85
       }
77
       }
86
 
78
 
87
     });
79
     });
88
 
80
 
89
-    //
90
-    // 配偶者関係
91
-    //
81
+    // -----------------------------
82
+    // 配偶者関係(current)
83
+    // -----------------------------
92
     marriages
84
     marriages
93
-      .filter(
94
-        (m) =>
95
-          m.status === 'current',
96
-      )
97
-      .forEach((marriage) => {
98
-
99
-        const person1 =
100
-          nodeMap.get(
101
-            marriage.person1Id,
102
-          );
103
-
104
-        const person2 =
105
-          nodeMap.get(
106
-            marriage.person2Id,
107
-          );
108
-
109
-        if (!person1 || !person2) {
110
-          return;
111
-        }
112
-
113
-        const id1 =
114
-          Number(person1.family.id);
85
+      .filter(m => m.status === 'current')
86
+      .forEach((m) => {
115
 
87
 
116
-        const id2 =
117
-          Number(person2.family.id);
88
+        const p1 = nodeMap.get(m.person1Id);
89
+        const p2 = nodeMap.get(m.person2Id);
118
 
90
 
119
-        const owner =
120
-          id1 < id2
121
-            ? person1
122
-            : person2;
91
+        if (!p1 || !p2) return;
123
 
92
 
124
-        const spouse =
125
-          id1 < id2
126
-            ? person2
127
-            : person1;
128
-
129
-        if (
130
-          !owner.spouses.some(
131
-            (s) =>
132
-              s.family.id ===
133
-              spouse.family.id,
134
-          )
135
-        ) {
136
-          owner.spouses.push(
137
-            spouse,
138
-          );
93
+        if (!p1.spouses.some(s => s.family.id === p2.family.id)) {
94
+          p1.spouses.push(p2);
139
         }
95
         }
140
-      });
141
-
142
-    //
143
-    // spouseId フォールバック
144
-    //
145
-    families.forEach((family) => {
146
 
96
 
147
-      if (!family.spouseId) {
148
-        return;
149
-      }
97
+      });
150
 
98
 
151
-      const person =
152
-        nodeMap.get(family.id);
99
+    // -----------------------------
100
+    // ④ spouseIdフォールバック
101
+    // -----------------------------
102
+    families.forEach((f) => {
153
 
103
 
154
-      const spouse =
155
-        nodeMap.get(family.spouseId);
104
+      if (!f.spouseId) return;
156
 
105
 
157
-      if (!person || !spouse) {
158
-        return;
159
-      }
106
+      const a = nodeMap.get(f.id);
107
+      const b = nodeMap.get(f.spouseId);
160
 
108
 
161
-      if (
162
-        !person.spouses.some(
163
-          (s) =>
164
-            s.family.id ===
165
-            spouse.family.id
166
-        )
167
-      ) {
109
+      if (!a || !b) return;
168
 
110
 
169
-        person.spouses.push(
170
-          spouse
171
-        );
111
+      if (!a.spouses.some(s => s.family.id === b.family.id)) {
112
+        a.spouses.push(b);
172
       }
113
       }
173
 
114
 
174
     });
115
     });
176
     return [...nodeMap.values()];
117
     return [...nodeMap.values()];
177
   }
118
   }
178
 
119
 
179
-  /**
180
-   * 家系図の起点になる人物
181
-   * (親が登録されていない人物)
182
-   */
183
-  getRoots(
184
-    nodes: FamilyTreeNode[]
185
-  ): FamilyTreeNode[] {
120
+  // -----------------------------
121
+  // Roots
122
+  // -----------------------------
123
+  getRoots(nodes: FamilyTreeNode[]): FamilyTreeNode[] {
186
 
124
 
187
     return nodes.filter(node => {
125
     return nodes.filter(node => {
188
 
126
 
189
-      if (
190
-        node.parents.length > 0
191
-      ) {
192
-        return false;
193
-      }
194
-
195
-      // 配偶者がいて
196
-      if (
197
-        node.spouses.length > 0
198
-      ) {
127
+      if (node.parents.length > 0) return false;
199
 
128
 
200
-        const spouseId =
201
-          node.spouses[0].family.id;
202
-
203
-        // IDが若い方だけRoot
204
-        return (
205
-          node.family.id <
206
-          spouseId
207
-        );
129
+      if (node.spouses.length > 0) {
130
+        const spouseId = node.spouses[0].family.id;
131
+        return node.family.id < spouseId;
208
       }
132
       }
209
 
133
 
210
       return true;
134
       return true;
211
-
212
     });
135
     });
213
-
214
-  }
215
-
216
-  /**
217
-   * ID検索
218
-   */
219
-  getNodeById(
220
-    nodes: FamilyTreeNode[],
221
-    id: string,
222
-  ): FamilyTreeNode | undefined {
223
-
224
-    return nodes.find(
225
-      (node) =>
226
-        node.family.id === id,
227
-    );
228
   }
136
   }
229
 
137
 
230
   buildFamilyUnits(
138
   buildFamilyUnits(
238
 
146
 
239
     for (const node of nodes) {
147
     for (const node of nodes) {
240
 
148
 
241
-      //
242
-      // 夫婦あり
243
-      //
244
       if (node.spouses.length > 0) {
149
       if (node.spouses.length > 0) {
245
 
150
 
246
         const spouse =
151
         const spouse =
262
 
167
 
263
         processed.add(key);
168
         processed.add(key);
264
 
169
 
265
-        //
266
-        // この夫婦の子供を取得
267
-        //
268
         const children =
170
         const children =
269
           nodes
171
           nodes
270
             .filter(child => {
172
             .filter(child => {
310
 
212
 
311
       } else {
213
       } else {
312
 
214
 
313
-        //
314
-        // 独身者
315
-        //
316
         units.push({
215
         units.push({
317
 
216
 
318
           id:
217
           id:
346
     const nodeMap =
245
     const nodeMap =
347
       new Map<string, FamilyUnitNode>();
246
       new Map<string, FamilyUnitNode>();
348
 
247
 
349
-    //
350
-    // ノード生成
351
-    //
352
     units.forEach(unit => {
248
     units.forEach(unit => {
353
 
249
 
354
       nodeMap.set(unit.id, {
250
       nodeMap.set(unit.id, {
363
 
259
 
364
     });
260
     });
365
 
261
 
366
-    //
367
-    // 親子リンク
368
-    //
369
     units.forEach(parentUnit => {
262
     units.forEach(parentUnit => {
370
 
263
 
371
       parentUnit.children.forEach(child => {
264
       parentUnit.children.forEach(child => {
417
     );
310
     );
418
 
311
 
419
   }
312
   }
420
-
421
 }
313
 }

Loading…
Cancel
Save