1<?php use Fisharebest\Webtrees\Functions\FunctionsPrint; ?> 2<?php use Fisharebest\Webtrees\I18N; ?> 3<?php use Fisharebest\Webtrees\Module\ModuleThemeInterface; ?> 4 5<div id="pedigree-page"> 6 <div id="pedigree_chart" class="layout<?= e($orientation) ?>"> 7 <?php foreach ($nodes as $i => $node) : ?> 8 <div id="sosa_<?= ($i + 1) ?>" class="shadow d-flex align-items-center<?= e($flex_direction) ?>" style="<?= e($posn) ?>:<?= e($node['x']) ?>px; top:<?= e($node['y']) ?>px; position:absolute;"> 9 <?php if ($orientation === $oldest_at_top) : ?> 10 <?php if ($i >= $last_gen_start) : ?> 11 <?= $node['previous_gen'] ?> 12 <?php endif ?> 13 <?php else : ?> 14 <?php if ($i === 0) : ?> 15 <?= $child_menu ?> 16 <?php endif ?> 17 <?php endif ?> 18 19 <?= FunctionsPrint::printPedigreePerson($nodes[$i]['indi']) ?> 20 21 <?php if ($orientation === $oldest_at_top) : ?> 22 <?php if ($i === 0) : ?> 23 <?= $child_menu ?> 24 <?php endif ?> 25 <?php else : ?> 26 <?php if ($i >= $last_gen_start) : ?> 27 <?= $node['previous_gen'] ?> 28 <?php endif ?> 29 <?php endif ?> 30 </div> 31 <?php endforeach ?> 32 <canvas id="pedigree_canvas" width="<?= e($canvas_width) ?>" height="<?= e($canvas_height) ?>"> 33 </canvas> 34 </div> 35</div> 36 37<script> 38 (function() { 39 $("#childarrow").on("click", ".menuselect", function(e) { 40 e.preventDefault(); 41 $("#childbox-pedigree").slideToggle("fast"); 42 }); 43 44 $("#pedigree_chart") 45 .width(<?= json_encode($canvas_width) ?>) 46 .height(<?= json_encode($canvas_height) ?>); 47 48 // Set variables 49 var p0, p1, p2, // Holds the ids of the boxes used in the join calculations 50 canvas = $("#pedigree_canvas"), 51 ctx = canvas[0].getContext("2d"), 52 nodes = $(".shadow").length, 53 gen1Start = Math.ceil(nodes / 2), 54 boxWidth = $(".person_box_template").first().outerWidth(), 55 boxHeight = $(".person_box_template").first().outerHeight(), 56 useOffset = true, 57 extraOffsetX = Math.floor(boxWidth / 15), // set offsets to be sensible fractions of the box size 58 extraOffsetY = Math.floor(boxHeight / 10), 59 addOffset; 60 61 // Draw joining lines on the <canvas> 62 function drawLines(context, x1, y1, x2, y2) { 63 x1 = Math.floor(x1); 64 y1 = Math.floor(y1); 65 x2 = Math.floor(x2); 66 y2 = Math.floor(y2); 67 if (<?= json_encode($orientation < $oldest_at_top) ?>) { 68 context.moveTo(x1, y1); 69 context.lineTo(x2, y1); 70 context.lineTo(x2, y2); 71 context.lineTo(x1, y2); 72 } else { 73 context.moveTo(x1, y1); 74 context.lineTo(x1, y2); 75 context.lineTo(x2, y2); 76 context.lineTo(x2, y1); 77 } 78 } 79 80 //Plot the lines 81 switch (<?= json_encode($orientation) ?>) { 82 case <?= json_encode($portrait) ?>: 83 useOffset = false; 84 // Drop through 85 case <?= json_encode($landscape) ?>: 86 for (var i = 2; i < nodes; i+=2) { 87 p0 = $("#sosa_" + i); 88 p1 = $("#sosa_" + (i+1)); 89 // change line y position if within 10% of box top/bottom 90 addOffset = boxHeight / (p1.position().top - p0.position().top) > 0.9 ? extraOffsetY: 0; 91 if (<?= json_encode(I18N::direction() === 'rtl') ?>) { 92 drawLines( 93 ctx, 94 p0.position().left + p0.width(), 95 p0.position().top + (boxHeight / 2) + addOffset, 96 p0.position().left + p0.width() + extraOffsetX, 97 p1.position().top + (boxHeight / 2) - addOffset 98 ); 99 } else { 100 drawLines( 101 ctx, 102 p0.position().left, 103 p0.position().top + (boxHeight / 2) + addOffset, 104 p0.position().left - extraOffsetX, 105 p1.position().top + (boxHeight / 2) - addOffset 106 ); 107 } 108 } 109 break; 110 case <?= json_encode($oldest_at_top) ?>: 111 useOffset = false; 112 // Drop through 113 case <?= json_encode($oldest_at_bottom) ?>: 114 for (var i = 1; i < gen1Start; i++) { 115 p0 = $("#sosa_" + i); 116 p1 = $("#sosa_" + (i*2)); 117 p2 = $("#sosa_" + (i*2+1)); 118 addOffset = i*2 >= gen1Start ? extraOffsetX : 0; 119 var templateHeight = p0.children(".person_box_template").outerHeight(), 120 // bHeight taks account of offset when root person has a menu icon 121 bHeight = useOffset ? (p0.outerHeight() - templateHeight) + (templateHeight / 2) : templateHeight / 2; 122 drawLines( 123 ctx, 124 p1.position().left + (boxWidth / 2) + addOffset, 125 p1.position().top + boxHeight, 126 p2.position().left + (boxWidth / 2) - addOffset, 127 p0.position().top + bHeight 128 ); 129 } 130 break; 131 } 132 133 // Set line styles & draw them 134 ctx.strokeStyle = canvas.css("color"); 135 ctx.lineWidth = <?= json_encode(app()->make(ModuleThemeInterface::class)->parameter('line-width')) ?>; 136 ctx.shadowColor = <?= json_encode(app()->make(ModuleThemeInterface::class)->parameter('shadow-color')) ?>; 137 ctx.shadowBlur = <?= json_encode(app()->make(ModuleThemeInterface::class)->parameter('shadow-blur')) ?>; 138 ctx.shadowOffsetX = <?= json_encode(app()->make(ModuleThemeInterface::class)->parameter('shadow-offset-x')) ?>; 139 ctx.shadowOffsetY = <?= json_encode(app()->make(ModuleThemeInterface::class)->parameter('shadow-offset-y')) ?>; 140 ctx.stroke(); 141 })(); 142</script> 143