public function __construct() { parent::__construct(); // Extract the request parameters $this->show_thumbs = WT_Filter::getBool('show_thumbs'); if ($this->root && $this->root->canShowName()) { $this->setPageTitle(WT_I18N::translate('Compact tree of %s', $this->root->getFullName())); } else { $this->setPageTitle(WT_I18N::translate('Compact tree')); } $this->treeid = ancestry_array($this->rootid, 5); }
print "<td class=\"optionbox\">"; print "<select name=\"PEDIGREE_GENERATIONS\">"; // Can only show 9 generations (256 ancestors) as graphics library has integer degree resolution for ($i = 2; $i <= min(9, $MAX_PEDIGREE_GENERATIONS); $i++) { print "<option value=\"" . $i . "\""; if ($i == $PEDIGREE_GENERATIONS) { print "selected=\"selected\" "; } print ">" . $i . "</option>"; } print "</select>"; print "</td>"; print "</tr><tr>"; // NOTE: fan width print "<td class=\"descriptionbox\">"; print_help_link("fan_width_help", "qm"); print $pgv_lang["fan_width"] . "</td>"; print "<td class=\"optionbox\">"; print "<input type=\"text\" size=\"3\" name=\"fan_width\" value=\"{$fan_width}\" /> <b>%</b> "; print "</td>"; print "</tr></table>"; print "</form><br />"; } else { print "<script language='JavaScript' type='text/javascript'>"; print "if (IE) document.write('<span class=\"warning\">" . str_replace("'", "\\'", $pgv_lang["fanchart_IE"]) . "</span>');"; print "</script>"; } print "</td></tr></table>"; $treeid = ancestry_array($rootid); print_fan_chart($treeid, 640 * $fan_width / 100, $fan_style * 90); print_footer();
} } } } } break; case 2: // Individual list $treeid = ancestry_array($controller->rootid, $PEDIGREE_GENERATIONS); echo '<div class="center">'; print_indi_table($treeid, $pgv_lang["ancestry_chart"] . ' : ' . PrintReady($controller->name), 'sosa'); echo '</div>'; break; case 3: // Family list $treeid = ancestry_array($controller->rootid, $PEDIGREE_GENERATIONS - 1); $famlist = array(); foreach ($treeid as $pid) { $person = Person::getInstance($pid); if (is_null($person)) { continue; } foreach ($person->getChildFamilies() as $famc) { $famlist[$famc->getXref()] = $famc; } } echo '<div class="center">'; print_fam_table($famlist, $pgv_lang["ancestry_chart"] . ' : ' . PrintReady($controller->name)); echo '</div>'; break; }
/** * Initialization function */ function init() { global $PEDIGREE_FULL_DETAILS, $PEDIGREE_LAYOUT, $MAX_PEDIGREE_GENERATIONS; global $DEFAULT_PEDIGREE_GENERATIONS, $SHOW_EMPTY_BOXES; global $bwidth, $bheight, $baseyoffset, $basexoffset, $byspacing, $bxspacing; global $TEXT_DIRECTION, $BROWSER_TYPE, $show_full, $talloffset; $this->log2 = log(2); if ($this->isPrintPreview()) { $this->show_famlink = false; } $this->rootid = safe_GET_xref('rootid'); $this->show_full = safe_GET('show_full', array('0', '1'), $PEDIGREE_FULL_DETAILS); $this->talloffset = safe_GET('talloffset', array('0', '1', '2', '3'), $PEDIGREE_LAYOUT); $this->PEDIGREE_GENERATIONS = safe_GET_integer('PEDIGREE_GENERATIONS', 2, $MAX_PEDIGREE_GENERATIONS, $DEFAULT_PEDIGREE_GENERATIONS); if ($this->talloffset == 1) { $this->talloffset = 1; } // Make SURE this is an integer if ($this->talloffset > 1 && $this->PEDIGREE_GENERATIONS > 8) { $this->PEDIGREE_GENERATIONS = 8; } // TODO: some library functions expect this as a global. // Passing a function parameter would be much better. global $PEDIGREE_GENERATIONS; $PEDIGREE_GENERATIONS = $this->PEDIGREE_GENERATIONS; // This is passed as a global. A parameter would be better... $this->show_full = $this->show_full ? 1 : 0; // Make SURE this is an integer if ($this->talloffset > 3) { $this->talloffset = 3; } else { if ($this->talloffset < 0) { $this->talloffset = 0; } } $show_full = $this->show_full; $talloffset = $this->talloffset; // Validate parameters $this->rootid = check_rootid($this->rootid); $this->rootPerson = Person::getInstance($this->rootid); if (is_null($this->rootPerson)) { $this->rootPerson = new Person(''); } $this->name = $this->rootPerson->getFullName(); $this->addname = $this->rootPerson->getAddName(); //-- adjustments for hide details if ($this->show_full == false) { $bheight = 30; if ($this->talloffset < 2) { $bwidth -= 30; } else { $bwidth -= 50; } } //-- adjustments for portrait mode if ($this->talloffset == 0) { $bxspacing += 12; $bwidth += 20; $baseyoffset -= 20 * ($this->PEDIGREE_GENERATIONS - 1); } $this->pbwidth = $bwidth + 6; $this->pbheight = $bheight + 5; $this->treeid = ancestry_array($this->rootid); $this->treesize = pow(2, (int) $this->PEDIGREE_GENERATIONS) - 1; //-- ancestry_array puts everyone at $i+1 for ($i = 0; $i < $this->treesize; $i++) { $this->treeid[$i] = $this->treeid[$i + 1]; } if (!$this->show_full) { if ($this->talloffset == 0) { $baseyoffset = 160 + $bheight * 2; } else { if ($this->talloffset == 1) { $baseyoffset = 180 + $bheight * 2; } else { if ($this->talloffset > 1) { if ($this->PEDIGREE_GENERATIONS == 3) { $baseyoffset = 30; } else { $baseyoffset = -85; } } } } } else { if ($this->talloffset == 0) { $baseyoffset = 100 + $bheight / 2; } else { if ($this->talloffset == 1) { $baseyoffset = 160 + $bheight / 2; } else { if ($this->talloffset > 1) { if ($this->PEDIGREE_GENERATIONS == 3) { $baseyoffset = 30; } else { $baseyoffset = -85; } } } } } //-- adjustments for preview if ($this->isPrintPreview() && $this->talloffset < 2) { $baseyoffset -= 230; } // -- this next section will create and position the DIV layers for the pedigree tree $this->curgen = 1; // -- variable to track which generation the algorithm is currently working on $this->yoffset = 0; // -- used to offset the position of each box as it is generated $this->xoffset = 0; $this->prevyoffset = 0; // -- used to track the y position of the previous box $this->offsetarray = array(); $this->minyoffset = 0; if ($this->treesize < 3) { $this->treesize = 3; } // -- loop through all of id's in the array starting at the last and working to the first //-- calculation the box positions for ($i = $this->treesize - 1; $i >= 0; $i--) { // -- check to see if we have moved to the next generation if ($i < floor($this->treesize / pow(2, $this->curgen))) { $this->curgen++; } //-- box position in current generation $boxpos = $i - pow(2, $this->PEDIGREE_GENERATIONS - $this->curgen); //-- offset multiple for current generation if ($this->talloffset < 2) { $genoffset = pow(2, $this->curgen - $this->talloffset); $boxspacing = $this->pbheight + $byspacing; } else { $genoffset = pow(2, $this->curgen - 1); $boxspacing = $this->pbwidth + $byspacing; } // -- calculate the yoffset Position in the generation Spacing between boxes put child between parents $this->yoffset = $baseyoffset + $boxpos * ($boxspacing * $genoffset) + $boxspacing / 2 * $genoffset + $boxspacing * $genoffset; // -- calculate the xoffset if ($this->talloffset == 0) { if ($this->PEDIGREE_GENERATIONS < 6) { $addxoffset = $basexoffset + (10 + 60 * (5 - $this->PEDIGREE_GENERATIONS)); $this->xoffset = ($this->PEDIGREE_GENERATIONS - $this->curgen) * (($this->pbwidth + $bxspacing) / 2) + $addxoffset; } else { $addxoffset = $basexoffset + 10; $this->xoffset = ($this->PEDIGREE_GENERATIONS - $this->curgen) * (($this->pbwidth + $bxspacing) / 2) + $addxoffset; } //-- compact the tree if ($this->curgen < $this->PEDIGREE_GENERATIONS) { $parent = floor(($i - 1) / 2); if ($i % 2 == 0) { $this->yoffset = $this->yoffset - $boxspacing / 2 * ($this->curgen - 1); } else { $this->yoffset = $this->yoffset + $boxspacing / 2 * ($this->curgen - 1); } $pgen = $this->curgen; while ($parent > 0) { if ($parent % 2 == 0) { $this->yoffset = $this->yoffset - $boxspacing / 2 * $pgen; } else { $this->yoffset = $this->yoffset + $boxspacing / 2 * $pgen; } $pgen++; if ($pgen > 3) { $temp = 0; for ($j = 1; $j < $pgen - 2; $j++) { $temp += pow(2, $j) - 1; } if ($parent % 2 == 0) { $this->yoffset = $this->yoffset - $boxspacing / 2 * $temp; } else { $this->yoffset = $this->yoffset + $boxspacing / 2 * $temp; } } $parent = floor(($parent - 1) / 2); } if ($this->curgen > 3) { $temp = 0; for ($j = 1; $j < $this->curgen - 2; $j++) { $temp += pow(2, $j) - 1; } if ($i % 2 == 0) { $this->yoffset = $this->yoffset - $boxspacing / 2 * $temp; } else { $this->yoffset = $this->yoffset + $boxspacing / 2 * $temp; } } } $this->yoffset -= $boxspacing / 2 * pow(2, $this->PEDIGREE_GENERATIONS - 2) - $boxspacing / 2; } else { if ($this->talloffset == 1) { $this->xoffset = 10 + $basexoffset + ($this->PEDIGREE_GENERATIONS - $this->curgen) * ($this->pbwidth + $bxspacing); if ($this->curgen == $this->PEDIGREE_GENERATIONS) { $this->xoffset += 10; } if ($this->PEDIGREE_GENERATIONS < 4) { $this->xoffset += 60; } } else { if ($this->talloffset == 2) { if ($this->show_full) { $this->xoffset = $this->curgen * (($this->pbwidth + $bxspacing) / 2) + $this->curgen * 10 + 136.5; } else { $this->xoffset = $this->curgen * (($this->pbwidth + $bxspacing) / 4) + $this->curgen * 10 + 215.75; } if ($this->isPrintPreview()) { $this->xoffset -= 260; } } else { if ($this->show_full) { $this->xoffset = ($this->PEDIGREE_GENERATIONS - $this->curgen) * (($this->pbwidth + $bxspacing) / 2) + 260; } else { $this->xoffset = ($this->PEDIGREE_GENERATIONS - $this->curgen) * (($this->pbwidth + $bxspacing) / 4) + 270; } if ($this->isPrintPreview()) { $this->xoffset -= 260; } } } } if ($this->curgen == 1 && $this->talloffset == 1) { $this->xoffset += 10; } $this->offsetarray[$i]["x"] = $this->xoffset; $this->offsetarray[$i]["y"] = $this->yoffset; } //-- collapse the tree if boxes are missing if (!$SHOW_EMPTY_BOXES) { if ($this->PEDIGREE_GENERATIONS > 1) { $this->collapse_tree(0, 1, 0); } } //-- calculate the smallest yoffset and adjust the tree to that offset $minyoffset = 0; for ($i = 0; $i < count($this->treeid); $i++) { if ($SHOW_EMPTY_BOXES || !empty($treeid[$i])) { if (!empty($offsetarray[$i])) { if ($minyoffset == 0 || $minyoffset > $this->offsetarray[$i]["y"]) { $minyoffset = $this->offsetarray[$i]["y"]; } } } } $ydiff = $baseyoffset + 35 - $minyoffset; $this->adjust_subtree(0, $ydiff); //-- if no father keep the tree off of the pedigree form if ($this->isPrintPreview() && $this->offsetarray[0]["y"] + $baseyoffset < 300) { $this->adjust_subtree(0, 300 - ($this->offsetarray[0]["y"] + $baseyoffset)); } }
/** * Generate both the HTML and PNG components of the fan chart * * The HTML and PNG components both require the same co-ordinate calculations, * so we generate them using the same code, but we send them in separate * HTTP requests. * * @param string $what "png" or "html" * @param string[] $fanChart Presentation parameters, provided by the theme. * * @return string */ public function generate_fan_chart($what, $fanChart) { $treeid = ancestry_array($this->root->getXref(), $this->generations); $fanw = 640 * $this->fan_width / 100; $fandeg = 90 * $this->fan_style; $html = ''; $treesize = count($treeid); // generations count $gen = log($treesize) / log(2) - 1; $sosa = $treesize - 1; // fan size if ($fandeg == 0) { $fandeg = 360; } $fandeg = min($fandeg, 360); $fandeg = max($fandeg, 90); $cx = $fanw / 2 - 1; // center x $cy = $cx; // center y $rx = $fanw - 1; $rw = $fanw / ($gen + 1); $fanh = $fanw; // fan height if ($fandeg == 180) { $fanh = round($fanh * ($gen + 1) / ($gen * 2)); } if ($fandeg == 270) { $fanh = round($fanh * 0.86); } $scale = $fanw / 640; // image init $image = ImageCreate($fanw, $fanh); $white = ImageColorAllocate($image, 0xff, 0xff, 0xff); ImageFilledRectangle($image, 0, 0, $fanw, $fanh, $white); ImageColorTransparent($image, $white); $color = ImageColorAllocate($image, hexdec(substr($fanChart['color'], 1, 2)), hexdec(substr($fanChart['color'], 3, 2)), hexdec(substr($fanChart['color'], 5, 2))); $bgcolor = ImageColorAllocate($image, hexdec(substr($fanChart['bgColor'], 1, 2)), hexdec(substr($fanChart['bgColor'], 3, 2)), hexdec(substr($fanChart['bgColor'], 5, 2))); $bgcolorM = ImageColorAllocate($image, hexdec(substr($fanChart['bgMColor'], 1, 2)), hexdec(substr($fanChart['bgMColor'], 3, 2)), hexdec(substr($fanChart['bgMColor'], 5, 2))); $bgcolorF = ImageColorAllocate($image, hexdec(substr($fanChart['bgFColor'], 1, 2)), hexdec(substr($fanChart['bgFColor'], 3, 2)), hexdec(substr($fanChart['bgFColor'], 5, 2))); // imagemap $imagemap = '<map id="fanmap" name="fanmap">'; // loop to create fan cells while ($gen >= 0) { // clean current generation area $deg2 = 360 + ($fandeg - 180) / 2; $deg1 = $deg2 - $fandeg; ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bgcolor, IMG_ARC_PIE); $rx -= 3; // calculate new angle $p2 = pow(2, $gen); $angle = $fandeg / $p2; $deg2 = 360 + ($fandeg - 180) / 2; $deg1 = $deg2 - $angle; // special case for rootid cell if ($gen == 0) { $deg1 = 90; $deg2 = 360 + $deg1; } // draw each cell while ($sosa >= $p2) { $pid = $treeid[$sosa]; $person = WT_Individual::getInstance($pid); if ($person) { $name = $person->getFullName(); $addname = $person->getAddName(); $text = WT_I18N::reverseText($name); if ($addname) { $text .= "\n" . WT_I18N::reverseText($addname); } $text .= "\n" . WT_I18N::reverseText($person->getLifeSpan()); switch ($person->getSex()) { case 'M': $bg = $bgcolorM; break; case 'F': $bg = $bgcolorF; break; case 'U': $bg = $bgcolor; break; } ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bg, IMG_ARC_PIE); // split and center text by lines $wmax = (int) ($angle * 7 / $fanChart['size'] * $scale); $wmax = min($wmax, 35 * $scale); if ($gen == 0) { $wmax = min($wmax, 17 * $scale); } $text = $this->split_align_text($text, $wmax); // text angle $tangle = 270 - ($deg1 + $angle / 2); if ($gen == 0) { $tangle = 0; } // calculate text position $deg = $deg1 + 0.44; if ($deg2 - $deg1 > 40) { $deg = $deg1 + ($deg2 - $deg1) / 11; } if ($deg2 - $deg1 > 80) { $deg = $deg1 + ($deg2 - $deg1) / 7; } if ($deg2 - $deg1 > 140) { $deg = $deg1 + ($deg2 - $deg1) / 4; } if ($gen == 0) { $deg = 180; } $rad = deg2rad($deg); $mr = ($rx - $rw / 4) / 2; if ($gen > 0 && $deg2 - $deg1 > 80) { $mr = $rx / 2; } $tx = $cx + $mr * cos($rad); $ty = $cy - $mr * -sin($rad); if ($sosa == 1) { $ty -= $mr / 2; } // print text ImageTtfText($image, (double) $fanChart['size'], $tangle, $tx, $ty, $color, $fanChart['font'], $text); $imagemap .= '<area shape="poly" coords="'; // plot upper points $mr = $rx / 2; $deg = $deg1; while ($deg <= $deg2) { $rad = deg2rad($deg); $tx = round($cx + $mr * cos($rad)); $ty = round($cy - $mr * -sin($rad)); $imagemap .= "{$tx},{$ty},"; $deg += ($deg2 - $deg1) / 6; } // plot lower points $mr = ($rx - $rw) / 2; $deg = $deg2; while ($deg >= $deg1) { $rad = deg2rad($deg); $tx = round($cx + $mr * cos($rad)); $ty = round($cy - $mr * -sin($rad)); $imagemap .= "{$tx},{$ty},"; $deg -= ($deg2 - $deg1) / 6; } // join first point $mr = $rx / 2; $deg = $deg1; $rad = deg2rad($deg); $tx = round($cx + $mr * cos($rad)); $ty = round($cy - $mr * -sin($rad)); $imagemap .= "{$tx},{$ty}"; // add action url $imagemap .= '" href="#' . $pid . '"'; $tempURL = 'fanchart.php?rootid=' . $pid . '&generations=' . $this->generations . '&fan_width=' . $this->fan_width . '&fan_style=' . $this->fan_style . '&ged=' . WT_GEDURL; $html .= '<div id="' . $pid . '" class="fan_chart_menu">'; $html .= '<div class="person_box"><div class="details1">'; $html .= '<a href="' . $person->getHtmlUrl() . '" class="name1">' . $name; if ($addname) { $html .= $addname; } $html .= '</a>'; $html .= '<ul class="charts">'; $html .= "<li><a href=\"pedigree.php?rootid={$pid}&amp;ged=" . WT_GEDURL . "\" >" . WT_I18N::translate('Pedigree') . "</a></li>"; if (array_key_exists('googlemap', WT_Module::getActiveModules())) { $html .= "<li><a href=\"module.php?mod=googlemap&mod_action=pedigree_map&rootid=" . $pid . "&ged=" . WT_GEDURL . "\">" . WT_I18N::translate('Pedigree map') . "</a></li>"; } if (WT_USER_GEDCOM_ID && WT_USER_GEDCOM_ID != $pid) { $html .= "<li><a href=\"relationship.php?pid1=" . WT_USER_GEDCOM_ID . "&pid2={$pid}&ged=" . WT_GEDURL . "\">" . WT_I18N::translate('Relationship to me') . "</a></li>"; } $html .= "<li><a href=\"descendancy.php?rootid={$pid}&ged=" . WT_GEDURL . "\" >" . WT_I18N::translate('Descendants') . "</a></li>"; $html .= "<li><a href=\"ancestry.php?rootid={$pid}&ged=" . WT_GEDURL . "\">" . WT_I18N::translate('Ancestors') . "</a></li>"; $html .= "<li><a href=\"compact.php?rootid={$pid}&ged=" . WT_GEDURL . "\">" . WT_I18N::translate('Compact tree') . "</a></li>"; $html .= "<li><a href=\"" . $tempURL . "\">" . WT_I18N::translate('Fan chart') . "</a></li>"; $html .= "<li><a href=\"hourglass.php?rootid={$pid}&ged=" . WT_GEDURL . "\">" . WT_I18N::translate('Hourglass chart') . "</a></li>"; if (array_key_exists('tree', WT_Module::getActiveModules())) { $html .= '<li><a href="module.php?mod=tree&mod_action=treeview&ged=' . WT_GEDURL . '&rootid=' . $pid . '">' . WT_I18N::translate('Interactive tree') . '</a></li>'; } $html .= '</ul>'; // spouse(s) and children foreach ($person->getSpouseFamilies() as $family) { $spouse = $family->getSpouse($person); if ($spouse) { $html .= '<a href="' . $spouse->getHtmlUrl() . '" class="name1">' . $spouse->getFullName() . '</a>'; $kids = $family->getChildren(); if ($kids) { $html .= '<ul class="children">'; foreach ($kids as $child) { $html .= '<li><a href="' . $child->getHtmlUrl() . '" class="name1">' . $child->getFullName() . '</a></li>'; } $html .= '</ul>'; } } } // siblings foreach ($person->getChildFamilies() as $family) { $children = $family->getChildren(); if ($children) { $html .= '<div class="name1">' . WT_I18N::plural('Sibling', 'Siblings', count($children) - 1) . '</div>'; $html .= '<ul class="siblings">'; foreach ($children as $sibling) { if ($sibling !== $person) { $html .= '<li><a href="' . $sibling->getHtmlUrl() . '" class="name1"> ' . $sibling->getFullName() . '</a></li>'; } } $html .= '</ul>'; } } $html .= '</div></div>'; $html .= '</div>'; $imagemap .= ' alt="' . strip_tags($person->getFullName()) . '" title="' . strip_tags($person->getFullName()) . '">'; } $deg1 -= $angle; $deg2 -= $angle; $sosa--; } $rx -= $rw; $gen--; } $imagemap .= '</map>'; switch ($what) { case 'html': $image_title = WT_I18N::translate('Fan chart of %s', strip_tags($person->getFullName())); return $html . $imagemap . '<div id="fan_chart_img"><img src="' . WT_SCRIPT_NAME . '?rootid=' . $this->rootid . '&fan_style=' . $this->fan_style . '&generations=' . $this->generations . '&fan_width=' . $this->fan_width . '&img=1" width="' . $fanw . '" height="' . $fanh . '" alt="' . $image_title . '" title="' . $image_title . '" usemap="#fanmap"></div>'; case 'png': header('Content-Type: image/png'); ImageStringUp($image, 1, $fanw - 10, $fanh / 3, WT_SERVER_NAME . WT_SCRIPT_PATH, $color); ImagePng($image); ImageDestroy($image); } }
public function __construct() { global $PEDIGREE_FULL_DETAILS, $PEDIGREE_LAYOUT, $MAX_PEDIGREE_GENERATIONS; global $DEFAULT_PEDIGREE_GENERATIONS; global $bwidth, $bheight, $cbwidth, $cbheight, $baseyoffset, $basexoffset, $byspacing, $bxspacing; global $linewidth, $shadowcolor, $shadowblur, $shadowoffsetX, $shadowoffsetY; global $show_full, $talloffset; parent::__construct(); $this->linewidth = $linewidth; $this->shadowcolor = $shadowcolor; $this->shadowblur = $shadowblur; $this->shadowoffsetX = $shadowoffsetX; $this->shadowoffsetY = $shadowoffsetY; $this->show_full = WT_Filter::getInteger('show_full', 0, 1, $PEDIGREE_FULL_DETAILS); $this->talloffset = WT_Filter::getInteger('talloffset', 0, 3, $PEDIGREE_LAYOUT); $this->box_width = WT_Filter::getInteger('box_width', 50, 300, 100); $this->PEDIGREE_GENERATIONS = WT_Filter::getInteger('PEDIGREE_GENERATIONS', 2, $MAX_PEDIGREE_GENERATIONS, $DEFAULT_PEDIGREE_GENERATIONS); if ($this->talloffset == 1) { $this->talloffset = 1; } // Make SURE this is an integer if ($this->talloffset > 1 && $this->PEDIGREE_GENERATIONS > 8) { $this->PEDIGREE_GENERATIONS = 8; } // TODO: some library functions expect this as a global. // Passing a function parameter would be much better. global $PEDIGREE_GENERATIONS; $PEDIGREE_GENERATIONS = $this->PEDIGREE_GENERATIONS; // This is passed as a global. A parameter would be better... $this->show_full = $this->show_full ? 1 : 0; // Make SURE this is an integer if ($this->talloffset > 3) { $this->talloffset = 3; } elseif ($this->talloffset < 0) { $this->talloffset = 0; } $show_full = $this->show_full; $talloffset = $this->talloffset; if ($this->root && $this->root->canShowName()) { $this->setPageTitle(WT_I18N::translate('Pedigree tree of %s', $this->root->getFullName())); } else { $this->setPageTitle(WT_I18N::translate('Pedigree')); } // -- adjust size of the compact box if (!$this->show_full) { $bwidth = $cbwidth; $bheight = $cbheight; } //-- adjustments for portrait mode if ($this->talloffset == 0) { $bxspacing += 12; $baseyoffset -= 20 * ($this->PEDIGREE_GENERATIONS - 1); } $this->pbwidth = $bwidth + 6; $this->pbheight = $bheight + 5; $this->treeid = ancestry_array($this->rootid); $this->treesize = pow(2, (int) $this->PEDIGREE_GENERATIONS) - 1; //-- ancestry_array puts everyone at $i+1 for ($i = 0; $i < $this->treesize; $i++) { $this->treeid[$i] = $this->treeid[$i + 1]; } if (!$this->show_full) { if ($this->talloffset == 0) { $baseyoffset = 160 + $bheight * 2; } elseif ($this->talloffset == 1) { $baseyoffset = 180 + $bheight * 2; } elseif ($this->talloffset > 1) { if ($this->PEDIGREE_GENERATIONS == 3) { $baseyoffset = 30; } else { $baseyoffset = -85; } } } else { if ($this->talloffset == 0) { $baseyoffset = 100 + $bheight / 2; } elseif ($this->talloffset == 1) { $baseyoffset = 160 + $bheight / 2; } elseif ($this->talloffset > 1) { if ($this->PEDIGREE_GENERATIONS == 3) { $baseyoffset = 30; } else { $baseyoffset = -85; } } } // -- this next section will create and position the DIV layers for the pedigree tree $this->curgen = 1; // -- variable to track which generation the algorithm is currently working on $this->yoffset = 0; // -- used to offset the position of each box as it is generated $this->xoffset = 0; $this->prevyoffset = 0; // -- used to track the y position of the previous box $this->offsetarray = array(); $this->minyoffset = 0; if ($this->treesize < 3) { $this->treesize = 3; } // -- loop through all of IDs in the array starting at the last and working to the first //-- calculation the box positions for ($i = $this->treesize - 1; $i >= 0; $i--) { // -- check to see if we have moved to the next generation if ($i < (int) ($this->treesize / pow(2, $this->curgen))) { $this->curgen++; } //-- box position in current generation $boxpos = $i - pow(2, $this->PEDIGREE_GENERATIONS - $this->curgen); //-- offset multiple for current generation if ($this->talloffset < 2) { $genoffset = pow(2, $this->curgen - $this->talloffset); $boxspacing = $this->pbheight + $byspacing; } else { $genoffset = pow(2, $this->curgen - 1); $boxspacing = $this->pbwidth + $byspacing; } // -- calculate the yoffset Position in the generation Spacing between boxes put child between parents $this->yoffset = $baseyoffset + $boxpos * ($boxspacing * $genoffset) + $boxspacing / 2 * $genoffset + $boxspacing * $genoffset; // -- calculate the xoffset if ($this->talloffset == 0) { if ($this->PEDIGREE_GENERATIONS < 6) { $addxoffset = $basexoffset + (10 + 60 * (5 - $this->PEDIGREE_GENERATIONS)); $this->xoffset = ($this->PEDIGREE_GENERATIONS - $this->curgen) * (($this->pbwidth + $bxspacing) / 2) + $addxoffset; } else { $addxoffset = $basexoffset + 10; $this->xoffset = ($this->PEDIGREE_GENERATIONS - $this->curgen) * (($this->pbwidth + $bxspacing) / 2) + $addxoffset; } //-- compact the tree if ($this->curgen < $this->PEDIGREE_GENERATIONS) { $parent = (int) (($i - 1) / 2); if ($i % 2 == 0) { $this->yoffset = $this->yoffset - $boxspacing / 2 * ($this->curgen - 1); } else { $this->yoffset = $this->yoffset + $boxspacing / 2 * ($this->curgen - 1); } $pgen = $this->curgen; while ($parent > 0) { if ($parent % 2 == 0) { $this->yoffset = $this->yoffset - $boxspacing / 2 * $pgen; } else { $this->yoffset = $this->yoffset + $boxspacing / 2 * $pgen; } $pgen++; if ($pgen > 3) { $temp = 0; for ($j = 1; $j < $pgen - 2; $j++) { $temp += pow(2, $j) - 1; } if ($parent % 2 == 0) { $this->yoffset = $this->yoffset - $boxspacing / 2 * $temp; } else { $this->yoffset = $this->yoffset + $boxspacing / 2 * $temp; } } $parent = (int) (($parent - 1) / 2); } if ($this->curgen > 3) { $temp = 0; for ($j = 1; $j < $this->curgen - 2; $j++) { $temp += pow(2, $j) - 1; } if ($i % 2 == 0) { $this->yoffset = $this->yoffset - $boxspacing / 2 * $temp; } else { $this->yoffset = $this->yoffset + $boxspacing / 2 * $temp; } } } $this->yoffset -= $boxspacing / 2 * pow(2, $this->PEDIGREE_GENERATIONS - 2) - $boxspacing / 2; } else { if ($this->talloffset == 1) { $this->xoffset = 22 + $basexoffset + ($this->PEDIGREE_GENERATIONS - $this->curgen) * ($this->pbwidth + $bxspacing); if ($this->curgen == $this->PEDIGREE_GENERATIONS) { $this->xoffset; } if ($this->PEDIGREE_GENERATIONS < 4) { $this->xoffset += 60; } } else { if ($this->talloffset == 2) { if ($this->show_full) { $this->xoffset = $this->curgen * (($this->pbwidth + $bxspacing) / 2) + $this->curgen * 10 + 136.5; } else { $this->xoffset = $this->curgen * (($this->pbwidth + $bxspacing) / 4) + $this->curgen * 10 + 215.75; } } else { if ($this->show_full) { $this->xoffset = ($this->PEDIGREE_GENERATIONS - $this->curgen) * (($this->pbwidth + $bxspacing) / 2) + 260; } else { $this->xoffset = ($this->PEDIGREE_GENERATIONS - $this->curgen) * (($this->pbwidth + $bxspacing) / 4) + 270; } } } } if ($this->curgen == 1 && $this->talloffset == 1) { $this->xoffset += 10; } $this->offsetarray[$i]["x"] = $this->xoffset; $this->offsetarray[$i]["y"] = $this->yoffset; } //-- calculate the smallest yoffset and adjust the tree to that offset $minyoffset = 0; for ($i = 0; $i < count($this->treeid); $i++) { if (!empty($offsetarray[$i])) { if ($minyoffset == 0 || $minyoffset > $this->offsetarray[$i]["y"]) { $minyoffset = $this->offsetarray[$i]["y"]; } } } $ydiff = $baseyoffset + 35 - $minyoffset; $this->adjust_subtree(0, $ydiff); }
foreach ($person->getChildFamilies() as $family) { print_sosa_family($family->getXref(), $pid, $i); } } } } echo '</div>'; break; case 2: // Individual list $treeid = ancestry_array($controller->root->getXref(), $PEDIGREE_GENERATIONS); echo '<div id="ancestry-list">', format_indi_table($treeid, 'sosa'), '</div>'; break; case 3: // Family list $treeid = ancestry_array($controller->root->getXref(), $PEDIGREE_GENERATIONS - 1); $famlist = array(); foreach ($treeid as $pid) { $person = WT_Individual::getInstance($pid); if (!$person) { continue; } foreach ($person->getChildFamilies() as $famc) { $famlist[$famc->getXref()] = $famc; } } echo '<div id="ancestry-list">', format_fam_table($famlist), '</div>'; break; } echo '</div>'; // close #ancestry-page