function FilledArc(&$im, $CenterX, $CenterY, $DiameterX, $DiameterY, $Start, $End, $line_color, $fill_color = 'none') { if (gd_version() >= 2.0) { if ($fill_color != 'none') { // fill ImageFilledArc($im, $CenterX, $CenterY, $DiameterX, $DiameterY, $Start, $End, $fill_color, IMG_ARC_PIE); } // outline ImageFilledArc($im, $CenterX, $CenterY, $DiameterX, $DiameterY, $Start, $End, $line_color, IMG_ARC_EDGED | IMG_ARC_NOFILL | IMG_ARC_PIE); } else { // cbriou@orange-art.fr // To draw the arc ImageArc($im, $CenterX, $CenterY, $DiameterX, $DiameterY, $Start, $End, $line_color); // To close the arc with 2 lines between the center and the 2 limits of the arc $x = $CenterX + cos(deg2rad($Start)) * ($DiameterX / 2); $y = $CenterY + sin(deg2rad($Start)) * ($DiameterY / 2); ImageLine($im, $x, $y, $CenterX, $CenterY, $line_color); $x = $CenterX + cos(deg2rad($End)) * ($DiameterX / 2); $y = $CenterY + sin(deg2rad($End)) * ($DiameterY / 2); ImageLine($im, $x, $y, $CenterX, $CenterY, $line_color); if ($fill_color != 'none') { if ($End - $Start > 0.5) { // ImageFillToBorder() will flood the wrong parts of the image if the slice is too small // thanks Jami Lowery <*****@*****.**> for pointing out the problem // To fill the arc, the starting point is a point in the middle of the closed space $x = $CenterX + cos(deg2rad(($Start + $End) / 2)) * ($DiameterX / 4); $y = $CenterY + sin(deg2rad(($Start + $End) / 2)) * ($DiameterY / 4); ImageFillToBorder($im, $x, $y, $line_color, $fill_color); } } } }
public function generate($f_image, $n_image) { ImageFilledArc($f_image, $this->_width, $this->_height, $this->_width * 2, $this->_height * 2, 0, 300, $this->_completeColorAllocate, IMG_ARC_PIE); ImageFilledArc($f_image, $this->_width, $this->_height, $this->_width * 2, $this->_height * 2, 300, 360, $this->_incompleteColorAllocate, IMG_ARC_PIE); imageantialias($n_image, true); imagecopyresampled($n_image, $f_image, 0, 0, 0, 0, $this->_width, $this->_height, $this->_width * 2, $this->_height * 2); return $this; }
function GetSignatureImage($signData) { $base64DecData = base64_decode($signData); if (1 == 1) { $exploded_sign = explode(';', $base64DecData); $explode_firstRow = explode(',', $exploded_sign[0]); if (count($explode_firstRow) == 8) { // process ahead if there are enough data in first input $SignBackGround = Html2RGB($explode_firstRow[1]); $SignWidth = $explode_firstRow[3]; $SignHeight = $explode_firstRow[4]; $SignTransparent = strtoupper($explode_firstRow[5]); $SignPoints = (int) $explode_firstRow[6]; $SignControl = $explode_firstRow[7]; $im = imagecreatetruecolor($SignWidth, $SignHeight); $colBack = imagecolorallocate($im, $SignBackGround[0], $SignBackGround[1], $SignBackGround[2]); imagefill($im, 0, 0, $colBack); if ($SignTransparent == "TRUE") { imagecolortransparent($im, $colBack); } // Now get rest of points for ($counter = 1; $counter < count($exploded_sign); $counter++) { if (strlen($exploded_sign[$counter]) > 0) { // Keep processing points $exploded_PointData = explode(" ", trim($exploded_sign[$counter])); $exploded_FirstPointData = explode(',', $exploded_PointData[0]); $SignThick = $exploded_FirstPointData[0]; $SignPenColor = Html2RGB($exploded_FirstPointData[1]); $penColor = imagecolorallocate($im, $SignPenColor[0], $SignPenColor[1], $SignPenColor[2]); // Now run loop for rest of the points if (count($exploded_PointData) == 2) { $coXY = explode(',', trim($exploded_PointData[1])); ImageFilledArc($im, $coXY[0], $coXY[1], 2 * $SignThick, 2 * $SignThick, 0, 360, $penColor, IMG_ARC_PIE); } else { for ($Incounter = 1; $Incounter < count($exploded_PointData) - 1; $Incounter++) { $coXY = explode(',', trim($exploded_PointData[$Incounter])); $coXY2 = explode(',', trim($exploded_PointData[$Incounter + 1])); imgdrawLine($im, $coXY[0], $coXY[1], $coXY2[0], $coXY2[1], $penColor, $SignThick); imgdrawLine($im, $coXY[0], $coXY[1], $coXY2[0], $coXY2[1], $penColor, $SignThick + 1); } } } } return $im; } } return null; }
function GetSignatureImage($spqwzr_11) { $enaysr_12 = base64_decode($spqwzr_11); if (1 == 1) { $jibrxv_13 = explode(base64_decode('Ow=='), $enaysr_12); $ahpyui_14 = explode(base64_decode('LA=='), $jibrxv_13[0]); if (count($ahpyui_14) == 8) { $qdfrcu_3 = Html2RGB($ahpyui_14[1]); $igkrwu_0 = $ahpyui_14[3]; $rhncls_1 = $ahpyui_14[4]; $qpgifq_5 = strtoupper($ahpyui_14[5]); $ijcski_6 = (int) $ahpyui_14[6]; $uyagdp_7 = $ahpyui_14[7]; $yjyqwd_10 = imagecreatetruecolor($igkrwu_0, $rhncls_1); $pshzfj_15 = imagecolorallocate($yjyqwd_10, $qdfrcu_3[0], $qdfrcu_3[1], $qdfrcu_3[2]); imagefill($yjyqwd_10, 0, 0, $pshzfj_15); if ($qpgifq_5 == base64_decode('VFJVRQ==')) { imagecolortransparent($yjyqwd_10, $pshzfj_15); } for ($zumudw_16 = 1; $zumudw_16 < count($jibrxv_13); $zumudw_16++) { if (strlen($jibrxv_13[$zumudw_16]) > 0) { $dmqeif_17 = explode(base64_decode('IA=='), trim($jibrxv_13[$zumudw_16])); $bkgzoa_18 = explode(base64_decode('LA=='), $dmqeif_17[0]); $hzwrws_2 = $bkgzoa_18[0]; $uooxsm_4 = Html2RGB($bkgzoa_18[1]); $vuinxy_19 = imagecolorallocate($yjyqwd_10, $uooxsm_4[0], $uooxsm_4[1], $uooxsm_4[2]); if (count($dmqeif_17) == 2) { $umkucn_20 = explode(base64_decode('LA=='), trim($dmqeif_17[1])); ImageFilledArc($yjyqwd_10, $umkucn_20[0], $umkucn_20[1], 2 * $hzwrws_2, 2 * $hzwrws_2, 0, 360, $vuinxy_19, IMG_ARC_PIE); } else { for ($puihwm_21 = 1; $puihwm_21 < count($dmqeif_17) - 1; $puihwm_21++) { $umkucn_20 = explode(base64_decode('LA=='), trim($dmqeif_17[$puihwm_21])); $kkgkso_22 = explode(base64_decode('LA=='), trim($dmqeif_17[$puihwm_21 + 1])); imgdrawLine($yjyqwd_10, $umkucn_20[0], $umkucn_20[1], $kkgkso_22[0], $kkgkso_22[1], $vuinxy_19, $hzwrws_2); imgdrawLine($yjyqwd_10, $umkucn_20[0], $umkucn_20[1], $kkgkso_22[0], $kkgkso_22[1], $vuinxy_19, $hzwrws_2 + 1); } } } } return $yjyqwd_10; } } return null; }
public function showPieGraph() { $myImage = ImageCreate(300, 300); $white = ImageColorAllocate($myImage, 255, 255, 255); $red = ImageColorAllocate($myImage, 255, 0, 0); $green = ImageColorAllocate($myImage, 0, 255, 0); $blue = ImageColorAllocate($myImage, 0, 0, 255); $lt_red = ImageColorAllocate($myImage, 255, 150, 150); $lt_green = ImageColorAllocate($myImage, 150, 255, 150); $lt_blue = ImageColorAllocate($myImage, 150, 150, 255); for ($i = 120; $i > 100; $i--) { ImageFilledArc($myImage, 100, $i, 200, 150, 0, 90, $lt_red, IMG_ARC_PIE); ImageFilledArc($myImage, 100, $i, 200, 150, 90, 360, $lt_blue, IMG_ARC_PIE); // ImageFilledArc ($myImage, 100, $i, 200, 150, 180, 360, $lt_blue, IMG_ARC_PIE); } ImageFilledArc($myImage, 100, 100, 200, 150, 0, 90, $red, IMG_ARC_PIE); ImageFilledArc($myImage, 100, 100, 200, 150, 90, 360, $blue, IMG_ARC_PIE); //ImageFilledArc($myImage, 100, 100, 200, 150, 180, 360 , $blue, IMG_ARC_PIE); header("Content-type: image/png"); ImagePNG($myImage); ImageDestroy($myImage); }
function draw() { $black = ImageColorAllocate($this->draw->res, 0, 0, 0); // Получим размеры изображения $W = $this->draw->sX(); $H = $this->draw->sY(); $this->draw->antialias(TRUE); // Вывод легенды ##################################### // Посчитаем количество пунктов,от этого зависит высота легенды $this->legend_count = sizeof($this->legend); // Посчитаем максимальную длину пункта,от этого зависит ширина легенды $max_length = 0; foreach ($this->legend as $v) { if ($max_length < strlen($v)) { $max_length = strlen($v); } } // Номер шрифта,котором мы будем выводить легенду $FONT = 2; $font_w = ImageFontWidth($FONT); $font_h = ImageFontHeight($FONT); // Вывод прямоугольника - границы легенды ---------------------------- $l_width = $font_w * $max_length + $font_h + 10 + 5 + 10; $l_height = $font_h * $this->legend_count + 10 + 10; // Получим координаты верхнего левого угла прямоугольника - границы легенды $l_x1 = $W - 100 - $l_width; $l_y1 = ($H - $l_height) / 2; // Выводя прямоугольника - границы легенды ImageRectangle($this->draw->res, $l_x1, $l_y1, $l_x1 + $l_width, $l_y1 + $l_height, $black); // Вывод текст легенды и цветных квадратиков $text_x = $l_x1 + 10 + 5 + $font_h; $square_x = $l_x1 + 10; $y = $l_y1 + 10; $i = 0; foreach ($this->legend as $v) { $dy = $y + $i * $font_h; $this->draw->ttftext($v, $black, CORE_PATH . 'fonts/TAHOMA.TTF', 8, $text_x, $dy + 11); ImageFilledRectangle($this->draw->res, $square_x + 1, $dy + 1, $square_x + $font_h - 1, $dy + $font_h - 1, $this->draw->hex2color($this->colors[$i])); ImageRectangle($this->draw->res, $square_x + 1, $dy + 1, $square_x + $font_h - 1, $dy + $font_h - 1, $black); $i++; } // Вывод круговой диаграммы ---------------------------------------- $sv = sizeof($this->values); if (sizeof($this->values) == 1) { $this->values[] = 9.999999999999999E-12; ++$sv; } $total = array_sum($this->values); $anglesum = $angle = array(0); $i = 1; // Расчет углов while ($i < $sv) { $part = $this->values[$i - 1] / $total; $angle[$i] = floor($part * 360); $anglesum[$i] = array_sum($angle); $i++; } $anglesum[] = $anglesum[0]; // Расчет диаметра $diametr = $l_x1 - 10 - 10; // Расчет координат центра эллипса $circle_x = $diametr / 2 + 10; $circle_y = $H / 2 - 10; // Поправка диаметра,если эллипс не помещается по высоте if ($diametr > $H * 2 - 10 - 10) { $diametr = $H * 2 - 20 - 20 - 40; } // Вывод тени for ($j = 20; $j > 0; $j--) { for ($i = 0; $i < sizeof($anglesum) - 1; $i++) { ImageFilledArc($this->draw->res, $circle_x, $circle_y + $j, $diametr, $diametr / 2, $anglesum[$i], $anglesum[$i + 1], $this->draw->hex2color($this->shadows[$i]), IMG_ARC_PIE); } } // Вывод круговой диаграммы for ($i = 0; $i < sizeof($anglesum) - 1; $i++) { ImageFilledArc($this->draw->res, $circle_x, $circle_y, $diametr, $diametr / 2, $anglesum[$i], $anglesum[$i + 1], $this->draw->hex2color($this->colors[$i]), IMG_ARC_PIE); } }
/** *Display the graph *this is the final function to be called to display the graph. */ function display() { $this->init(); $this->pie = @ImageCreateTrueColor($this->init_img_width, $this->init_img_height); $colBG = ImageColorAllocate($this->pie, $this->pie_color_bg[0], $this->pie_color_bg[1], $this->pie_color_bg[2]); ImageFill($this->pie, 0, 0, $colBG); // Do the 3d effect $this->start_3d = $this->cy + $this->init_3d_height; for($i=$this->start_3d;$i > $this->cy; $i--) { reset($this->pie_data); $c=0; foreach($this->pie_data as $k => $data) { $col = $this->get_color($k, "3d"); ImageFilledArc($this->pie, $this->cx, $i, $this->init_width, $this->init_height, $data[0], $data[1], $col, IMG_ARC_NOFILL); $c++; } } // Now do the graph reset($this->pie_data); $c=0; foreach($this->pie_data as $k => $data) { $col = $this->get_color($k, "normal"); ImageFilledArc($this->pie, $this->cx, $this->cy, $this->init_width, $this->init_height, $data[0], $data[1], $col, IMG_ARC_PIE); $c++; } // The Legends $cellpadding=5; $max_str=0; $items=0; foreach($this->legends as $k => $legend) { if(strlen($legend) > $max_str) { $max_str = strlen($legend); } $items++; } $box_with = ImageFontHeight(2)-5; $box_height = ImageFontHeight(2)-5; $leg_height = ((ImageFontHeight(2)+2) * $items) + ($cellpadding * 2); $leg_width = (ImageFontWidth(2) * ($max_str+7)) + ($cellpadding * 2) +($box_with * 2); $leg_img = ImageCreateTrueColor($leg_width, $leg_height); ImageFill($leg_img, 0, 0, $colBG); // text color $colTEXT = ImageColorAllocate($leg_img, $this->pie_color_text[0], $this->pie_color_text[1], $this->pie_color_text[2]); // text / legends backgroundcolor $colTEXTBG = ImageColorAllocate($leg_img, $this->pie_color_text_bg[0], $this->pie_color_text_bg[1], $this->pie_color_text_bg[2]); // border color for the legends $colTEXTBO = ImageColorAllocate($leg_img, $this->pie_color_border[0], $this->pie_color_border[1], $this->pie_color_border[2]); // the table + border for the legend ImageFilledRectangle($leg_img, 0, 0, $leg_width, $leg_height, $colTEXTBG); ImageRectangle($leg_img, 0, 0, $leg_width-1, $leg_height-1, $colTEXTBO); reset($this->data); $c=0; $lx = $box_with + $cellpadding*2; $ly = $cellpadding; foreach($this->data as $k => $data) { // legend text item $percent = round($data/$this->total*100, 2); $text = $this->legends[$k]." ".$percent."%"; $col = $this->get_color($k, "normal"); ImageFilledRectangle($leg_img, $cellpadding, $ly+2, $cellpadding+$box_with, $ly+$box_height+2, $col); ImageRectangle($leg_img, $cellpadding, $ly+2, $cellpadding+$box_with, $ly+$box_height+2, $colTEXTBO); ImageString($leg_img, 2, $lx, $ly, $text, $colTEXT); $ly += (2 + ImageFontHeight(2)); $c++; } // final setups an image creation $pie_width = ImageSX($this->pie); $pie_height = ImageSY($this->pie); if($this->img_height < $leg_height) { $this->img_height = $leg_height; } $final = ImageCreateTrueColor($this->img_width+$leg_width+$cellpadding, $this->img_height); $ly += (2 + ImageFontHeight(2)); ImageFill($final, 0, 0, $colBG); ImageCopyResampled($final, $this->pie, 0, 0, 0, 0, $this->img_width, $this->img_height, $pie_width, $pie_height); ImageCopyResampled($final, $leg_img, $this->img_width+$cellpadding, 0, 0, 0, $leg_width, $leg_height, $leg_width, $leg_height); // print debugging info, creation time if($this->display_creation_time) { // add creation time if wanted $this->endtime = microtime(); list($susec, $ssec) = explode(" ",$this->starttime); $this->starttime = $susec+$ssec; list($eusec, $esec) = explode(" ",$this->endtime); $this->endtime = $eusec+$esec; $time = round ($this->endtime-$this->starttime, 2); $time_text = "creation time: ".$time." sec"; ImageString($final, 1, ($this->pie_width+$cellpadding), ($this->img_height-ImageFontHeight(1)), $time_text, $colTEXT); } header('Content-type: image/png'); imagepng($final); ImageDestroy($this->pie); ImageDestroy($leg_img); ImageDestroy($final); }
$month = $_GET['month']; $day = $_GET['day']; $year = $_GET['year']; $month1 = $_GET['month1']; $day1 = $_GET['day1']; $year1 = $_GET['year1']; $ro = new database1(); $totalPx = $ro->getTotalPx($month, $day, $year, $month1, $day1, $year1, "OPD") + $ro->getTotalPx($month, $day, $year, $month1, $day1, $year1, "IPD"); $opd1 = $ro->getTotalPx($month, $day, $year, $month1, $day1, $year1, "OPD") / $totalPx; $ipd1 = $ro->getTotalPx($month, $day, $year, $month1, $day1, $year1, "IPD") / $totalPx; $opd2 = $opd1 * 360; $ipd2 = $ipd1 * 360; $myImage = ImageCreate(250, 200); $white = ImageColorAllocate($myImage, 255, 255, 255); $red = ImageColorAllocate($myImage, 255, 0, 0); $green = ImageColorAllocate($myImage, 0, 255, 0); $blue = ImageColorAllocate($myImage, 0, 0, 255); $lt_red = ImageColorAllocate($myImage, 255, 150, 150); $lt_green = ImageColorAllocate($myImage, 150, 255, 150); $lt_blue = ImageColorAllocate($myImage, 150, 150, 255); for ($i = 120; $i > 100; $i--) { ImageFilledArc($myImage, 100, $i, 200, 120, 0, $opd2, $lt_red, IMG_ARC_PIE); ImageFilledArc($myImage, 100, $i, 200, 120, $ipd2, 360, $lt_blue, IMG_ARC_PIE); // ImageFilledArc ($myImage, 100, $i, 200, 150, 180, 360, $lt_blue, IMG_ARC_PIE); } ImageFilledArc($myImage, 100, 100, 200, 120, 0, $opd2, $red, IMG_ARC_PIE); ImageFilledArc($myImage, 100, 100, 200, 120, $ipd2, 360, $blue, IMG_ARC_PIE); //ImageFilledArc($myImage, 100, 100, 200, 150, 180, 360 , $blue, IMG_ARC_PIE); header("Content-type: image/png"); ImagePNG($myImage); ImageDestroy($myImage);
public function generateChart($params) { $this->chartType = isset($params['chartType']) ? (string) $params['chartType'] : $this->chartType; $this->displayTrue = isset($params['displayTrue']) ? (bool) $params['displayTrue'] : $this->displayTrue; $this->values = isset($params['values']) ? $params['values'] : $this->values; $this->groupNames = isset($params['groupNames']) ? $params['groupNames'] : $this->groupNames; $this->groupSize = isset($params['groupSize']) ? (int) $params['groupSize'] : $this->groupSize; $this->barWidth = isset($params['barWidth']) ? (int) $params['barWidth'] : $this->barWidth; $this->marginSize = isset($params['marginSize']) ? (int) $params['marginSize'] : $this->marginSize; $this->yAxisMod = isset($params['yAxisMod']) ? (int) $params['yAxisMod'] : $this->yAxisMod; $this->colors = isset($params['colors']) ? $params['colors'] : $this->colors; $this->showLabel = isset($params['showLabel']) ? (bool) $params['showLabel'] : $this->showLabel; $this->showPercent = isset($params['showPercent']) ? (bool) $params['showPercent'] : $this->showPercent; $this->showText = isset($params['showText']) ? (bool) $params['showText'] : $this->showText; $this->showParts = isset($params['showParts']) ? (bool) $params['showParts'] : $this->showParts; $this->labelsOnPie = isset($params['labelsOnPie']) ? (bool) $params['labelsOnPie'] : $this->labelsOnPie; $this->stripNonLetters = isset($params['stripNonLetters']) ? (bool) $params['stripNonLetters'] : $this->stripNonLetters; $this->bulletForm = isset($params['bulletForm']) ? (string) $params['bulletForm'] : $this->bulletForm; $this->version = isset($params['version']) ? (string) $params['version'] : $this->version; // Get text length details about the label - $data for ($i = 0; $i < count($this->values); $i++) { // Get each value set for the list list($key, $value) = each($this->values); if ($value / array_sum($this->values) < 0.1) { $number[$i] = ' ' . number_format($value / array_sum($this->values) * 100, 1, '.', '.') . '%'; } else { $number[$i] = number_format($value / array_sum($this->values) * 100, 1, '.', '.') . '%'; } if (strlen($value) > $text_length) { $text_length = strlen($key); } } /* // Details of the display for labels $antal_label = count($this->values); $xtra = (5+15*$antal_label)-($height+ceil($shadow_drop)); if ($xtra > 0) $xtra_height = (5+15*$antal_label)-($height+ceil($shadow_drop)); // +ceil($shadow_drop)+$xtra_height */ // Determine the colours that will be used if ($this->colors) { foreach ($this->colors as $colorkode) { $fill_color[] = chartColorHex($this->chartImage->img, $colorkode); $shadow_color[] = chartColorHexshadow($this->chartImage->img, $colorkode, $this->chartImage->shadowDark); } } else { // If no colours were passed, go with the default $fill_color[] = chartColorHex($this->chartImage->img, $this->chartImage->barColor); $shadow_color[] = chartColorHexshadow($this->chartImage->img, $this->chartImage->barColor, $this->chartImage->shadowDark); } // Space for the legend $mSpaceSize = 5; // Loop through, and get size details about the text to be written $max_text_height = 0; // Will be used to describe the box as well $max_label_width = 0; $max_percent_width = 0; if ($this->chartType == 'pie') { //////////////////////// // Pie Chart //////////////////////// reset($this->values); for ($i = 0; $i < count($this->values); $i++) { // Get each value set for the list list($key, $value) = each($this->values); $label_output = ''; if ($this->showText) { $label_output = $label_output . $key . ' '; } if ($this->showParts) { $label_output = $label_output . $value; } // Display off the page somewhere, and then capture $text_details = imagettftext($this->chartImage->img, $this->fontLabel->fontSize, 0, -10000, -10000, chartColorHex($this->chartImage->img, $this->fontLabel->textColor), $this->fontLabel->textFont, $label_output); // Height of Key $mHeight = $text_details[1] - $text_details[7]; if ($mHeight > $max_text_height) { $max_text_height = $mHeight; } // Width of Key $mWidth = $text_details[2] - $text_details[0]; // Right side - left side if ($mWidth > $max_label_width) { $max_label_width = $mWidth; } // Only if we show percent if ($this->showPercent) { // Details about the percentage display $text_details = imagettftext($this->chartImage->img, $this->fontText->fontSize, 0, -10000, -10000, chartColorHex($this->chartImage->img, $this->fontText->textColor), $this->fontText->textFont, $number[$i]); // Width of Key $mWidth = $text_details[2] - $text_details[0]; // Right side - left side if ($mWidth > $max_percent_width) { $max_percent_width = $mWidth; } // Save the width $number_width[$i] = $mWidth; } } // for // Space for the legend $mSpaceSize = 5; // -- How much space is the legend going to take $legend_width = 10 + $max_text_height + $mSpaceSize + $max_percent_width + $mSpaceSize + $max_label_width; // Description // Determine where to start drawing $width = $this->chartImage->imgWidth - $legend_width; // Outline (where the text is) imagefilledrectangle($this->chartImage->img, 1, 1, $this->chartImage->imgWidth - 2, $this->chartImage->imgHeight - 2, chartColorHex($this->chartImage->img, $this->chartImage->outlineColor)); // Background imagefilledrectangle($this->chartImage->img, 1, 1, $width, $this->chartImage->imgHeight - 2, chartColorHex($this->chartImage->img, $this->chartImage->backgroundColor)); // Label and percent text drawing $label_place = 5; // Y reset($this->values); for ($i = 0; $i < count($this->values); $i++) { // Get each value set for the list list($key, $value) = each($this->values); if ($this->bulletForm == 'round' && $this->showLabel && $value > 0) { imagefilledellipse($this->chartImage->img, $width + $max_text_height / 2 + $mSpaceSize / 2, $label_place + $max_text_height / 2, $max_text_height, $max_text_height, chartColorHex($this->chartImage->img, $this->colors[$i % count($this->colors)])); imageellipse($this->chartImage->img, $width + $max_text_height / 2 + $mSpaceSize / 2, $label_place + $max_text_height / 2, $max_text_height, $max_text_height, chartColorHex($this->chartImage->img, $this->fontText->textColor)); } else { if ($this->bulletForm == 'square' && $this->showLabel && $value > 0) { imagefilledrectangle($this->chartImage->img, $width + $mSpaceSize, $label_place, $width + $max_text_height + $mSpaceSize - 2, $label_place + $max_text_height - 2, chartColorHex($this->chartImage->img, $this->colors[$i % count($this->colors)])); imagerectangle($this->chartImage->img, $width + $mSpaceSize, $label_place, $width + $max_text_height + $mSpaceSize - 2, $label_place + $max_text_height - 2, chartColorHex($this->chartImage->img, $this->fontText->textColor)); } } if ($value > 0) { $mPlaceX = $width + $max_text_height + $mSpaceSize + 2; // Bump along with a little space // Put each part down as needed if ($this->showPercent) { $mPlaceX = $mPlaceX + $max_percent_width - $number_width[$i]; imagettftext($this->chartImage->img, $this->fontText->fontSize, 0, $mPlaceX, $label_place + 10, chartColorHex($this->chartImage->img, $this->fontText->textColor), $this->fontText->textFont, $number[$i]); } $label_output = ''; if ($this->showText) { $label_output = $label_output . $key . ' '; } if ($this->showParts) { $label_output = $label_output . $value; } // Draw out the font for the label $mPlaceX = $width + $max_text_height + $mSpaceSize + $max_percent_width + $mSpaceSize; imagettftext($this->chartImage->img, $this->fontLabel->fontSize, 0, $mPlaceX, $label_place + 10, chartColorHex($this->chartImage->img, $this->fontLabel->textColor), $this->fontLabel->textFont, $label_output); // Bump down to the next line based on the font height $label_place = $label_place + $max_text_height + 5; // 15; } } $centerX = round($width / 2); $centerY = round(($this->chartImage->imgHeight - $this->chartImage->shadowDrop) / 2); $diameterX = $width - 4; $diameterY = $this->chartImage->imgHeight - $this->chartImage->shadowDrop - 4; reset($this->values); $data_sum = array_sum($this->values); $start = 270; $counter = 0; $value_counter = 0; // Determine the slices for ($i = 0; $i < count($this->values); $i++) { // Get each value set for the list list($key, $value) = each($this->values); $counter += $value; $end = ceil($counter / $data_sum * 360) + 270; $slice[] = array($start, $end, $shadow_color[$value_counter % count($shadow_color)], $fill_color[$value_counter % count($fill_color)]); $start = $end; $value_counter++; } // Draw the shadow for ($i = $centerY + $this->chartImage->shadowDrop; $i > $centerY; $i--) { // How many pixels deep? for ($j = 0; $j < count($slice); $j++) { if ($slice[$j][0] != $slice[$j][1]) { ImageFilledArc($this->chartImage->img, $centerX, $i, $diameterX, $diameterY, $slice[$j][0], $slice[$j][1], $slice[$j][2], IMG_ARC_PIE); } } } // Draw each slice for ($j = 0; $j < count($slice); $j++) { if ($slice[$j][0] != $slice[$j][1]) { ImageFilledArc($this->chartImage->img, $centerX, $centerY, $diameterX, $diameterY, $slice[$j][0], $slice[$j][1], $slice[$j][3], IMG_ARC_PIE); } } } else { //////////////////////// // Bar Chart //////////////////////// // Max value is required to adjust the scale $max_value = max($this->values); // Find the size of graph by substracting the size of borders $graph_width = $this->chartImage->imgWidth - $this->marginSize * 2; $graph_height = $this->chartImage->imgHeight - $this->marginSize * 2; $total_bars = count($this->values); $gap = ($graph_width - $total_bars * $this->barWidth) / ($total_bars + 1); // Determine the size of the on the X Axis Labels reset($this->values); for ($i = 0; $i < count($this->values); $i++) { // Get each value set for the list list($key, $this->value) = each($this->values); // Display off the page somewhere, and then capture $text_details = imagettftext($this->chartImage->img, $this->fontLabel->fontSize, $this->fontLabel->fontAngle, -10000, -10000, chartColorHex($this->chartImage->img, $this->fontLabel->textColor), $this->fontLabel->textFont, $key); //echo ('<br />'); //print_r($text_details); // Height of Key // -- This is odd, because the location is on the corner points of the text ... NOT the rectangle in which the text prints // -- So, we need to find the worst circumstance $mHeight1 = abs($text_details[1] - $text_details[5]); // bottom left Y - top right Y $mHeight2 = abs($text_details[3] - $text_details[7]); // bottom right Y - top left Y $mHeight = max($mHeight1, $mHeight2); if ($mHeight > $max_text_height) { $max_text_height = $mHeight; } //echo ($max_text_height.'-'.$mHeight1.'-'.$mHeight2.'<br />'); // Width of Key $mWidth = $text_details[2] - $text_details[0]; // Right side - left side if ($mWidth > $max_label_width) { $max_label_width = $mWidth; } } // Get the max value for the Y axis (also used for group height definition) $text_details = imagettftext($this->chartImage->img, $this->fontText->fontSize, 0, -10000, -10000, chartColorHex($this->chartImage->img, $this->fontText->textColor), $this->fontText->textFont, $max_value); $max_value_width = $text_details[2] - $text_details[0]; // Right side - left side // Get the text thickness $text_details = imagettftext($this->chartImage->img, $this->fontText->fontSize, 0, -10000, -10000, chartColorHex($this->chartImage->img, $this->fontText->textColor), $this->fontText->textFont, 'Z'); $text_thickness = abs($text_details[1] - $text_details[7]); // Have GroupName lables been passed in? $group_height = 0; $group_text_thickness = 0; if ($this->groupSize > 0 && $this->groupSize) { // Get the group text thicknesss $text_details = imagettftext($this->chartImage->img, $this->fontGroup->fontSize, 0, -10000, -10000, chartColorHex($this->chartImage->img, $this->fontGroup->textColor), $this->fontGroup->textFont, 'Z'); $group_text_thickness = abs($text_details[1] - $text_details[7]); // The group labels will go just below the bars $group_height = $group_text_thickness; } // === Draw the entire works === // Determine the ratio for the bars (@@@ use / 5 or 10 instead) $ratio = ($graph_height - $max_text_height - $group_height) / $max_value; // Outline (where the text is) imagefilledrectangle($this->chartImage->img, 1, 1, $this->chartImage->imgWidth - 2, $this->chartImage->imgHeight - 2, chartColorHex($this->chartImage->img, $this->chartImage->outlineColor)); // A line for the bottom of the bar graph to give it a base imagefilledrectangle($this->chartImage->img, $max_value_width + $mSpaceSize + $this->marginSize - 1, $this->marginSize, $this->chartImage->imgWidth - 1 - $this->marginSize, $this->chartImage->imgHeight - 0 - $this->marginSize - $max_text_height - $group_height, chartColorHex($this->chartImage->img, $this->chartImage->baselineColor)); // Background imagefilledrectangle($this->chartImage->img, $max_value_width + $mSpaceSize + $this->marginSize, $this->marginSize, $this->chartImage->imgWidth - 1 - $this->marginSize, $this->chartImage->imgHeight - 1 - $this->marginSize - $max_text_height - $group_height, chartColorHex($this->chartImage->img, $this->chartImage->backgroundColor)); // Graph Grid Lines by mod for ($i = 0; $i <= max($this->values); $i++) { $yLine = $this->marginSize - $max_text_height + $graph_height - intval($i * $ratio); // Top of bars if ($i % $this->yAxisMod == 0) { // Make sure we dont take out the bottom line if ($i > 0) { imageline($this->chartImage->img, $this->marginSize + $mSpaceSize + $max_value_width, $yLine - $group_height, $this->chartImage->imgWidth - $this->marginSize, $yLine - $group_height, chartColorHex($this->chartImage->img, $this->chartImage->gridlineColor)); } // Y axis number imagettftext($this->chartImage->img, $this->fontText->fontSize, 0, 5, $yLine - $group_height, chartColorHex($this->chartImage->img, $this->fontText->textColor), $this->fontText->textFont, $i); } } // Draw the bars on the chart // -- include values at top of bar reset($this->values); // Determine the group gap amount to add and subtract ( if groups ) $mGroupGap = 0; if ($this->groupSize > 0 && $this->groupNames) { $mGroupGap = round($gap / $this->groupSize); // Get the keys as well $mGroupKeys = array_keys($this->groupNames); } // Group counter for lables $mGroupCount = 0; for ($i = 0; $i < $total_bars; $i++) { // Extract key and value pair from the current pointer position list($key, $value) = each($this->values); // Bunch the bars up together for groups if ($mGroupGap > 0) { $mGroupAdjust = $mGroupAdjust - $mGroupGap; if ($i % $this->groupSize == 0) { $mGroupAdjust = 0; // Issolate the keys from the array $mGroupName = $mGroupKeys[$mGroupCount]; // Display the group label here $mGroupX = $this->marginSize + $max_value_width + $gap / 2 + $i * ($gap + $this->barWidth); // Print group label imagettftext($this->chartImage->img, $this->fontGroup->fontSize, 0, $mGroupX, $this->chartImage->imgHeight - $max_text_height - $mSpaceSize, chartColorHex($this->chartImage->img, $this->fontGroup->textColor), $this->fontGroup->textFont, $mGroupName); // Next group $mGroupCount++; } } // Determine the position of the bar $x1 = $this->marginSize + $max_value_width + $gap / 2 + $i * ($gap + $this->barWidth) + $mGroupAdjust; $x2 = $x1 + $this->barWidth; // Verticals $y1 = $this->marginSize + $graph_height - intval($value * $ratio); // Top of bars $y2 = $this->chartImage->imgHeight - $this->marginSize; // Bottom // X axis Bar labels (( Can include angles )) // -- Adjust position of of text depending on the angle // -- @@@ Need to use sin / cos for clean results (( but even then, its hard to visualize whats going on with the angle part ) $mOffset = $text_thickness - 2; // Note: 0 is flat and pointing right if ($this->fontLabel->fontAngle >= 270) { // Angled down, start at top $mOffset = $max_text_height - $mSpaceSize; } else { if ($this->fontLabel->fontAngle >= 180) { // Angled up, start at bottom $mOffset = $max_text_height; } else { if ($this->fontLabel->fontAngle >= 25) { // Angled up, start at bottom $mOffset = $text_thickness; } } } // Remove non-letters from the key // -- Note: This is used in order to force array keys by using numbers $mKeyLabel = $key; if ($this->stripNonLetters) { $allowed = "/[^a-z\\040\\.\\-]/i"; $mKeyLabel = preg_replace($allowed, "", $mKeyLabel); } // X Axis Labels imagettftext($this->chartImage->img, $this->fontLabel->fontSize, $this->fontLabel->fontAngle, $x1 + 3, $this->chartImage->imgHeight - $mOffset + $group_height - 3, chartColorHex($this->chartImage->img, $this->fontLabel->textColor), $this->fontLabel->textFont, $mKeyLabel); // Bar shadow for ($mLoop = 0; $mLoop < $this->chartImage->shadowDrop; $mLoop++) { // y2-1 will give room for the base line imagefilledrectangle($this->chartImage->img, $x1, $y1 + $mLoop - $max_text_height - $group_height, $x2 + $mLoop, $y2 - $max_text_height - 1 - $group_height, $shadow_color[$i % count($shadow_color)]); } // Bar imagefilledrectangle($this->chartImage->img, $x1, $y1 - $max_text_height - $group_height, $x2, $y2 - $max_text_height - 1 - $group_height, $fill_color[$i % count($fill_color)]); // Value of bar (printed at top) // -- Print this last over all other graphics $mYPos = $y1 - $max_text_height - 4 - $group_height; if ($mYPos - 1 < $text_thickness) { $mYPos = $text_thickness + 1; } imagettftext($this->chartImage->img, $this->fontText->fontSize, 0, $x1 + 3, $mYPos, chartColorHex($this->chartImage->img, $this->fontText->textColor), $this->fontText->textFont, $value); } } // if [pie or bar] // Generate an image file to display $mTempFile = $this->chartImage->imgFile; if ($mTempFile == '') { $mTempFile = $this->chartType . '_chart_' . uniqid() . '.png'; } imagepng($this->chartImage->img, $mTempFile); // Display it? if ($this->displayTrue) { echo '<img height="' . $this->chartImage->imgHeight . '" width="' . $this->chartImage->imgWidth . '" alt="Dynamically generated image" src="' . $mTempFile . '"> '; } }
protected function DrawPieChart() { // Early checks and initialization: if (!$this->CheckDataType('text-data, text-data-single, data-data')) { return FALSE; } // SetLabelScalePosition(0 or FALSE) means no labels. $do_labels = !empty($this->label_scale_position); if ($do_labels) { // Validate and get default for pie chart label source and format: $pie_label_source = $this->CheckPieLabels(); // Labels outside (vs inside) the pie? If so, pie size will need adjusting. $labels_outside = $this->label_scale_position >= 0.5; // Only defined if ($do_labels) } // Draw segment borders? Default is True for unshaded, False for shaded $do_borders = isset($this->draw_pie_borders) ? $this->draw_pie_borders : $this->shading == 0; $max_data_colors = count($this->ndx_data_colors); // Number of colors available // Check shading. Diameter factor $diam_factor is (height / width) if ($this->shading > 0) { $diam_factor = $this->pie_diam_factor; $this->NeedDataDarkColors(); // Dark colors are needed for shading } else { $diam_factor = 1.0; // Unshaded pies are always round, width == height } // Pie center point is always the center of the plot area, regardless of label sizes. $xpos = $this->plot_area[0] + $this->plot_area_width / 2; $ypos = $this->plot_area[1] + $this->plot_area_height / 2; // Reduce the data array into sumarr[], accounting for the data type: $num_slices = $this->data_columns; // See CheckDataArray which calculates this for us. if ($num_slices < 1) { return TRUE; } // Give up early if there is no data at all. $sumarr = array_fill(0, $num_slices, 0); // Initialize array of per-sector sums. if ($this->datatype_pie_single) { // text-data-single: One data column per row, one pie slice per row. for ($i = 0; $i < $num_slices; $i++) { if (is_numeric($val = $this->data[$i][1])) { $sumarr[$i] = abs($val); } } } else { // text-data: Sum each column (skipping label), one pie slice per column. // data-data: Sum each column (skipping X value and label), one pie slice per column. $skip = $this->datatype_implied ? 1 : 2; // Leading values to skip in each row. for ($i = 0; $i < $this->num_data_rows; $i++) { for ($j = $skip; $j < $this->num_recs[$i]; $j++) { if (is_numeric($val = $this->data[$i][$j])) { $sumarr[$j - $skip] += abs($val); } } } } $total = array_sum($sumarr); if ($total == 0) { // There are either no valid data points, or all are 0. // See top comment about why not to make this an error. return TRUE; } // Pre-calculate the label strings, if labels are on. Also get the maximum height and width // of the labels, to use in sizing the pie chart (if the labels are outside the pie). // This is an overly pessimistic approach - assumes the widest label is at 0 or 180 degrees - but // is much easier than calculating the exact space needed for all labels around the pie. // For more detailed comments on the in-loop calculations, see the second loop below where // the features are actually drawn. // Note this is going around the pie, with angles specified, but we do not yet know the pie size. $label_max_width = 0; // Widest label width, in pixels $label_max_height = 0; // Tallest label height, in pixels if ($do_labels) { $labels = array(); // Array to store the formatted label strings $end_angle = $start_angle = $this->pie_start_angle; for ($j = 0; $j < $num_slices; $j++) { $slice_weight = $sumarr[$j]; $arc_angle = 360 * $slice_weight / $total; if ($this->pie_direction_cw) { $end_angle = $start_angle; $start_angle -= $arc_angle; } else { $start_angle = $end_angle; $end_angle += $arc_angle; } $arc_start_angle = (int) (360 - $start_angle); $arc_end_angle = (int) (360 - $end_angle); if ($arc_start_angle > $arc_end_angle) { // Skip segments with angle < 1 degree $labels[$j] = $this->FormatPieLabel($j, $pie_label_source, $arc_angle, $slice_weight); if ($labels_outside) { // Labels are outside the pie chart list($width, $height) = $this->SizeText('generic', 0, $labels[$j]); if ($width > $label_max_width) { $label_max_width = $width; } if ($height > $label_max_height) { $label_max_height = $height; } } } } } // Calculate the maximum available area for the pie, leaving room for labels (if outside the pie): // This can be overridden by using SetPieAutoSize(FALSE), which sets the flag: pie_full_size=TRUE. if ($do_labels && $labels_outside && !$this->pie_full_size) { // There needs to be safe_margin between the labels and the plot area margins, and at least // safe_margin between the labels and the pie edge (this is LR_marg and TB_marg below). // plot_area_width = avail_width + 2 * (LR_marg + label_width + safe_margin) // Where LR_marg = max(safe_margin, avail_width * label_scale_position - avail_width/2) // plot_area_height = avail_height + 2 * (TB_marg + label_height + safe_margin + shading) // Where TB_marg = max(safe_margin, avail_height * label_scale_position - avail_height/2) // Note shading is on bottom only, but since center is fixed, it is counted on top too. // Note (avail_width * label_scale_position) is the distance from the pie center to the label // text base point. Subtract avail_width/2 to get the inner margin (unless it is too small). // Similar for Y: avail_height * label_scale_position - avail_height/2 is the distance from // the pie center up to the label text base point. // Calculate available space for both values of LR_marg, TB_marg and take the smaller ones. $avail_width = min(($this->plot_area_width / 2 - $label_max_width - $this->safe_margin) / $this->label_scale_position, $this->plot_area_width - 4 * $this->safe_margin - 2 * $label_max_width); $avail_height = min(($this->plot_area_height / 2 - $label_max_height - $this->safe_margin - $this->shading) / $this->label_scale_position, $this->plot_area_height - 4 * $this->safe_margin - 2 * ($label_max_height + $this->shading)); // Sanity check - don't let large labels shrink the pie too much. $avail_width = max($avail_width, $this->pie_min_size_factor * $this->plot_area_width); $avail_height = max($avail_height, $this->pie_min_size_factor * $this->plot_area_height); } else { // No adjustment needed for labels $avail_width = $this->plot_area_width - 2 * $this->safe_margin; // Note shading is only on bottom, but need to subtract 2x because center does not move. $avail_height = $this->plot_area_height - 2 * ($this->safe_margin + $this->shading); } // Calculate the pie width and height for the best fit, given diam_factor and available space: if ($avail_height / $avail_width > $diam_factor) { $pie_width = $avail_width; $pie_height = $pie_width * $diam_factor; } else { $pie_height = $avail_height; $pie_width = $pie_height / $diam_factor; } // Factors used to calculate label positions by DrawPieLabel(). See there for explanation. if ($do_labels) { $r['reverse'] = 0.25 < $this->label_scale_position && $this->label_scale_position < 0.5; $r['x'] = $pie_width * $this->label_scale_position; $r['y'] = $pie_height * $this->label_scale_position; if ($labels_outside) { // Don't let outside labels touch the pie edge - move them out a bit: $r['x'] = max($r['x'], $pie_width / 2 + $this->safe_margin); $r['y'] = max($r['y'], $pie_height / 2 + $this->safe_margin); } else { // Don't let inside labels touch the pie edge - move them in a bit: $r['x'] = min($r['x'], $pie_width / 2 - $this->safe_margin); $r['y'] = min($r['y'], $pie_height / 2 - $this->safe_margin); } } // Draw the pie. For shaded pies, draw one set for each shading level ($h). for ($h = $this->shading; $h >= 0; $h--) { $color_index = 0; // Initialize the start angle (for clockwise) or end angle (for counter-clockwise). // See "Calculate the two angles" below to make sense of this. $end_angle = $start_angle = $this->pie_start_angle; // Loop over all pie segments: for ($j = 0; $j < $num_slices; $j++) { $slice_weight = $sumarr[$j]; $arc_angle = 360 * $slice_weight / $total; // For shaded pies: the last one (at the top of the "stack") has a brighter color: if ($h == 0) { $slicecol = $this->ndx_data_colors[$color_index]; } else { $slicecol = $this->ndx_data_dark_colors[$color_index]; } // Calculate the two angles that define this pie segment. // Note that regardless of the direction (CW or CCW), start_angle < end_angle. if ($this->pie_direction_cw) { $end_angle = $start_angle; $start_angle -= $arc_angle; } else { $start_angle = $end_angle; $end_angle += $arc_angle; } // Calculate the arc angles for ImageFilledArc(), which measures angles in the opposite // direction (counter-clockwise), and only takes integer values. $arc_start_angle = (int) (360 - $start_angle); $arc_end_angle = (int) (360 - $end_angle); // Don't try to draw a 0 degree slice - it would make a full circle. if ($arc_start_angle > $arc_end_angle) { // Draw the slice ImageFilledArc($this->img, $xpos, $ypos + $h, $pie_width, $pie_height, $arc_end_angle, $arc_start_angle, $slicecol, IMG_ARC_PIE); // Processing to do only for the last (if shaded) or only (if unshaded) loop: if ($h == 0) { // Draw the pie segment outline (if enabled): if ($do_borders) { ImageFilledArc($this->img, $xpos, $ypos, $pie_width, $pie_height, $arc_end_angle, $arc_start_angle, $this->ndx_pieborder_color, IMG_ARC_PIE | IMG_ARC_EDGED | IMG_ARC_NOFILL); } // Draw the label: if ($do_labels) { $this->DrawPieLabel($labels[$j], $xpos, $ypos, $start_angle, $arc_angle, $r); } // Trigger a data points callback; note it gets the calculated (reversed) angles: $this->DoCallback('data_points', 'pie', $j, 0, $xpos, $ypos, $pie_width, $pie_height, $arc_start_angle, $arc_end_angle); } } if (++$color_index >= $max_data_colors) { $color_index = 0; } } // end loop for each slice } // end loop for each level of shading return TRUE; }
<?php //create the canvas $myImage = ImageCreate(300, 300); //set up some colors for use on the canvas $white = ImageColorAllocate($myImage, 255, 255, 255); $red = ImageColorAllocate($myImage, 255, 0, 0); $green = ImageColorAllocate($myImage, 0, 255, 0); $blue = ImageColorAllocate($myImage, 0, 0, 255); //draw a pie ImageFilledArc($myImage, 100, 100, 200, 150, 0, 90, $red, IMG_ARC_PIE); ImageFilledArc($myImage, 100, 100, 200, 150, 90, 180, $green, IMG_ARC_PIE); ImageFilledArc($myImage, 100, 100, 200, 150, 180, 360, $blue, IMG_ARC_PIE); //output the image to the browser header("Content-type: image/png"); ImagePNG($myImage); //clean up after yourself ImageDestroy($myImage);
/** * 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 print_fan_chart($treeid, $fanw = 640, $fandeg = 270) { global $PEDIGREE_GENERATIONS, $fan_width, $fan_style; global $name, $pgv_lang, $SHOW_ID_NUMBERS, $view, $TEXT_DIRECTION; global $stylesheet, $print_stylesheet; global $PGV_IMAGE_DIR, $PGV_IMAGES, $LINK_ICONS, $GEDCOM; // check for GD 2.x library if (!defined("IMG_ARC_PIE")) { print "<span class=\"error\">" . $pgv_lang["gd_library"] . "</span>"; print " <a href=\"" . $pgv_lang["gd_helplink"] . "\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["help"]["small"] . "\" class=\"icon\" alt=\"\" /></a><br /><br />"; return false; } if (!function_exists("ImageTtfBbox")) { print "<span class=\"error\">" . $pgv_lang["gd_freetype"] . "</span>"; print " <a href=\"" . $pgv_lang["gd_helplink"] . "\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["help"]["small"] . "\" class=\"icon\" alt=\"\" /></a><br /><br />"; return false; } // parse CSS file include "includes/cssparser.inc.php"; $css = new cssparser(false); if ($view == "preview") { $css->Parse($print_stylesheet); } else { $css->Parse($stylesheet); } // check for fontfile $fontfile = $css->Get(".fan_chart", "font-family"); $fontsize = $css->Get(".fan_chart", "font-size"); $fontfile = str_replace("url(", "", $fontfile); $fontfile = str_replace(")", "", $fontfile); if (!file_exists($fontfile)) { if (!empty($fontfile)) { print "<span class=\"error\">" . $pgv_lang["fontfile_error"] . " : {$fontfile}</span>"; } $fontfile = "./includes/fonts/DejaVuSans.ttf"; } if ($fontfile[0] != '/') { $fontfile = dirname(__FILE__) . "/" . $fontfile; } if (!file_exists($fontfile)) { print "<span class=\"error\">" . $pgv_lang["fontfile_error"] . " : {$fontfile}</span>"; return false; } if (intval($fontsize) < 2) { $fontsize = 7; } $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 * 0.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); $rgb = $css->Get(".fan_chart", "color"); if (empty($rgb)) { $rgb = "#000000"; } $color = ImageColorAllocate($image, hexdec(substr($rgb, 1, 2)), hexdec(substr($rgb, 3, 2)), hexdec(substr($rgb, 5, 2))); $rgb = $css->Get(".fan_chart", "background-color"); if (empty($rgb)) { $rgb = "#EEEEEE"; } $bgcolor = ImageColorAllocate($image, hexdec(substr($rgb, 1, 2)), hexdec(substr($rgb, 3, 2)), hexdec(substr($rgb, 5, 2))); $rgb = $css->Get(".fan_chart_box", "background-color"); if (empty($rgb)) { $rgb = "#D0D0AC"; } $bgcolorM = ImageColorAllocate($image, hexdec(substr($rgb, 1, 2)), hexdec(substr($rgb, 3, 2)), hexdec(substr($rgb, 5, 2))); $rgb = $css->Get(".fan_chart_boxF", "background-color"); if (empty($rgb)) { $rgb = "#D0ACD0"; } $bgcolorF = ImageColorAllocate($image, hexdec(substr($rgb, 1, 2)), hexdec(substr($rgb, 3, 2)), hexdec(substr($rgb, 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]; if (!empty($pid)) { $indirec = find_person_record($pid); if (!$indirec) { $indirec = find_updated_record($pid); } if ($sosa % 2) { $bg = $bgcolorF; } else { $bg = $bgcolorM; } if ($sosa == 1) { $bg = $bgcolor; // sex unknown if (preg_match("/1 SEX F/", $indirec) > 0) { $bg = $bgcolorF; } else { if (preg_match("/1 SEX M/", $indirec) > 0) { $bg = $bgcolorM; } } } ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bg, IMG_ARC_PIE); $person = Person::getInstance($pid); $name = $person->getFullName(); $addname = $person->getAddName(); //$name = str_replace(array('<span class="starredname">', '</span>'), '', $name); //$addname = str_replace(array('<span class="starredname">', '</span>'), '', $addname); //$name = str_replace(array('<span class="starredname">', '</span>'), array('<u>', '</u>'), $name); //@@ //$addname = str_replace(array('<span class="starredname">', '</span>'), array('<u>', '</u>'), $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 (displayDetailsById($pid)) { $birthrec = get_sub_record(1, "1 BIRT", $indirec); $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", $indirec); $ct = preg_match("/2 DATE.*(\\d\\d\\d\\d)/", $deathrec, $match); if ($ct > 0) { $text .= "-" . trim($match[1]); } } $text = unhtmlentitiesrtl($text); $text = strip_tags($text); //Do we still need? // split and center text by lines $wmax = floor($angle * 7 / $fontsize * $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) $fontsize, 0, $fontfile, $text); $textwidth = $bbox[4]; $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 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) $fontsize, $tangle, $tx, $ty, $color, $fontfile, $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 $tempURL = "javascript://" . htmlspecialchars(strip_tags($name)); if ($SHOW_ID_NUMBERS) { $tempURL .= " (" . $pid . ")"; } $imagemap .= "\" href=\"{$tempURL}\" "; $tempURL = "fanchart.php?rootid={$pid}&PEDIGREE_GENERATIONS={$PEDIGREE_GENERATIONS}&fan_width={$fan_width}&fan_style={$fan_style}"; if (!empty($view)) { $tempURL .= "&view={$view}"; } $count = 0; $lbwidth = 200; print "<div id=\"I" . $pid . "." . $count . "links\" style=\"position:absolute; >"; print "left:" . $tx . "px; top:" . $ty . "px; width: " . $lbwidth . "px; visibility:hidden; z-index:'100';\">"; print "<table class=\"person_box\"><tr><td class=\"details1\">"; print "<a href=\"individual.php?pid={$pid}\" class=\"name1\">" . PrintReady($name); if (!empty($addname)) { print "<br />" . PrintReady($addname); } print "</a>"; print "<br /><a href=\"pedigree.php?rootid={$pid}\" >" . $pgv_lang["index_header"] . "</a>"; print "<br /><a href=\"descendancy.php?pid={$pid}\" >" . $pgv_lang["descend_chart"] . "</a>"; if (PGV_USER_GEDCOM_ID) { print "<br /><a href=\"" . encode_url("relationship.php?pid1=" . PGV_USER_GEDCOM_ID . "&pid2={$pid}&ged={$GEDCOM}") . "\" onmouseover=\"clear_family_box_timeout('" . $pid . "." . $count . "');\" onmouseout=\"family_box_timeout('" . $pid . "." . $count . "');\">" . $pgv_lang["relationship_to_me"] . "</a>"; } print "<br /><a href=\"ancestry.php?rootid={$pid}\" onmouseover=\"clear_family_box_timeout('" . $pid . "." . $count . "');\" onmouseout=\"family_box_timeout('" . $pid . "." . $count . "');\">" . $pgv_lang["ancestry_chart"] . "</a>"; print "<br /><a href=\"compact.php?rootid={$pid}\" onmouseover=\"clear_family_box_timeout('" . $pid . "." . $count . "');\" onmouseout=\"family_box_timeout('" . $pid . "." . $count . "');\">" . $pgv_lang["compact_chart"] . "</a>"; print "<br /><a href=\"" . encode_url($tempURL) . "\" onmouseover=\"clear_family_box_timeout('" . $pid . "." . $count . "');\" onmouseout=\"family_box_timeout('" . $pid . "." . $count . "');\">" . $pgv_lang["fan_chart"] . "</a>"; print "<br /><a href=\"hourglass.php?pid={$pid}\" onmouseover=\"clear_family_box_timeout('" . $pid . "." . $count . "');\" onmouseout=\"family_box_timeout('" . $pid . "." . $count . "');\">" . $pgv_lang["hourglass_chart"] . "</a>"; if ($sosa >= 1) { $famids = find_sfamily_ids($pid); //-- make sure there is more than 1 child in the family with parents $cfamids = find_family_ids($pid); $num = 0; for ($f = 0; $f < count($cfamids); $f++) { $famrec = find_family_record($cfamids[$f]); if ($famrec) { $num += preg_match_all("/1\\s*CHIL\\s*@(.*)@/", $famrec, $smatch, PREG_SET_ORDER); } } if ($famids || $num > 1) { //-- spouse(s) and children for ($f = 0; $f < count($famids); $f++) { $famrec = find_family_record(trim($famids[$f])); if ($famrec) { $parents = find_parents($famids[$f]); if ($parents) { if ($pid != $parents["HUSB"]) { $spid = $parents["HUSB"]; } else { $spid = $parents["WIFE"]; } $person = Person::getInstance($spid); if ($person) { echo '<br /><a href="', $person->getLinkUrl(), '" class="name1">', $person->getFullName(), '</a>'; } } $num = preg_match_all("/1\\s*CHIL\\s*@(.*)@/", $famrec, $smatch, PREG_SET_ORDER); for ($i = 0; $i < $num; $i++) { $person = Person::getInstance($smatch[$i][1]); if ($person) { echo '<br /> <a href="', $person->getLinkUrl(), '" class="name1">< ', $person->getFullName(), '</a>'; } } } } //-- siblings for ($f = 0; $f < count($cfamids); $f++) { $famrec = find_family_record($cfamids[$f]); if ($famrec) { $num = preg_match_all("/1\\s*CHIL\\s*@(.*)@/", $famrec, $smatch, PREG_SET_ORDER); if ($num > 2) { print "<br /><span class=\"name1\">" . $pgv_lang["siblings"] . "</span>"; } if ($num == 2) { print "<br /><span class=\"name1\">" . $pgv_lang["sibling"] . "</span>"; } for ($i = 0; $i < $num; $i++) { $cpid = $smatch[$i][1]; if ($cpid != $pid) { $person = Person::getInstance($cpid); if ($person) { echo '<br /> <a href="', $person->getLinkUrl(), '" class="name1"> ', $person->getFullName(), '</a>'; } } } } } } } print "</td></tr></table>"; print "</div>"; $imagemap .= " onclick=\"show_family_box('" . $pid . "." . $count . "', 'relatives'); return false;\""; $imagemap .= " onmouseout=\"family_box_timeout('" . $pid . "." . $count . "'); return false;\""; $imagemap .= " alt=\"" . PrintReady(strip_tags($name)) . "\" title=\"" . PrintReady(strip_tags($name)) . "\" />"; } $deg1 -= $angle; $deg2 -= $angle; $sosa--; } $rx -= $rw; $gen--; } $imagemap .= "</map>"; echo $imagemap; // PGV banner ;-) ImageStringUp($image, 1, $fanw - 10, $fanh / 3, PGV_PHPGEDVIEW_URL, $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 file name to send to browser $image_title = preg_replace("~<.*>~", "", $name) . " " . $pgv_lang["fan_chart"]; echo "<p align=\"center\" >"; echo "<img src=\"imageflush.php?image_type=png&image_name={$image_name}&height={$fanh}&width={$fanw}\" width=\"{$fanw}\" height=\"{$fanh}\" border=\"0\" alt=\"{$image_title}\" title=\"{$image_title}\" usemap=\"#fanmap\" />"; echo "</p>"; ImageDestroy($image); }
private function drawshape($image, $action, $color) { switch ($action % 7) { case 0: ImageFilledRectangle($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $color); break; case 1: case 2: ImageFilledEllipse($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $color); break; case 3: $points = array($this->getX(), $this->getY(), $this->getX(), $this->getY(), $this->getX(), $this->getY(), $this->getX(), $this->getY()); ImageFilledPolygon($image, $points, 4, $color); break; case 4: case 5: case 6: $start = $this->getInt() * 360 / 256; $end = $start + $this->getInt() * 180 / 256; ImageFilledArc($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $start, $end, $color, IMG_ARC_PIE); break; } }
function display() { $this->init(); $this->pie = @ImageCreateTrueColor($this->init_img_width, $this->init_img_height); $colBG = ImageColorAllocate($this->pie, $this->pie_color_bg[0], $this->pie_color_bg[1], $this->pie_color_bg[2]); ImageFill($this->pie, 0, 0, $colBG); $TotalArrayValues = array_sum($this->data); // The Legends $cellpadding=5; $max_str=0; $items=0; // $FontNumber = 5; $FontNumber = 3; foreach($this->legends as $k => $legend) { $percent = round($legend/$this->total*100, 2); $text = $this->legends[$k] . ': ' . str_pad($legend,6,' ',STR_PAD_LEFT) . ' ('.str_pad(number_format(($legend / $TotalArrayValues) * 100, 1),4,' ',STR_PAD_LEFT).'%)'; if(strlen($text) > $max_str) { $max_str = strlen($text); } $items++; } // $box_with = ImageFontHeight($FontNumber); // $box_height = ImageFontHeight($FontNumber); // $leg_height = ((ImageFontHeight($FontNumber)+10) * $items) + ($cellpadding * 2); // $leg_width = (ImageFontWidth($FontNumber) * ($max_str)) + ($cellpadding * 2);// +($box_with * 2); $leg_height = (((ImageFontHeight($FontNumber)+10) * $items) + ($cellpadding * 35))/2; $leg_width = ((ImageFontWidth($FontNumber) * ($max_str)) + ($cellpadding * 35))/2;// +($box_with * 2); $leg_img = ImageCreateTrueColor($leg_width, $leg_height); ImageFill($leg_img, 0, 0, $colBG); // text color $colTEXT = ImageColorAllocate($leg_img, $this->pie_color_text[0], $this->pie_color_text[1], $this->pie_color_text[2]); // text / legends backgroundcolor $colTEXTBG = ImageColorAllocate($leg_img, $this->pie_color_text_bg[0], $this->pie_color_text_bg[1], $this->pie_color_text_bg[2]); // border color for the legends $colTEXTBO = ImageColorAllocate($leg_img, $this->pie_color_border[0], $this->pie_color_border[1], $this->pie_color_border[2]); // the table + border for the legend // ImageFilledRectangle($leg_img, 0, 0, $leg_width, $leg_height, $colTEXTBG); // ImageRectangle($leg_img, 0, 0, $leg_width-1, $leg_height-1, $colTEXTBO); reset($this->data); $c=0; $valuecounter =0; /* $string_pre_colors = implode(',',$this->pre_colors); $fillcolorsarray = explode(',', str_replace('#','',$string_pre_colors)); for ($i = 0; $i < count($fillcolorsarray); $i++) { $label_color[] = ImageColorAllocate($leg_img, hexdec(substr($fillcolorsarray["$i"], 0, 2)) * 0.8, hexdec(substr($fillcolorsarray["$i"], 2, 2)) * 0.8, hexdec(substr($fillcolorsarray["$i"], 4, 2)) * 0.8); } */ $lx = $box_with + $cellpadding*2; $ly = $cellpadding; $TamanhoLinha = 255; // if (!$CreatePie) //Existirá em piechart... Não matar... // { $TamanhoLinha = $leg_width; // } foreach($this->data as $k => $data) { // legend text item $percent = round($data/$this->total*100, 2); $text = $this->legends[$k] . ': ' . str_pad($data,6,' ',STR_PAD_LEFT) . ' ('.str_pad(number_format(($data / $TotalArrayValues) * 100, 1),4,' ',STR_PAD_LEFT).'%)'; $col = $this->get_color($k, "normal"); // ImageFilledRectangle($leg_img, $cellpadding, $ly+2, $cellpadding+$box_with, $ly+$box_height+2, $col); // ImageRectangle($leg_img, $cellpadding, $ly+2, $cellpadding+$box_with, $ly+$box_height+2, $colTEXTBO); //teste ImageString($leg_img, 2, $lx, $ly, $text, $colTEXT); // ImageString($leg_img, $FontNumber, $lx, $ly, $text, $col); $MeuY = round((ImageFontHeight($FontNumber) * .5) + ($valuecounter * 1.5 * ImageFontHeight($FontNumber))); ImageString($leg_img, $FontNumber, 5, $MeuY, $text, $col); $MeuYLinha = $MeuY + ImageFontHeight($FontNumber) + 2; ImageLine($leg_img, 5, $MeuYLinha, $TamanhoLinha, $MeuYLinha, '999999'); // ImageLine($im, 5, $MeuYLinha+2, $TamanhoLinha, $MeuYLinha+2, '999999'); $ly += ($FontNumber + ImageFontHeight($FontNumber)); $c++; $valuecounter++; } // final setups an image creation // Do the 3d effect $this->start_3d = $this->cy + $this->init_3d_height; for($i=$this->start_3d;$i > $this->cy; $i--) { reset($this->pie_data); $c=0; foreach($this->pie_data as $k => $data) { $col = $this->get_color($k, "3d"); ImageFilledArc($this->pie, $this->cx, $i, $this->init_width, $this->init_height, $data[0], $data[1], $col, IMG_ARC_NOFILL); $c++; } } // Now do the graph reset($this->pie_data); $c=0; foreach($this->pie_data as $k => $data) { $col = $this->get_color($k, "normal"); ImageFilledArc($this->pie, $this->cx, $this->cy, $this->init_width, $this->init_height, $data[0], $data[1], $col, IMG_ARC_PIE); $c++; } $pie_width = ImageSX($this->pie); $pie_height = ImageSY($this->pie); if($this->img_height < $leg_height) { $this->img_height = $leg_height; } $final = ImageCreateTrueColor($this->img_width+$leg_width+$cellpadding, $this->img_height); $ly += (2 + ImageFontHeight(2)); ImageFill($final, 0, 0, $colBG); ImageCopyResampled($final, $leg_img, 0, 0, 0, 0, $this->img_width, $this->img_height, $leg_width, $leg_height); ImageCopyResampled($final, $this->pie, $this->img_width+$cellpadding, 0, 0, 0, $leg_width, $leg_height, $pie_width, $pie_height); // print debugging info, creation time /* if($this->display_creation_time) { // add creation time if wanted $this->endtime = microtime(); list($susec, $ssec) = explode(" ",$this->starttime); $this->starttime = $susec+$ssec; list($eusec, $esec) = explode(" ",$this->endtime); $this->endtime = $eusec+$esec; $time = round ($this->endtime-$this->starttime, 2); $time_text = "creation time: ".$time." sec"; ImageString($final, 1, ($this->pie_width+$cellpadding), ($this->img_height-ImageFontHeight(1)), $time_text, $colTEXT); } */ header('Content-type: image/png'); ImagePNG($final); ImageDestroy($this->pie); ImageDestroy($leg_img); ImageDestroy($final); return TRUE; }
function Diagramm($im, $VALUES, $LEGEND) { //GLOBAL $COLORS,$SHADOWS; $black = ImageColorAllocate($im, 0, 0, 0); // Получим размеры изображения $W = ImageSX($im); $H = ImageSY($im); // Вывод легенды ##################################### // Посчитаем количество пунктов, от этого зависит высота легенды //$legend_count=count($LEGEND); $legend_count = $this->ucount; // Посчитаем максимальную длину пункта, от этого зависит ширина легенды $max_length = 0; foreach ($LEGEND as $v) { if ($max_length < strlen($v)) { $max_length = strlen($v); } } // Номер шрифта, котором мы будем выводить легенду $FONT = 2; $font_w = ImageFontWidth($FONT); $font_h = ImageFontHeight($FONT); // Вывод прямоугольника - границы легенды ---------------------------- $l_width = $font_w * $max_length + $font_h + 10 + 5 + 10; $l_height = $font_h * $legend_count + 10 + 10; // Получим координаты верхнего левого угла прямоугольника - границы легенды $l_x1 = $W - 10 - $l_width; $l_y1 = ($H - $l_height) / 2; // Выводя прямоугольника - границы легенды //ImageRectangle($im, $l_x1, $l_y1, $l_x1+$l_width, $l_y1+$l_height, $black); // Вывод текст легенды и цветных квадратиков $text_x = $l_x1 + 10 + 5 + $font_h; $square_x = $l_x1 + 10; $y = $l_y1 + 10; $i = 0; foreach ($LEGEND as $v) { $dy = $y + $i * $font_h; ImageString($im, $FONT, $text_x, $dy, $v, $black); ImageFilledRectangle($im, $square_x + 1, $dy + 1, $square_x + $font_h - 1, $dy + $font_h - 1, $this->COLORS[$i]); ImageRectangle($im, $square_x + 1, $dy + 1, $square_x + $font_h - 1, $dy + $font_h - 1, $black); $i++; } // Вывод круговой диаграммы ---------------------------------------- $total = array_sum($VALUES); $anglesum = $angle = array(0); $i = 1; // Расчет углов while ($i < count($VALUES)) { $part = $VALUES[$i - 1] / $total; $angle[$i] = floor($part * 360); $anglesum[$i] = array_sum($angle); $i++; } $anglesum[] = $anglesum[0]; // Расчет диаметра // $diametr=$l_x1-10-10; $diametr = $l_x1 - 10 - 10; // Расчет координат центра эллипса $circle_x = $diametr / 2 + 10; $circle_y = $H / 2 - 10; // Поправка диаметра, если эллипс не помещается по высоте if ($diametr > $H * 2 - 10 - 10) { $diametr = $H * 2 - 20 - 20 - 40; } // Вывод тени for ($j = 20; $j > 0; $j--) { for ($i = 0; $i < count($anglesum) - 1; $i++) { ImageFilledArc($im, $circle_x, $circle_y + $j, $diametr, $diametr / 2, $anglesum[$i], $anglesum[$i + 1], $this->SHADOWS[$i], IMG_ARC_PIE); } } // Вывод круговой диаграммы for ($i = 0; $i < count($anglesum) - 1; $i++) { ImageFilledArc($im, $circle_x, $circle_y, $diametr, $diametr / 2, $anglesum[$i], $anglesum[$i + 1], $this->COLORS[$i], IMG_ARC_PIE); } }
function Diagramm($im, $VALUES, $LEGEND) { global $COLORS, $SHADOWS; $black = ImageColorAllocate($im, 0, 0, 0); // Получим размеры изображения $W = ImageSX($im); $H = ImageSY($im); // Вывод круговой диаграммы ---------------------------------------- $total = array_sum($VALUES); $anglesum = $angle = array(0); $i = 1; // Расчет углов while ($i < count($VALUES)) { $part = $VALUES[$i - 1] / $total; $angle[$i] = floor($part * 360); $anglesum[$i] = array_sum($angle); $i++; } $anglesum[] = $anglesum[0]; // Расчет диаметра $diametr = $W; // Расчет координат центра эллипса $circle_x = $diametr / 2; $circle_y = $H / 2 - 10; // Поправка диаметра, если эллипс не помещается по высоте //if ($diametr>($H*2)-10) $diametr=($H*2)-40; // Вывод тени for ($j = 20; $j > 0; $j--) { for ($i = 0; $i < count($anglesum) - 1; $i++) { ImageFilledArc($im, $circle_x, $circle_y + $j, $diametr, $diametr / 2 - 10, $anglesum[$i], $anglesum[$i + 1], $SHADOWS[$i], IMG_ARC_PIE); } } // Вывод круговой диаграммы for ($i = 0; $i < count($anglesum) - 1; $i++) { ImageFilledArc($im, $circle_x, $circle_y, $diametr, $diametr / 2 - 10, $anglesum[$i], $anglesum[$i + 1], $COLORS[$i], IMG_ARC_PIE); } }
function DrawDot($x_world, $y_world, $dot_type, $color) { $half_point = $this->point_size / 2; $x_mid = $this->xtr($x_world); $y_mid = $this->ytr($y_world); $x1 = $x_mid - $half_point; $x2 = $x_mid + $half_point; $y1 = $y_mid - $half_point; $y2 = $y_mid + $half_point; switch ($dot_type) { case 'halfline': ImageLine($this->img, $x1, $y_mid, $x_mid, $y_mid, $color); break; case 'line': ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); break; case 'plus': ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color); break; case 'cross': ImageLine($this->img, $x1, $y1, $x2, $y2, $color); ImageLine($this->img, $x1, $y2, $x2, $y1, $color); break; case 'rect': ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; case 'circle': ImageArc($this->img, $x_mid, $y_mid, $this->point_size, $this->point_size, 0, 360, $color); break; case 'dot': ImageFilledArc($this->img, $x_mid, $y_mid, $this->point_size, $this->point_size, 0, 360, $color, IMG_ARC_PIE); break; case 'diamond': $arrpoints = array($x1, $y_mid, $x_mid, $y1, $x2, $y_mid, $x_mid, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'triangle': $arrpoints = array($x1, $y_mid, $x2, $y_mid, $x_mid, $y2); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'trianglemid': $arrpoints = array($x1, $y1, $x2, $y1, $x_mid, $y_mid); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; default: ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; } return TRUE; }
<?php $styles = [IMG_ARC_PIE, IMG_ARC_CHORD, IMG_ARC_PIE | IMG_ARC_NOFILL, IMG_ARC_PIE | IMG_ARC_NOFILL | IMG_ARC_EDGED]; $size = 100; $image = ImageCreateTrueColor($size * count($styles), $size); $background_color = 0xffffff; // white ImageFilledRectangle($image, 0, 0, $size * count($styles) - 1, $size * count($styles) - 1, $background_color); $black = 0x0; // aka 0 for ($i = 0; $i < count($styles); $i++) { ImageFilledArc($image, $size / 2 + $i * $size, $size / 2, $size - 1, $size - 1, 0, 135, $black, $styles[$i]); } header('Content-type: image/png'); ImagePNG($image); ImageDestroy($image);
function PrintGraph($pie_array) { global $graph_width, $graph_height, $graph_title, $graph_padding, $use_logo, $full_img_url, $first, $i, $pie_array_sum; $im = imagecreate($graph_width, $graph_height); if ($use_logo == 1) { /* Import logo */ $logo = ImageCreateFromPNG($full_img_url); /* Get size of imported logo */ $logo_size = GetImageSize($full_img_url); $logo_width = $logo_size[0]; $logo_height = $logo_size[1]; /* Copy the logo into the graph */ $logo_dst_x = $graph_width - $logo_width - $graph_padding; //How far from left to position $logo_dst_y = $graph_height - $logo_height - $graph_padding - 0; //How far from top to position ImageCopy($im, $logo, $logo_dst_x, $logo_dst_y, 0, 0, $logo_width, $logo_height); } /* Make our color palette */ $white = ImageColorAllocate($im, 255, 255, 255); $black = ImageColorAllocate($im, 0, 0, 0); $darkblue = ImageColorAllocate($im, 72, 107, 143); $mediumgrey = ImageColorAllocate($im, 210, 210, 210); $color[] = ImageColorAllocate($im, 255, 0, 0); $color[] = ImageColorAllocate($im, 255, 0, 255); $color[] = ImageColorAllocate($im, 0, 0, 255); $color[] = ImageColorAllocate($im, 0, 255, 255); $color[] = ImageColorAllocate($im, 0, 255, 0); $color[] = ImageColorAllocate($im, 255, 255, 0); /* Fill the border of the whole graph with blue */ ImageRectangle($im, 0, 0, $graph_width - 1, $graph_height - 1, $darkblue); ImageString($im, 5, $graph_width / 2 - strlen($graph_title) * 4, $graph_padding, $graph_title, $black); foreach ($pie_array as $name => $value) { $pie_value = round(360 * ($value / $pie_array_sum), 0); /* Draw pie slices */ /* Draw pie slice with black border and filled with color */ ImageFilledArc($im, 130, 120 + $graph_padding + 20, 175, 175, $first, $pie_value + $first, $color[$i], IMG_ARC_PIE); ImageFilledArc($im, 130, 120 + $graph_padding + 20, 175, 175, $first, $pie_value + $first, $black, IMG_ARC_EDGED | IMG_ARC_NOFILL); $new_pie_value = 0; $math = $pie_value / 2 + $new_pie_value; $new_pie_value = $pie_value + $new_pie_value; //Determine padding for x and y position for numbers next to pie slices $pie_padding = number_padding($math); $x_padding = $pie_padding["x"]; $y_padding = $pie_padding["y"]; ImageString($im, 2, round(130 + cos(deg2rad($math)) * (175 / 2)) + $x_padding, round(120 + sin(deg2rad($math)) * (175 / 2)) + $y_padding + 20, $value, $black); $extra = $extra + 15; $first = $first + $pie_value; /* Draw the key */ /* Draw the rectangles with black border */ ImageRectangle($im, 130 + 130 - 1, $graph_padding + 40 + $extra - 1, 140 + 130 + 1, $graph_padding + 30 + $extra + 1 + 20, $black); ImageFilledRectangle($im, 130 + 130, $graph_padding + 40 + $extra, 140 + 130, $graph_padding + 30 + $extra + 20, $color[$i]); /* Draw the string name next to each rectangle */ ImageString($im, 2, 130 + 80 + 65, $graph_padding + 40 + $extra, "{$name}", $black); $i++; } /* Print the copyright */ /* Note: Please leave our copyright as-is. */ $copyright = "Copyright 2003 - AdeptiSoft.com"; ImageString($im, 3, $graph_width / 2 - strlen($copyright) * 3.5, $graph_padding + 120 + 10 + 120, $copyright, $mediumgrey); imagepng($im); imagedestroy($im); }
$value += $data[$i]; $end = ceil($value / $data_sum * 360) + 270; $slice[] = array($start, $end, $shadow_color[$value_counter % count($shadow_color)], $fill_color[$value_counter % count($fill_color)]); $start = $end; $value_counter++; } for ($i = $centerY + $shadow_height; $i > $centerY; $i--) { for ($j = 0; $j < count($slice); $j++) { if ($slice[$j][0] != $slice[$j][1]) { ImageFilledArc($img, $centerX, $i, $diameterX, $diameterY, $slice[$j][0], $slice[$j][1], $slice[$j][2], IMG_ARC_PIE); } } } for ($j = 0; $j < count($slice); $j++) { if ($slice[$j][0] != $slice[$j][1]) { ImageFilledArc($img, $centerX, $centerY, $diameterX, $diameterY, $slice[$j][0], $slice[$j][1], $slice[$j][3], IMG_ARC_PIE); } } OutputImage($img); ImageDestroy($img); function colorHex($img, $HexColorString) { $R = hexdec(substr($HexColorString, 0, 2)); $G = hexdec(substr($HexColorString, 2, 2)); $B = hexdec(substr($HexColorString, 4, 2)); return ImageColorAllocate($img, $R, $G, $B); } function colorHexshadow($img, $HexColorString, $mork) { $R = hexdec(substr($HexColorString, 0, 2)); $G = hexdec(substr($HexColorString, 2, 2));
/** * 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" * * @return string */ public function generateFanChart($what) { $treeid = $this->sosaAncestors($this->generations); $fanw = 640 * $this->fan_width / 100; $fandeg = 90 * $this->fan_style; $html = ''; $treesize = count($treeid) + 1; // 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(Theme::theme()->parameter('chart-font-color'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-font-color'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-font-color'), 4, 2))); $bgcolor = ImageColorAllocate($image, hexdec(substr(Theme::theme()->parameter('chart-background-u'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-u'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-u'), 4, 2))); $bgcolorM = ImageColorAllocate($image, hexdec(substr(Theme::theme()->parameter('chart-background-m'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-m'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-m'), 4, 2))); $bgcolorF = ImageColorAllocate($image, hexdec(substr(Theme::theme()->parameter('chart-background-f'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-f'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-f'), 4, 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) { $person = $treeid[$sosa]; if ($person) { $name = $person->getFullName(); $addname = $person->getAddName(); $text = I18N::reverseText($name); if ($addname) { $text .= "\n" . I18N::reverseText($addname); } $text .= "\n" . I18N::reverseText($person->getLifeSpan()); switch ($person->getSex()) { case 'M': $bg = $bgcolorM; break; case 'F': $bg = $bgcolorF; break; default: $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 / Theme::theme()->parameter('chart-font-size') * $scale); $wmax = min($wmax, 35 * $scale); if ($gen == 0) { $wmax = min($wmax, 17 * $scale); } $text = $this->splitAlignText($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, Theme::theme()->parameter('chart-font-size'), $tangle, $tx, $ty, $color, Theme::theme()->parameter('chart-font-name'), $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 $pid = $person->getXref(); $imagemap .= '" href="#' . $pid . '"'; $tempURL = 'fanchart.php?rootid=' . $pid . '&generations=' . $this->generations . '&fan_width=' . $this->fan_width . '&fan_style=' . $this->fan_style . '&ged=' . $person->getTree()->getNameUrl(); $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 . '&ged=' . $person->getTree()->getNameUrl() . '" >' . I18N::translate('Pedigree') . '</a></li>'; if (Module::getModuleByName('googlemap')) { $html .= '<li><a href="module.php?mod=googlemap&mod_action=pedigree_map&rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Pedigree map') . '</a></li>'; } $gedcomid = $person->getTree()->getUserPreference(Auth::user(), 'gedcomid'); if ($gedcomid && $gedcomid != $pid) { $html .= '<li><a href="relationship.php?pid1=' . $gedcomid . '&pid2=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Relationship to me') . '</a></li>'; } $html .= '<li><a href="descendancy.php?rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '" >' . I18N::translate('Descendants') . '</a></li>'; $html .= '<li><a href="ancestry.php?rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Ancestors') . '</a></li>'; $html .= '<li><a href="compact.php?rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Compact tree') . '</a></li>'; $html .= '<li><a href="' . $tempURL . '">' . I18N::translate('Fan chart') . '</a></li>'; $html .= '<li><a href="hourglass.php?rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Hourglass chart') . '</a></li>'; if (Module::getModuleByName('tree')) { $html .= '<li><a href="module.php?mod=tree&mod_action=treeview&ged=' . $person->getTree()->getNameUrl() . '&rootid=' . $pid . '">' . 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">'; // With two children in a family, you have only one sibling. $html .= count($children) > 2 ? I18N::translate('Siblings') : I18N::translate('Sibling'); $html .= '</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': return $html . $imagemap . '<div id="fan_chart_img"><img src="' . WT_SCRIPT_NAME . '?rootid=' . $this->root->getXref() . '&fan_style=' . $this->fan_style . '&generations=' . $this->generations . '&fan_width=' . $this->fan_width . '&img=1" width="' . $fanw . '" height="' . $fanh . '" alt="' . strip_tags($this->getPageTitle()) . '" usemap="#fanmap"></div>'; case 'png': ImageStringUp($image, 1, $fanw - 10, $fanh / 3, WT_BASE_URL, $color); ob_start(); ImagePng($image); ImageDestroy($image); return ob_get_clean(); default: throw new \InvalidArgumentException(__METHOD__ . ' ' . $what); } }
function MakeFilledButtonPolygon($width, $height, &$actwidth, &$actheight, $radius, $color, $bkcolor = "clear") { $w = $width; $h = $height; $r = $radius; // validate the dimensions .. radius trumps height and width if ($r > $h / 2) { $h = $r * 2; } if ($r > $w / 2) { $w = $r * 2; } $actwidth = $w; $actheight = $h; // size of the straight side sections $w_str = $w - 2 * $r; $h_str = $h - 2 * $r; if ($w_str < 0) { $w_str = 0; } if ($h_str < 0) { $h_str = 0; } // create a color object to work with $color = new cColor($color); $bkcolor = new cColor($bkcolor); // make some adjustments for // and an image $im = ImageCreateTrueColor($w, $h); $col = $color->Allocate($im); $bk = $bkcolor->Allocate($im); imagefilledrectangle($im, 0, 0, $w - 1, $h - 1, $bk); // this may be substituted for imagefill $bkcolor->MakeTransparent($im); ImageFilledRectangle($im, 0, $r, $w_str + 2 * $r, $r + $h_str, $col); ImageFilledRectangle($im, $r, 0, $r + $w_str, $h_str + 2 * $r, $col); ImageFilledArc($im, $r, $r, $r * 2, $r * 2, 180, 270, $col, IMG_ARC_PIE); ImageFilledArc($im, $r, $r + $h_str - 1, $r * 2, $r * 2, 90, 180, $col, IMG_ARC_PIE); ImageFilledArc($im, $r + $w_str, $r, $r * 2, $r * 2, 270, 0, $col, IMG_ARC_PIE); ImageFilledArc($im, $r + $w_str, $r + $h_str - 1, $r * 2, $r * 2, 0, 90, $col, IMG_ARC_PIE); // return the image return $im; }
protected function DrawDot($x_world, $y_world, $record, $color) { $index = $record % $this->point_counts; $point_size = $this->point_sizes[$index]; $half_point = (int) ($point_size / 2); $x_mid = $this->xtr($x_world); $y_mid = $this->ytr($y_world); $x1 = $x_mid - $half_point; $x2 = $x_mid + $half_point; $y1 = $y_mid - $half_point; $y2 = $y_mid + $half_point; switch ($this->point_shapes[$index]) { case 'halfline': ImageLine($this->img, $x1, $y_mid, $x_mid, $y_mid, $color); break; case 'line': ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); break; case 'plus': ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color); break; case 'cross': ImageLine($this->img, $x1, $y1, $x2, $y2, $color); ImageLine($this->img, $x1, $y2, $x2, $y1, $color); break; case 'circle': ImageArc($this->img, $x_mid, $y_mid, $point_size, $point_size, 0, 360, $color); break; case 'dot': ImageFilledArc($this->img, $x_mid, $y_mid, $point_size, $point_size, 0, 360, $color, IMG_ARC_PIE); break; case 'diamond': $arrpoints = array($x1, $y_mid, $x_mid, $y1, $x2, $y_mid, $x_mid, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'triangle': $arrpoints = array($x1, $y_mid, $x2, $y_mid, $x_mid, $y2); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'trianglemid': $arrpoints = array($x1, $y1, $x2, $y1, $x_mid, $y_mid); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'yield': $arrpoints = array($x1, $y1, $x2, $y1, $x_mid, $y2); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'delta': $arrpoints = array($x1, $y2, $x2, $y2, $x_mid, $y1); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'star': ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color); ImageLine($this->img, $x1, $y1, $x2, $y2, $color); ImageLine($this->img, $x1, $y2, $x2, $y1, $color); break; case 'hourglass': $arrpoints = array($x1, $y1, $x2, $y1, $x1, $y2, $x2, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'bowtie': $arrpoints = array($x1, $y1, $x1, $y2, $x2, $y1, $x2, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'target': ImageFilledRectangle($this->img, $x1, $y1, $x_mid, $y_mid, $color); ImageFilledRectangle($this->img, $x_mid, $y_mid, $x2, $y2, $color); ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; case 'box': ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; case 'home': /* As in: "home plate" (baseball), also looks sort of like a house. */ $arrpoints = array($x1, $y2, $x2, $y2, $x2, $y_mid, $x_mid, $y1, $x1, $y_mid); ImageFilledPolygon($this->img, $arrpoints, 5, $color); break; case 'up': ImagePolygon($this->img, array($x_mid, $y1, $x2, $y2, $x1, $y2), 3, $color); break; case 'down': ImagePolygon($this->img, array($x_mid, $y2, $x1, $y1, $x2, $y1), 3, $color); break; case 'none': /* Special case, no point shape here */ break; default: /* Also 'rect' */ ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; } return TRUE; }
function draw() { $black = ImageColorAllocate($this->draw->res, 0, 0, 0); // ������� ������� ����������� $W = $this->draw->sX(); $H = $this->draw->sY(); $this->draw->antialias(TRUE); // ����� ������� ##################################### // ��������� ���������� �������,�� ����� ������� ������ ������� $this->legend_count = sizeof($this->legend); // ��������� ������������ ����� ������,�� ����� ������� ������ ������� $max_length = 0; foreach ($this->legend as $v) { if ($max_length < strlen($v)) { $max_length = strlen($v); } } // ����� ������,������� �� ����� �������� ������� $FONT = 2; $font_w = ImageFontWidth($FONT); $font_h = ImageFontHeight($FONT); // ����� �������������� - ������� ������� ---------------------------- $l_width = $font_w * $max_length + $font_h + 10 + 5 + 10; $l_height = $font_h * $this->legend_count + 10 + 10; // ������� ���������� �������� ������ ���� �������������� - ������� ������� $l_x1 = $W - 100 - $l_width; $l_y1 = ($H - $l_height) / 2; // ������ �������������� - ������� ������� ImageRectangle($this->draw->res, $l_x1, $l_y1, $l_x1 + $l_width, $l_y1 + $l_height, $black); // ����� ����� ������� � ������� ����������� $text_x = $l_x1 + 10 + 5 + $font_h; $square_x = $l_x1 + 10; $y = $l_y1 + 10; $i = 0; foreach ($this->legend as $v) { $dy = $y + $i * $font_h; $this->draw->ttftext($v, $black, CORE_PATH . 'fonts/TAHOMA.TTF', 8, $text_x, $dy + 11); ImageFilledRectangle($this->draw->res, $square_x + 1, $dy + 1, $square_x + $font_h - 1, $dy + $font_h - 1, $this->draw->hex2color($this->colors[$i])); ImageRectangle($this->draw->res, $square_x + 1, $dy + 1, $square_x + $font_h - 1, $dy + $font_h - 1, $black); $i++; } // ����� �������� ��������� ---------------------------------------- $sv = sizeof($this->values); if (sizeof($this->values) == 1) { $this->values[] = 9.999999999999999E-12; ++$sv; } $total = array_sum($this->values); $anglesum = $angle = array(0); $i = 1; // ������ ����� while ($i < $sv) { $part = $this->values[$i - 1] / $total; $angle[$i] = floor($part * 360); $anglesum[$i] = array_sum($angle); $i++; } $anglesum[] = $anglesum[0]; // ������ �������� $diametr = $l_x1 - 10 - 10; // ������ ��������� ������ ������� $circle_x = $diametr / 2 + 10; $circle_y = $H / 2 - 10; // �������� ��������,���� ������ �� ���������� �� ������ if ($diametr > $H * 2 - 10 - 10) { $diametr = $H * 2 - 20 - 20 - 40; } // ����� ���� for ($j = 20; $j > 0; $j--) { for ($i = 0; $i < sizeof($anglesum) - 1; $i++) { ImageFilledArc($this->draw->res, $circle_x, $circle_y + $j, $diametr, $diametr / 2, $anglesum[$i], $anglesum[$i + 1], $this->draw->hex2color($this->shadows[$i]), IMG_ARC_PIE); } } // ����� �������� ��������� for ($i = 0; $i < sizeof($anglesum) - 1; $i++) { ImageFilledArc($this->draw->res, $circle_x, $circle_y, $diametr, $diametr / 2, $anglesum[$i], $anglesum[$i + 1], $this->draw->hex2color($this->colors[$i]), IMG_ARC_PIE); } }
function draw_slices($x, $y, $angles, $colors) { $pie_count = count($angles); $PIE_THICKNESS = $this->diameter * 0.075; for ($j = $this->center_y + $PIE_THICKNESS; $j > $this->center_y; $j--) { for ($from = 0, $p = 0; $p < $pie_count; $p++, $from = $to) { $to = $from + $angles[$p]; if ($to > 360) { $to = 360; } if ($to == $from) { continue; } $color = $colors[$p]; $orig_colors = imageColorsForIndex($this->im, $color); $dark_red = $orig_colors['red'] > 30 ? $orig_colors['red'] - 30 : $orig_colors['red']; $dark_green = $orig_colors['green'] > 30 ? $orig_colors['green'] - 30 : $orig_colors['green']; $dark_blue = $orig_colors['blue'] > 30 ? $orig_colors['blue'] - 30 : $orig_colors['blue']; $new_color = ImageColorAllocate($this->im, $dark_red, $dark_green, $dark_blue); ImageFilledArc($this->im, $this->center_x, $j, $this->diameter, $this->diameter, $from, $to, $new_color, IMG_ARC_PIE); } } for ($from = 0, $p = 0; $p < $pie_count; $p++, $from = $to) { $to = $from + $angles[$p]; $color = $colors[$p]; if ($to > 360) { $to = 360; } if ($to == $from) { continue; } ImageFilledArc($this->im, $this->center_x, $this->center_y, $this->diameter, $this->diameter, $from, $to, $color, IMG_ARC_PIE); $from += $angles[$p]; } }
function graficopizza($data, $width, $inclinacao, $shadow_height, $cores, $map_file, $temaedit) { //////////////////////////////////////////////////////////////// // PHP script made by Rasmus Petersen - http://www.peters1.dk // //////////////////////////////////////////////////////////////// include_once "funcoes_gerais.php"; //<img src="http://www.domain.dk/piechart.php?data=10*9*11*10&label=Denmark*Germany*USA*Sweden" /> $show_label = false; // true = show label, false = don't show label. $show_percent = false; // true = show percentage, false = don't show percentage. $show_text = true; // true = show text, false = don't show text. $show_parts = false; // true = show parts, false = don't show parts. $label_form = 'square'; // 'square' or 'round' label. if (!isset($width)) { $width = 50; } if (!isset($inclinacao)) { $inclinacao = 1.5; } if (!isset($shadow_height)) { $shadow_height = 10; } $background_color = 'FFFFFF'; // background-color of the chart... $text_color = '000000'; // text-color. $colors = array('003366', 'CCD6E0', '7F99B2', 'F7EFC6', 'C6BE8C', 'CC6600', '990000', '520000', 'BFBFC1', '808080'); // colors of the slices. $colorsp = explode("*", $cores); //cores das fatias //$shadow_height = 16; // Height on shadown. $shadow_dark = true; // true = darker shadow, false = lighter shadow... // DON'T CHANGE ANYTHING BELOW THIS LINE... $height = $width / $inclinacao; $data = explode('*', $data); $img = ImageCreateTrueColor($width, $height + ceil($shadow_height)); imagetruecolortopalette($img, false, 256); // convert $white = imagecolorresolve($img, 255, 255, 255); // resolve given palette entry imagecolortransparent($img, $white); ImageFill($img, 0, 0, $white); foreach ($colorsp as $colorkode) { $fill_color[] = colorRGB($img, $colorkode); $shadow_color[] = colorRGBshadow($img, $colorkode, $shadow_dark); } $centerX = round($width / 2); $centerY = round($height / 2); $diameterX = $width - 4; $diameterY = $height - 4; $data_sum = array_sum($data); $start = 270; $value_counter = 0; $value = 0; $cd = count($data); for ($i = 0; $i < $cd; ++$i) { $value += $data[$i]; $end = ceil($value / $data_sum * 360) + 270; $slice[] = array($start, $end, $shadow_color[$value_counter % count($shadow_color)], $fill_color[$value_counter % count($fill_color)]); $start = $end; $value_counter++; } for ($i = $centerY + $shadow_height; $i > $centerY; $i--) { for ($j = 0; $j < count($slice); ++$j) { ImageFilledArc($img, $centerX, $i, $diameterX, $diameterY, $slice[$j][0], $slice[$j][1], $slice[$j][2], IMG_ARC_PIE); } } for ($j = 0; $j < count($slice); ++$j) { ImageFilledArc($img, $centerX, $centerY, $diameterX, $diameterY, $slice[$j][0], $slice[$j][1], $slice[$j][3], IMG_ARC_PIE); } $nome = nomeRandomico(20) . ".png"; $nomefisico = dirname($map_file) . "/" . $nome; $nomeurl = $nome; Imagepng($img, $nomefisico); ImageDestroy($img); return $nomefisico . "," . $nomeurl; }
protected function DrawPieChart() { if (!$this->CheckDataType('text-data, text-data-single, data-data')) { return FALSE; } $xpos = $this->plot_area[0] + $this->plot_area_width / 2; $ypos = $this->plot_area[1] + $this->plot_area_height / 2; $diameter = min($this->plot_area_width, $this->plot_area_height); $radius = $diameter / 2; if ($this->data_type == 'text-data') { // Get sum of each column - One pie slice per column: $num_slices = $this->records_per_group - 1; // records_per_group is the maximum row size if ($num_slices < 1) { return TRUE; } // Give up early if there is no data at all. $sumarr = array_fill(0, $num_slices, 0); for ($i = 0; $i < $this->num_data_rows; $i++) { for ($j = 1; $j < $this->num_recs[$i]; $j++) { // Skip label at [0] if (is_numeric($this->data[$i][$j])) { $sumarr[$j - 1] += abs($this->data[$i][$j]); } } } } elseif ($this->data_type == 'text-data-single') { // Or only one column per row, one pie slice per row: $num_slices = $this->num_data_rows; if ($num_slices < 1) { return TRUE; } // Give up early if there is no data at all. $sumarr = array_fill(0, $num_slices, 0); for ($i = 0; $i < $num_slices; $i++) { // $legend[$i] = $this->data[$i][0]; // Note: Labels are not used yet if (is_numeric($this->data[$i][1])) { $sumarr[$i] = abs($this->data[$i][1]); } } } else { // $this->data_type == 'data-data' $num_slices = $this->records_per_group - 2; // records_per_group is the maximum row size if ($num_slices < 1) { return TRUE; } // Give up early if there is no data at all. $sumarr = array_fill(0, $num_slices, 0); for ($i = 0; $i < $this->num_data_rows; $i++) { for ($j = 2; $j < $this->num_recs[$i]; $j++) { // Skip label at [0] an X and [1] if (is_numeric($this->data[$i][$j])) { $sumarr[$j - 2] += abs($this->data[$i][$j]); } } } } $total = array_sum($sumarr); if ($total == 0) { // There are either no valid data points, or all are 0. // See top comment about why not to make this an error. return TRUE; } if ($this->shading) { $diam2 = $diameter / 2; } else { $diam2 = $diameter; } $max_data_colors = count($this->data_colors); // Use the Y label format precision, with default value: if (isset($this->label_format['y']['precision'])) { $precision = $this->label_format['y']['precision']; } else { $precision = 1; } for ($h = $this->shading; $h >= 0; $h--) { $color_index = 0; $start_angle = 0; $end_angle = 0; for ($j = 0; $j < $num_slices; $j++) { $val = $sumarr[$j]; // For shaded pies: the last one (at the top of the "stack") has a brighter color: if ($h == 0) { $slicecol = $this->ndx_data_colors[$color_index]; } else { $slicecol = $this->ndx_data_dark_colors[$color_index]; } $label_txt = $this->number_format($val / $total * 100, $precision) . '%'; $val = 360 * ($val / $total); // NOTE that imagefilledarc measures angles CLOCKWISE (go figure why), // so the pie chart would start clockwise from 3 o'clock, would it not be // for the reversal of start and end angles in imagefilledarc() // Also note ImageFilledArc only takes angles in integer degrees, and if the // the start and end angles match then you get a full circle not a zero-width // pie. This is bad. So skip any zero-size wedge. On the other hand, we cannot // let cumulative error from rounding to integer result in missing wedges. So // keep the running total as a float, and round the angles. It should not // be necessary to check that the last wedge ends at 360 degrees. $start_angle = $end_angle; $end_angle += $val; // This method of conversion to integer - truncate after reversing it - was // chosen to match the implicit method of PHPlot<=5.0.4 to get the same slices. $arc_start_angle = (int) (360 - $start_angle); $arc_end_angle = (int) (360 - $end_angle); if ($arc_start_angle > $arc_end_angle) { $mid_angle = deg2rad($end_angle - $val / 2); // Draw the slice ImageFilledArc($this->img, $xpos, $ypos + $h, $diameter, $diam2, $arc_end_angle, $arc_start_angle, $slicecol, IMG_ARC_PIE); // Draw the labels only once if ($h == 0) { // Draw the outline if (!$this->shading) { ImageFilledArc($this->img, $xpos, $ypos + $h, $diameter, $diam2, $arc_end_angle, $arc_start_angle, $this->ndx_grid_color, IMG_ARC_PIE | IMG_ARC_EDGED | IMG_ARC_NOFILL); } // The '* 1.2' trick is to get labels out of the pie chart so there are more // chances they can be seen in small sectors. $label_x = $xpos + $diameter * 1.2 * cos($mid_angle) * $this->label_scale_position; $label_y = $ypos + $h - $diam2 * 1.2 * sin($mid_angle) * $this->label_scale_position; $this->DrawText($this->fonts['generic'], 0, $label_x, $label_y, $this->ndx_grid_color, $label_txt, 'center', 'center'); } } if (++$color_index >= $max_data_colors) { $color_index = 0; } } // end for } // end for return TRUE; }
/** * 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); } }
function DrawDot($x_world, $y_world, $record, $color) { // TODO: optimize, avoid counting every time we are called. $record = $record % count($this->point_shapes); $half_point = $this->point_sizes[$record] / 2; $x_mid = $this->xtr($x_world); $y_mid = $this->ytr($y_world); $x1 = $x_mid - $half_point; $x2 = $x_mid + $half_point; $y1 = $y_mid - $half_point; $y2 = $y_mid + $half_point; switch ($this->point_shapes[$record]) { case 'halfline': ImageLine($this->img, $x1, $y_mid, $x_mid, $y_mid, $color); break; case 'line': ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); break; case 'plus': ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color); break; case 'cross': ImageLine($this->img, $x1, $y1, $x2, $y2, $color); ImageLine($this->img, $x1, $y2, $x2, $y1, $color); break; case 'rect': ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; case 'circle': ImageArc($this->img, $x_mid, $y_mid, $this->point_sizes[$record], $this->point_sizes[$record], 0, 360, $color); break; case 'dot': ImageFilledArc($this->img, $x_mid, $y_mid, $this->point_sizes[$record], $this->point_sizes[$record], 0, 360, $color, IMG_ARC_PIE); break; case 'diamond': $arrpoints = array($x1, $y_mid, $x_mid, $y1, $x2, $y_mid, $x_mid, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'triangle': $arrpoints = array($x1, $y_mid, $x2, $y_mid, $x_mid, $y2); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'trianglemid': $arrpoints = array($x1, $y1, $x2, $y1, $x_mid, $y_mid); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'none': break; default: ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; } return TRUE; }
/** * print ancestors on a fan chart * @param array $treeid ancestry pid * @param int $fanw fan width in px (default=840) * @param int $fandeg fan size in deg (default=270) */ function print_fan_chart($treeid, $fanw = 840, $fandeg = 270) { global $dbh, $tree_id, $db_functions, $fontsize, $date_display; global $fan_style, $family_id; global $printing, $language, $selected_language; global $pers_var, $tree_prefix_quoted; global $china_message; // check for GD 2.x library if (!defined("IMG_ARC_PIE")) { print "ERROR: NO GD LIBRARY"; return false; } if (!function_exists("ImageTtfBbox")) { print "ERROR: NO GD LIBRARY"; return false; } if (intval($fontsize) < 2) { $fontsize = 7; } $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 * 0.86); } $scale = $fanw / 840; // 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); if ($printing == 1) { ImageColorTransparent($image, $white); } // *** Border colour *** $rgb = ""; if (empty($rgb)) { $rgb = "#6E6E6E"; } $grey = ImageColorAllocate($image, hexdec(substr($rgb, 1, 2)), hexdec(substr($rgb, 3, 2)), hexdec(substr($rgb, 5, 2))); // *** Text colour *** $rgb = ""; if (empty($rgb)) { $rgb = "#000000"; } $color = ImageColorAllocate($image, hexdec(substr($rgb, 1, 2)), hexdec(substr($rgb, 3, 2)), hexdec(substr($rgb, 5, 2))); // *** Background colour *** $rgb = ""; if (empty($rgb)) { $rgb = "#EEEEEE"; } $bgcolor = ImageColorAllocate($image, hexdec(substr($rgb, 1, 2)), hexdec(substr($rgb, 3, 2)), hexdec(substr($rgb, 5, 2))); // *** Man colour *** $rgb = ""; if (empty($rgb)) { $rgb = "#B2DFEE"; } $bgcolorM = ImageColorAllocate($image, hexdec(substr($rgb, 1, 2)), hexdec(substr($rgb, 3, 2)), hexdec(substr($rgb, 5, 2))); // *** wife colour *** $rgb = ""; if (empty($rgb)) { $rgb = "#FFE4C4"; } $bgcolorF = ImageColorAllocate($image, hexdec(substr($rgb, 1, 2)), hexdec(substr($rgb, 3, 2)), hexdec(substr($rgb, 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); ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bgcolor, IMG_ARC_EDGED | IMG_ARC_NOFILL); $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][0]; $birthyr = $treeid[$sosa][1]; $deathyr = $treeid[$sosa][4]; $fontpx = $fontsize; if ($sosa >= 16 and $fandeg == 180) { $fontpx = $fontsize - 1; } if ($sosa >= 32 and $fandeg != 180) { $fontpx = $fontsize - 1; } if (!empty($pid)) { if ($sosa % 2) { $bg = $bgcolorF; } else { $bg = $bgcolorM; } if ($sosa == 1) { if ($treeid[$sosa][5] == "F") { $bg = $bgcolorF; } else { if ($treeid[$sosa][5] == "M") { $bg = $bgcolorM; } else { $bg = $bgcolor; // sex unknown } } } ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bg, IMG_ARC_PIE); if ($gen != 0) { ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $grey, IMG_ARC_EDGED | IMG_ARC_NOFILL); } else { ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $grey, IMG_ARC_NOFILL); } $name = $pid; // check if string is RTL language- if it is, it has to be reversed later on by persian_log2vis() $rtlstr = 0; //if(preg_match('/(*UTF8)[א-ת]/',$name)!==0 OR preg_match('/(*UTF8)[أ-ى]/',$name)!==0) { if (preg_match('/(*UTF8)[א-ת]/', $name) === 1 or preg_match('/(*UTF8)[أ-ى]/', $name) === 1) { // this is either Hebrew, Arabic or Persian -> we have to reverse the text! $rtlstr = 1; } $fontfile = CMS_ROOTPATH . "include/fanchart/dejavusans.ttf"; // this default font serves: Latin,Hebrew,Arabic,Persian,Russian //if(preg_match('/(*UTF8)\p{Han}/',$name)!==0) { // String is Chinese so use a Chinese ttf font if present in the folder if (preg_match('/(*UTF8)\\p{Han}/', $name) === 1) { // String is Chinese so use a Chinese ttf font if present in the folder if (is_dir(CMS_ROOTPATH . "include/fanchart/chinese")) { $dh = opendir(CMS_ROOTPATH . "include/fanchart/chinese"); while (false !== ($filename = readdir($dh))) { //if (strtolower(substr($filename, -3)) == "ttf"){ if (strtolower(substr($filename, -3)) == "otf" or strtolower(substr($filename, -3)) == "ttf") { $fontfile = CMS_ROOTPATH . "include/fanchart/chinese/" . $filename; } } } if ($fontfile == CMS_ROOTPATH . "include/fanchart/dejavusans.ttf") { //no Chinese ttf file found $china_message = 1; } } $text = $name; // names $text2 = ""; // dates if ($date_display == 1) { // don't show dates } else { if ($date_display == 2) { //show years only // years only chosen but we also do this if no place in outer circles $text2 .= substr($birthyr, -4) . " - " . substr($deathyr, -4); } else { if ($date_display == 3) { //show full dates (but not in narrow outer circles!) if ($gen > 5) { $text2 .= substr($birthyr, -4) . " - " . substr($deathyr, -4); } else { if ($gen > 4 and $fan_style != 4) { $text2 .= substr($birthyr, -4) . " - " . substr($deathyr, -4); } else { // full dates if ($birthyr) { $text2 .= "b." . $birthyr . "\n"; } if ($deathyr) { $text2 .= "d." . $deathyr; } } } } } } // split and center text by lines $wmax = floor($angle * 7 / $fontpx * $scale); $wmax = min($wmax, 35 * $scale); //35 //$wmax = floor((90*$wmax)/100); if ($gen == 0) { $wmax = min($wmax, 17 * $scale); } //17 $text = split_align_text($text, $wmax, $rtlstr, 1, $gen); $text2 = split_align_text($text2, $wmax, $rtlstr, 0, $gen); if ($rtlstr == 1) { persian_log2vis($text); // converts persian, arab and hebrew text from logical to visual and reverses it } $text .= "\n" . $text2; // text angle $tangle = 270 - ($deg1 + $angle / 2); if ($gen == 0) { $tangle = 0; } // calculate text position $bbox = ImageTtfBbox((double) $fontpx, 0, $fontfile, $text); $textwidth = $bbox[4]; //4 $deg = $deg1 + 0.44; if ($deg2 - $deg1 > 40) { $deg = $deg1 + ($deg2 - $deg1) / 11; } // 11 if ($deg2 - $deg1 > 80) { $deg = $deg1 + ($deg2 - $deg1) / 7; } // 7 if ($deg2 - $deg1 > 140) { $deg = $deg1 + ($deg2 - $deg1) / 4; } // 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) $fontpx, $tangle, $tx, $ty, $color, $fontfile, $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}"; if (CMS_SPECIFIC == "Joomla") { $imagemap .= "\" href=\"index.php?option=com_humo-gen&task=family&id=" . $treeid[$sosa][2] . "&main_person=" . $treeid[$sosa][3] . "\""; } else { $imagemap .= "\" href=\"family.php?id=" . $treeid[$sosa][2] . "&main_person=" . $treeid[$sosa][3] . "\""; } //NEW - add first spouse to base person's tooltip $spousename = ""; if ($gen == 0 and $treeid[1][2] != "") { // base person and has spouse if ($treeid[1][5] == "F") { $spouse = "fam_man"; } else { $spouse = "fam_woman"; } $spouse_result = $dbh->query("SELECT " . $spouse . " FROM humo_families\n\t\t\t\t\t\tWHERE fam_tree_id='" . $tree_id . "' AND fam_gedcomnumber='" . $treeid[1][2] . "'"); @($spouseDb = $spouse_result->fetch()); // fetch() with no parameter deaults to array which is what we want here @($spouse2Db = $db_functions->get_person($spouseDb[$spouse])); $spouse_cls = new person_cls(); $spouse_cls->construct($spouse2Db); $spname = $spouse_cls->person_name($spouse2Db); if ($treeid[1][5] == "F") { $spouse_lan = "SPOUSE_MALE"; } else { $spouse_lan = "SPOUSE_FEMALE"; } if ($spname != "") { $spousename = "\n(" . __($spouse_lan) . ": " . $spname["standard_name"] . ")"; } } $imagemap .= " alt=\"" . $pid . "\" title=\"" . $pid . $spousename . "\">"; } $deg1 -= $angle; $deg2 -= $angle; $sosa--; } $rx -= $rw; $gen--; } $imagemap .= "</map>"; echo $imagemap; $image_title = preg_replace("~<.*>~", "", $name) . " - " . __('RELOAD FANCHART WITH \'VIEW\' BUTTON ON THE LEFT'); echo "<p align=\"center\" >"; if (CMS_SPECIFIC == "Joomla") { ImagePng($image, CMS_ROOTPATH . "include/fanchart/tmpimg.png"); $ext = "?" . time(); // add random string to file to prevent loading from cache and then replacing which is not nice echo "<img src=\"index.php?option=com_humo-gen&task=fanimage&format=raw&nochache=" . $ext . "\" width=\"{$fanw}\" height=\"{$fanh}\" border=\"0\" alt=\"{$image_title}\" title=\"{$image_title}\" usemap=\"#fanmap\">"; } else { 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; echo "<img src=\"include/fanchart/fanimage.php\" width=\"{$fanw}\" height=\"{$fanh}\" border=\"0\" alt=\"{$image_title}\" title=\"{$image_title}\" usemap=\"#fanmap\">"; } echo "</p>\n"; ImageDestroy($image); }