1) { $text = ""; foreach ($lines as $indexval => $line) $text .= split_align_text($line, $maxlen)."\n"; return $text; } // process current line word by word $split = explode(" ", $data); $text = ""; $line = ""; // do not split hebrew line $found = false; foreach ($RTLOrd as $indexval => $ord) { if (strpos($data, chr($ord)) !== false) $found=true; } if ($found) $line=$data; else foreach ($split as $indexval => $word) { $len = strlen($line); //if (!empty($line) and ord($line{0})==215) $len/=2; // hebrew text $wlen = strlen($word); // line too long ? if (($len+$wlen)<$maxlen) { if (!empty($line)) $line .= " "; $line .= "$word"; } else { $p = max(0,floor(($maxlen-$len)/2)); if (!empty($line)) { $line = str_repeat(" ", $p) . "$line"; // center alignment using spaces $text .= "$line\n"; } $line = $word; } } // last line if (!empty($line)) { $len = strlen($line); if (in_array(ord($line{0}),$RTLOrd)) $len/=2; $p = max(0,floor(($maxlen-$len)/2)); $line = str_repeat(" ", $p) . "$line"; // center alignment using spaces $text .= "$line"; } return $text; } /** * print ancestors on a fan chart * * @param array $treeid ancestry pid * @param int $fanw fan width in px (default=640) * @param int $fandeg fan size in deg (default=270) */ function generate_fan_chart($treeid, $fanw=640, $fandeg=270) { global $PEDIGREE_GENERATIONS, $fan_width, $fan_style, $name, $TEXT_DIRECTION; global $WT_IMAGES, $GEDCOM, $fanChart; $html=''; // check for GD 2.x library if (!defined("IMG_ARC_PIE")) { $html.= "".WT_I18N::translate('PHP server misconfiguration: GD 2.x library required to use image functions.').""; $html.= " \"\"

"; return false; } if (!function_exists("ImageTtfBbox")) { $html.= "".WT_I18N::translate('PHP server misconfiguration: FreeType library required to use TrueType fonts.').""; $html.= " \"\"

"; return false; } // Validate if (!file_exists($fanChart['font'])) { $html.= '

'.WT_I18N::translate('The file ā€œ%sā€ does not exist.', $fanChart['font']).'

'; return false; } $fanChart['size'] = intval($fanChart['size']); if ($fanChart['size']<2) $fanChart['size'] = 7; if (empty($fanChart['color']) || $fanChart['color']{0}!='#') $fanChart['color'] = '#000000'; if (empty($fanChart['bgColor']) || $fanChart['bgColor']{0}!='#') $fanChart['bgColor'] = '#EEEEEE'; if (empty($fanChart['bgMColor']) || $fanChart['bgMColor']{0}!='#') $fanChart['bgMColor'] = '#D0D0AC'; if (empty($fanChart['bgFColor']) || $fanChart['bgFColor']{0}!='#') $fanChart['bgFColor'] = '#D0ACD0'; $treesize=count($treeid); if ($treesize<1) return; // 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*.86); $scale=$fanw/640; // image init $image = ImageCreate($fanw, $fanh); $black = ImageColorAllocate($image, 0, 0, 0); $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=""; // 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]; if ($pid) { $person =WT_Person::getInstance($pid); $name =$person->getFullName(); $addname=$person->getAddName(); 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); //$name = str_replace(array('', ''), '', $name); //$addname = str_replace(array('', ''), '', $addname); //$name = str_replace(array('', ''), array('', ''), $name); //@@ //$addname = str_replace(array('', ''), array('', ''), $addname); //@@ // ToDo - print starred names underlined - 1985154 // Todo - print Arabic letters combined - 1360209 $text = reverseText($name) . "\n"; if (!empty($addname)) $text .= reverseText($addname). "\n"; if ($person->canDisplayDetails()) { $birthrec = get_sub_record(1, "1 BIRT", $person->getGedcomRecord()); $ct = preg_match("/2 DATE.*(\d\d\d\d)/", $birthrec, $match); if ($ct>0) $text.= trim($match[1]); $deathrec = get_sub_record(1, "1 DEAT", $person->getGedcomRecord()); $ct = preg_match("/2 DATE.*(\d\d\d\d)/", $deathrec, $match); if ($ct>0) $text.= "-".trim($match[1]); } $text = unhtmlentities($text); $text = strip_tags($text); //Do we still need? // split and center text by lines $wmax = floor($angle*7/$fanChart['size']*$scale); $wmax = min($wmax, 35*$scale); if ($gen==0) $wmax = min($wmax, 17*$scale); $text = split_align_text($text, $wmax); // text angle $tangle = 270-($deg1+$angle/2); if ($gen==0) $tangle=0; // calculate text position $bbox=ImageTtfBbox((double)$fanChart['size'], 0, $fanChart['font'], $text); $textwidth = $bbox[4]; $deg = $deg1+.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 and $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 .= '=$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="'.$person->getHtmlUrl().'"'; $tempURL = 'fanchart.php?rootid='.$pid.'&PEDIGREE_GENERATIONS='.$PEDIGREE_GENERATIONS.'&fan_width='.$fan_width.'&fan_style='.$fan_style.'&ged='.WT_GEDURL; $count=0; $lbwidth=200; $html.= "
"; $html.= "left:".$tx."px; top:".$ty."px; width: ".($lbwidth)."px; visibility:hidden; z-index:'100';\">"; $html.= "
"; $html.= "getHtmlUrl()."\" class=\"name1\">" . $name; if (!empty($addname)) $html.= "
" . $addname; $html.= "
"; $html.= "
".WT_I18N::translate('Pedigree').""; if (array_key_exists('googlemap', WT_Module::getActiveModules())) { $html.= "
".WT_I18N::translate('Pedigree map').""; } if (WT_USER_GEDCOM_ID && WT_USER_GEDCOM_ID!=$pid) { $html.= "
".WT_I18N::translate('Relationship to me').""; } $html.= "
".WT_I18N::translate('Descendants').""; $html.= "
".WT_I18N::translate('Ancestors').""; $html.= "
".WT_I18N::translate('Compact tree').""; $html.= "
".WT_I18N::translate('Fan chart').""; $html.= "
".WT_I18N::translate('Hourglass chart').""; if (array_key_exists('tree', WT_Module::getActiveModules())) { $html.= '
".WT_I18N::translate('Interactive tree').""; } // spouse(s) and children foreach ($person->getSpouseFamilies() as $family) { $spouse=$family->getSpouse($person); if ($spouse) { $html.= '
'.$spouse->getFullName().''; } foreach ($family->getChildren() as $child) { $html.= '
  < '.$child->getFullName().''; } } // siblings foreach ($person->getChildFamilies() as $family) { $children=$family->getChildren(); if (count($children)>2) { $html.= '
'.WT_I18N::translate('Siblings').''; } elseif (count($children)==2) { $html.= '
'.WT_I18N::translate('Sibling').''; } foreach ($children as $sibling) { if (!$sibling->equals($person)) { $html.= '
   '.$sibling->getFullName().''; } } } $html.= '
'; $html.= '
'; $imagemap .= " onclick=\"show_family_box('".$pid.".".$count."', 'relatives'); return false;\""; $imagemap .= " onmouseout=\"family_box_timeout('".$pid.".".$count."'); return false;\""; $imagemap .= " alt=\"".htmlspecialchars(strip_tags($name))."\" title=\"".htmlspecialchars(strip_tags($name))."\" />"; } $deg1-=$angle; $deg2-=$angle; $sosa--; } $rx-=$rw; $gen--; } $imagemap .= '
'; $html.= $imagemap; ImageStringUp($image, 1, $fanw-10, $fanh/3, WT_SERVER_NAME.WT_SCRIPT_PATH, $color); // here we cannot send image to browser ('header already sent') // and we dont want to use a tmp file // step 1. save image data in a session variable ob_start(); ImagePng($image); $image_data = ob_get_contents(); ob_end_clean(); $image_data = serialize($image_data); unset ($_SESSION['image_data']); $_SESSION['image_data']=$image_data; // step 2. call imageflush.php to read this session variable and display image // note: arg "image_name=" is to avoid image miscaching $image_name= "V".time(); unset($_SESSION[$image_name]); // statisticsplot.php uses this to hold a filename to send to browser $image_title=preg_replace("~<.*>~", "", $name) . " " . WT_I18N::translate('Fan chart'); $html.= "

"; $html.= "\"$image_title\""; $html.= "

"; ImageDestroy($image); return $html; } // Extract form parameters $rootid =safe_GET_xref('rootid'); $fan_style=safe_GET_integer('fan_style', 2, 4, 3); $fan_width=safe_GET_integer('fan_width', 50, 300, 100); $PEDIGREE_GENERATIONS=safe_GET_integer('PEDIGREE_GENERATIONS', 2, $MAX_PEDIGREE_GENERATIONS, $DEFAULT_PEDIGREE_GENERATIONS); // Validate form parameters $rootid = check_rootid($rootid); $person =WT_Person::getInstance($rootid); $name =$person->getFullName(); $addname=$person->getAddName(); $title = /* I18N: http://en.wikipedia.org/wiki/Family_tree#Fan_chart - %s is a person's name */ WT_I18N::translate('Fan chart of %s', $person->getFullName()); $treeid = ancestry_array($rootid); $html=generate_fan_chart($treeid, 640*$fan_width/100, $fan_style*90); $controller->setPageTitle($title); $controller->pageHeader(); if ($ENABLE_AUTOCOMPLETE) require WT_ROOT.'js/autocomplete.js.htm'; /*if (strlen($title)<30) $cellwidth="420"; else $cellwidth=(strlen($title)*7);*/ $cellwidth = max(strlen($title)*4, "420"); echo "
"; echo '

', $controller->getPageTitle(), '

'; // -- print the form to change the number of displayed generations echo WT_JS_START; echo "var pastefield; function paste_id(value) { pastefield.value=value; }"; echo WT_JS_END; echo "
"; echo ""; // NOTE: rootid echo ""; // NOTE: fan style echo ""; // NOTE: generations echo "'; echo ''; // NOTE: fan width echo ""; echo "
"; echo WT_I18N::translate('Root Person ID'), help_link('rootid'); echo ""; echo ""; print_findindi_link("rootid",""); echo ""; echo WT_I18N::translate('Circle diagram'), help_link('fan_style'); echo ""; echo " 1/2"; echo "
3/4"; echo "
4/4"; // NOTE: submit echo "
"; echo ""; echo "
"; echo WT_I18N::translate('Generations'), help_link('PEDIGREE_GENERATIONS'); echo ""; echo "'; echo '
"; echo WT_I18N::translate('Width'), help_link('fan_width'); echo ""; echo " % "; echo "
"; echo "

"; echo "
"; echo $html;