kuni преди 3 седмици
родител
ревизия
edabe3bbad

+ 38
- 21
src/app/pages/danka-detail/danka-detail.html Целия файл

@@ -320,7 +320,7 @@
320 320
             <div class="family-tree-diagram">
321 321
               <div class="family-tree-svg-container">
322 322
 
323
-                <svg #familyTreeSvg width="3000" height="3000">
323
+                <svg #familyTreeSvg width="1000" height="1000">
324 324
 
325 325
                   @for (
326 326
                   layout of unitLayouts;
@@ -339,15 +339,23 @@
339 339
                   as childLayout
340 340
                   ) {
341 341
 
342
-                  <line [attr.x1]="layout.x + 160" [attr.y1]="layout.y + 80" [attr.x2]="layout.x + 160"
343
-                    [attr.y2]="((layout.y + 80) + childLayout.y) / 2" stroke="black" stroke-width="2" />
342
+                  <!-- 親から中間点 -->
344 343
 
345
-                  <line [attr.x1]="layout.x + 160" [attr.y1]="((layout.y + 80) + childLayout.y) / 2"
346
-                    [attr.x2]="childLayout.x + 160" [attr.y2]="((layout.y + 80) + childLayout.y) / 2" stroke="black"
344
+                  <line [attr.x1]="getCenterX(layout)" [attr.y1]="getBottomCenterY(layout)"
345
+                    [attr.x2]="getCenterX(layout)" [attr.y2]="getMiddleY(layout, childLayout)" stroke="black"
347 346
                     stroke-width="2" />
348 347
 
349
-                  <line [attr.x1]="childLayout.x + 160" [attr.y1]="((layout.y + 80) + childLayout.y) / 2"
350
-                    [attr.x2]="childLayout.x + 160" [attr.y2]="childLayout.y" stroke="black" stroke-width="2" />
348
+                  <!-- 横線 -->
349
+
350
+                  <line [attr.x1]="getCenterX(layout)" [attr.y1]="getMiddleY(layout, childLayout)"
351
+                    [attr.x2]="getCenterX(childLayout)" [attr.y2]="getMiddleY(layout, childLayout)" stroke="black"
352
+                    stroke-width="2" />
353
+
354
+                  <!-- 子へ -->
355
+
356
+                  <line [attr.x1]="getCenterX(childLayout)" [attr.y1]="getMiddleY(layout, childLayout)"
357
+                    [attr.x2]="getCenterX(childLayout)" [attr.y2]="getTopCenterY(childLayout)" stroke="black"
358
+                    stroke-width="2" />
351 359
 
352 360
                   }
353 361
 
@@ -360,30 +368,36 @@
360 368
                   track layout.node.unit.id
361 369
                   ) {
362 370
 
371
+                  <!-- 夫婦線 -->
372
+
363 373
                   @if (
364 374
                   layout.node.unit.husband &&
365 375
                   layout.node.unit.wife
366 376
                   ) {
367 377
 
368
-                  <line [attr.x1]="layout.x + 140" [attr.y1]="layout.y + 35" [attr.x2]="layout.x + 180"
369
-                    [attr.y2]="layout.y + 35" stroke="red" stroke-width="2" />
378
+                  <line [attr.x1]="layout.x + PERSON_WIDTH" [attr.y1]="layout.y + PERSON_HEIGHT / 2"
379
+                    [attr.x2]="layout.x + PERSON_WIDTH + SPOUSE_GAP" [attr.y2]="layout.y + PERSON_HEIGHT / 2"
380
+                    stroke="red" stroke-width="2" />
370 381
 
371 382
                   }
372 383
 
373
-
374 384
                   <!-- 夫 -->
375 385
 
376 386
                   @if (
377 387
                   layout.node.unit.husband
378 388
                   ) {
379 389
 
380
-                  <rect [attr.x]="layout.x" [attr.y]="layout.y" width="140" height="70" fill="#dbeafe" stroke="black"
390
+                  <rect [attr.x]="getHusbandX(layout)" [attr.y]="layout.y" [attr.width]="PERSON_WIDTH"
391
+                    [attr.height]="PERSON_HEIGHT" fill="#dbeafe"
392
+                    [attr.stroke]="selectedFamily?.id === layout.node.unit.husband?.id ? '#2563eb' : 'black'"
381 393
                     class="family-node" (click)="selectFamily(layout.node.unit.husband!)" />
382
-                  <text [attr.x]="layout.x + 10" [attr.y]="layout.y + 40" class="family-text" (click)="selectFamily(layout.node.unit.husband!)">
383 394
 
384
-                    {{
385
-                    layout.node.unit.husband.name
386
-                    }}
395
+                  <text [attr.x]="getHusbandTextX(layout)" [attr.y]="layout.y + 20"
396
+                    style="writing-mode: vertical-rl;"
397
+                    [attr.stroke-width]="selectedFamily?.id === layout.node.unit.husband?.id ? 3 : 1"
398
+                    class="family-text" (click)="selectFamily(layout.node.unit.husband!)">
399
+
400
+                    {{ layout.node.unit.husband.name }}
387 401
 
388 402
                   </text>
389 403
 
@@ -395,14 +409,17 @@
395 409
                   layout.node.unit.wife
396 410
                   ) {
397 411
 
398
-                  <rect [attr.x]="layout.x + 180" [attr.y]="layout.y" width="140" height="70" fill="#fde2e2"
399
-                    stroke="black" class="family-node" (click)="selectFamily(layout.node.unit.wife!)" />
412
+                  <rect [attr.x]="getWifeX(layout)" [attr.y]="layout.y" [attr.width]="PERSON_WIDTH"
413
+                    [attr.height]="PERSON_HEIGHT" fill="#fde2e2"
414
+                    [attr.stroke]="selectedFamily?.id === layout.node.unit.wife?.id ? '#dc2626' : 'black'"
415
+                    class="family-node" (click)="selectFamily(layout.node.unit.wife!)" />
400 416
 
401
-                  <text [attr.x]="layout.x + 190" [attr.y]="layout.y + 40" class="family-text" (click)="selectFamily(layout.node.unit.husband!)">
417
+                  <text [attr.x]="getWifeTextX(layout)" [attr.y]="layout.y + 20"
418
+                    style="writing-mode: vertical-rl;"
419
+                    [attr.stroke-width]="selectedFamily?.id === layout.node.unit.wife?.id ? 3 : 1" class="family-text"
420
+                    (click)="selectFamily(layout.node.unit.wife!)">
402 421
 
403
-                    {{
404
-                    layout.node.unit.wife.name
405
-                    }}
422
+                    {{ layout.node.unit.wife.name }}
406 423
 
407 424
                   </text>
408 425
 

+ 106
- 8
src/app/pages/danka-detail/danka-detail.ts Целия файл

@@ -63,6 +63,10 @@ export class DankaDetail implements AfterViewInit {
63 63
   familyTreeSvg?: ElementRef<SVGSVGElement>;
64 64
   private panZoomInstance: any;
65 65
 
66
+  readonly PERSON_WIDTH = 70;
67
+  readonly PERSON_HEIGHT = 140;
68
+  readonly SPOUSE_GAP = 20;
69
+
66 70
   constructor(
67 71
     private dankaService: DankaService,
68 72
     private familyService: FamilyService,
@@ -147,22 +151,18 @@ export class DankaDetail implements AfterViewInit {
147 151
       this.familyTreeSvg.nativeElement,
148 152
       {
149 153
         zoomEnabled: true,
150
-
151
-        controlIconsEnabled: true,
154
+        panEnabled: true,
152 155
 
153 156
         fit: true,
154
-
155 157
         center: true,
156 158
 
157
-        minZoom: 0.2,
158
-
159
-        maxZoom: 20,
159
+        minZoom: 0.0001,
160
+        maxZoom: 500,
160 161
 
161 162
         mouseWheelZoomEnabled: true,
162
-
163 163
         dblClickZoomEnabled: true,
164 164
 
165
-        panEnabled: true
165
+        zoomScaleSensitivity: 0.15
166 166
       }
167 167
     );
168 168
   }
@@ -466,4 +466,102 @@ export class DankaDetail implements AfterViewInit {
466 466
 
467 467
   }
468 468
 
469
+  getCenterX(layout: FamilyUnitLayout): number {
470
+
471
+    return (
472
+      layout.x +
473
+      this.PERSON_WIDTH +
474
+      this.SPOUSE_GAP / 2
475
+    );
476
+
477
+  }
478
+
479
+  getTopCenterY(
480
+    layout: FamilyUnitLayout
481
+  ): number {
482
+
483
+    return layout.y;
484
+
485
+  }
486
+
487
+  getBottomCenterY(
488
+    layout: FamilyUnitLayout
489
+  ): number {
490
+
491
+    return (
492
+      layout.y +
493
+      this.PERSON_HEIGHT
494
+    );
495
+
496
+  }
497
+
498
+  getMiddleY(
499
+    parent: FamilyUnitLayout,
500
+    child: FamilyUnitLayout
501
+  ): number {
502
+
503
+    return (
504
+      this.getBottomCenterY(parent)
505
+      +
506
+      child.y
507
+    ) / 2;
508
+
509
+  }
510
+
511
+  getHusbandX(
512
+    layout: FamilyUnitLayout
513
+  ): number {
514
+
515
+    if (!layout.node.unit.wife) {
516
+      return (
517
+        layout.x +
518
+        (this.PERSON_WIDTH + this.SPOUSE_GAP) / 2
519
+      );
520
+    }
521
+
522
+    return layout.x;
523
+
524
+  }
525
+
526
+  getWifeX(
527
+    layout: FamilyUnitLayout
528
+  ): number {
529
+
530
+    if (!layout.node.unit.husband) {
531
+      return (
532
+        layout.x +
533
+        (this.PERSON_WIDTH + this.SPOUSE_GAP) / 2
534
+      );
535
+    }
536
+
537
+    return (
538
+      layout.x +
539
+      this.PERSON_WIDTH +
540
+      this.SPOUSE_GAP
541
+    );
542
+
543
+  }
544
+
545
+  getHusbandTextX(
546
+    layout: FamilyUnitLayout
547
+  ): number {
548
+
549
+    return (
550
+      this.getHusbandX(layout)
551
+      + this.PERSON_WIDTH / 2
552
+    );
553
+
554
+  }
555
+
556
+  getWifeTextX(
557
+    layout: FamilyUnitLayout
558
+  ): number {
559
+
560
+    return (
561
+      this.getWifeX(layout)
562
+      + this.PERSON_WIDTH / 2
563
+    );
564
+
565
+  }
566
+
469 567
 }

+ 1
- 1
src/app/services/family-tree-layout.ts Целия файл

@@ -18,7 +18,7 @@ export class FamilyTreeLayoutService {
18 18
   private readonly HORIZONTAL_GAP = 200;
19 19
   private readonly VERTICAL_GAP = 200;
20 20
 
21
-  private readonly SPOUSE_GAP = 180;
21
+  private readonly SPOUSE_GAP = 180;  
22 22
 
23 23
   private processedCouples = new Set<string>();
24 24
   private currentX = 0;

+ 13
- 4
src/app/services/family-unit-layout.ts Целия файл

@@ -11,13 +11,22 @@ import { FamilyUnitLayout }
11 11
 })
12 12
 export class FamilyUnitLayoutService {
13 13
 
14
-  private readonly UNIT_WIDTH = 320;
14
+  private readonly HORIZONTAL_GAP = 100;
15
+  private readonly VERTICAL_GAP = 180;
15 16
 
16
-  private readonly UNIT_HEIGHT = 80;
17
+  private readonly PERSON_WIDTH = 70;
18
+  private readonly PERSON_HEIGHT = 140;
17 19
 
18
-  private readonly HORIZONTAL_GAP = 100;
20
+  private readonly SPOUSE_GAP = 20;
21
+
22
+  // 夫婦1組のサイズ
23
+  private readonly UNIT_WIDTH =
24
+    this.PERSON_WIDTH * 2 +
25
+    this.SPOUSE_GAP;
26
+
27
+  private readonly UNIT_HEIGHT =
28
+    this.PERSON_HEIGHT;
19 29
 
20
-  private readonly VERTICAL_GAP = 180;
21 30
 
22 31
   private currentX = 0;
23 32
 

Loading…
Отказ
Запис