/** * {@inhericDoc} * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent() */ protected function renderContent() { $nb_found = $this->data->get('stats_gen_nb_found'); $nb_other = $this->data->get('stats_gen_nb_other'); $nb_unknown = $this->data->get('stats_gen_nb_unknown'); $perc_known = Functions::safeDivision($nb_found - $nb_other, $nb_found + $nb_unknown); $html = '<div id="geodispersion_summary"> <div class="maj-table center"> <div class="maj-row"> <div class="label">' . I18N::translate('Places found') . '</div> <div class="value">' . I18N::translate('%1$d (%2$s)', $nb_found - $nb_other, I18N::percentage($perc_known)) . '</div> </div>'; if ($nb_other > 0) { $perc_other = Functions::safeDivision($nb_other, $nb_found + $nb_unknown); $html .= '<div class="maj-row"> <div class="label">' . I18N::translate('Other places') . '</div> <div class="value">' . I18N::translate('%1$d (%2$s)', $nb_other, I18N::percentage($perc_other)) . '</div> </div>'; } $html .= '<div class="maj-row"> <div class="label">' . I18N::translate('Places not found') . '</div> <div class="value">' . I18N::translate('%1$d (%2$s)', $nb_unknown, I18N::percentage(1 - $perc_known)) . '</div> </div> </div> </div> <br/> <div id="geodispersion_data"> ' . $this->htmlAnalysisData() . ' </div>'; return $html; }
/** * {@inheritDoc} * @see \MyArtJaub\Webtrees\Module\GeoDispersion\Views\AbstractGeoAnalysisTabGeneralView::htmlAnalysisData() */ protected function htmlAnalysisData() { $results = $this->data->get('results'); $analysis_level = $this->data->get('analysis_level'); $nb_found = $this->data->get('stats_gen_nb_found'); $nb_other = $this->data->get('stats_gen_nb_other'); $i = 1; $previous_nb = 0; $html = '<div class="maj-table center">'; foreach ($results as $place => $nb) { $perc = Functions::safeDivision($nb, $nb_found - $nb_other); if ($nb != $previous_nb) { $j = I18N::number($i); } else { $j = ' '; } $levels = array_map('trim', explode(',', $place)); $placename = $levels[$analysis_level - 1]; if ($placename == '' && $analysis_level > 1) { $placename = I18N::translate('Unknown (%s)', $levels[$analysis_level - 2]); } $html .= '<div class="maj-row"> <div class="label"><strong>' . $j . '</strong></div> <div class="label">' . $placename . '</div> <div class="value">' . I18N::translate('%d', $nb) . '</div> <div class="value">' . I18N::percentage($perc, 1) . '</div> </div>'; $i++; $previous_nb = $nb; } $html .= '</div>'; return $html; }
/** * Create a chart of individuals with/without sources. * * @param string[] $params * * @return string */ public function chartFamsWithSources($params = array()) { $WT_STATS_CHART_COLOR1 = Theme::theme()->parameter('distribution-chart-no-values'); $WT_STATS_CHART_COLOR2 = Theme::theme()->parameter('distribution-chart-high-values'); $WT_STATS_S_CHART_X = Theme::theme()->parameter('stats-small-chart-x'); $WT_STATS_S_CHART_Y = Theme::theme()->parameter('stats-small-chart-y'); if (isset($params[0]) && $params[0] != '') { $size = strtolower($params[0]); } else { $size = $WT_STATS_S_CHART_X . "x" . $WT_STATS_S_CHART_Y; } if (isset($params[1]) && $params[1] != '') { $color_from = strtolower($params[1]); } else { $color_from = $WT_STATS_CHART_COLOR1; } if (isset($params[2]) && $params[2] != '') { $color_to = strtolower($params[2]); } else { $color_to = $WT_STATS_CHART_COLOR2; } $sizes = explode('x', $size); $tot_fam = $this->totalFamiliesQuery(); if ($tot_fam == 0) { return ''; } else { $tot_sfam_per = round($this->totalFamsWithSourcesQuery() / $tot_fam, 3); $chd = $this->arrayToExtendedEncoding(array(100 - 100 * $tot_sfam_per, 100 * $tot_sfam_per)); $chl = I18N::translate('Without sources') . ' - ' . I18N::percentage(1 - $tot_sfam_per, 1) . '|' . I18N::translate('With sources') . ' - ' . I18N::percentage($tot_sfam_per, 1); $chart_title = I18N::translate('Families with sources'); return "<img src=\"https://chart.googleapis.com/chart?cht=p3&chd=e:{$chd}&chs={$size}&chco={$color_from},{$color_to}&chf=bg,s,ffffff00&chl={$chl}\" width=\"{$sizes[0]}\" height=\"{$sizes[1]}\" alt=\"" . $chart_title . "\" title=\"" . $chart_title . "\" />"; } }
<div class="progress-bar" role="progressbar" aria-valuenow="<?php echo $progress * 100; ?> " aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $progress * 100; ?> %; min-width: 40px;" > <?php echo I18N::percentage($progress, 1); ?> </div> </div> <?php $first_time = $row->import_offset == 0; // Run for one second. This keeps the resource requirements low. for ($end_time = microtime(true) + 1.0; microtime(true) < $end_time;) { $data = Database::prepare("SELECT gedcom_chunk_id, REPLACE(chunk_data, '\r', '\n') AS chunk_data" . " FROM `##gedcom_chunk`" . " WHERE gedcom_id=? AND NOT imported" . " ORDER BY gedcom_chunk_id" . " LIMIT 1")->execute(array($gedcom_id))->fetchOneRow(); // If we are loading the first (header) record, make sure the encoding is UTF-8. if ($first_time) { // Remove any byte-order-mark Database::prepare("UPDATE `##gedcom_chunk`" . " SET chunk_data=TRIM(LEADING ? FROM chunk_data)" . " WHERE gedcom_chunk_id=?")->execute(array(WT_UTF8_BOM, $data->gedcom_chunk_id)); // Re-fetch the data, now that we have removed the BOM $data = Database::prepare("SELECT gedcom_chunk_id, REPLACE(chunk_data, '\r', '\n') AS chunk_data" . " FROM `##gedcom_chunk`" . " WHERE gedcom_chunk_id=?")->execute(array($data->gedcom_chunk_id))->fetchOneRow(); if (substr($data->chunk_data, 0, 6) != '0 HEAD') {
/** * {@inhericDoc} * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent() */ protected function renderContent() { if ($this->data->get('has_sosa', false)) { $table_id = $this->data->get('table_id'); ?> <div id="sosa-indi-list" class="sosa-list"> <table id="<?php echo $table_id; ?> "> <thead> <tr> <th colspan="22"> <div class="btn-toolbar"> <div class="btn-group"> <button class="ui-state-default" data-filter-column="18" data-filter-value="M" title="<?php echo I18N::translate('Show only males.'); ?> " type="button" ><?php echo Individual::sexImage('M', 'large'); ?> </button> <button class="ui-state-default" data-filter-column="18" data-filter-value="F" title="<?php echo I18N::translate('Show only females.'); ?> " type="button" > <?php echo Individual::sexImage('F', 'large'); ?> </button> <button class="ui-state-default" data-filter-column="18" data-filter-value="U" title="<?php echo I18N::translate('Show only individuals for whom the gender is not known.'); ?> " type="button" > <?php echo Individual::sexImage('U', 'large'); ?> </button> </div> <div class="btn-group"> <button class="ui-state-default" data-filter-column="20" data-filter-value="N" title="<?php echo I18N::translate('Show individuals who are alive or couples where both partners are alive.'); ?> " type="button" > <?php echo I18N::translate('Alive'); ?> </button> <button class="ui-state-default" data-filter-column="20" data-filter-value="Y" title="<?php echo I18N::translate('Show individuals who are dead or couples where both partners are deceased.'); ?> " type="button" > <?php echo I18N::translate('Dead'); ?> </button> <button class="ui-state-default" data-filter-column="20" data-filter-value="YES" title="<?php echo I18N::translate('Show individuals who died more than 100 years ago.'); ?> " type="button" ><?php echo GedcomTag::getLabel('DEAT'); ?> >100 </button> <button class="ui-state-default" data-filter-column="20" data-filter-value="Y100" title="<?php echo I18N::translate('Show individuals who died within the last 100 years.'); ?> " type="button" ><?php echo GedcomTag::getLabel('DEAT'); ?> <=100 </button> </div> <div class="btn-group"> <button class="ui-state-default" data-filter-column="19" data-filter-value="YES" title="<?php echo I18N::translate('Show individuals born more than 100 years ago.'); ?> " type="button" ><?php echo GedcomTag::getLabel('BIRT'); ?> >100 </button> <button class="ui-state-default" data-filter-column="19" data-filter-value="Y100" title="<?php echo I18N::translate('Show individuals born within the last 100 years.'); ?> " type="button" ><?php echo GedcomTag::getLabel('BIRT'); ?> <=100 </button> </div> <div class="btn-group"> <button class="ui-state-default" data-filter-column="21" data-filter-value="R" title="<?php echo I18N::translate('Show “roots” couples or individuals. These individuals may also be called “patriarchs”. They are individuals who have no parents recorded in the database.'); ?> " type="button" > <?php echo I18N::translate('Roots'); ?> </button> <button class="ui-state-default" data-filter-column="21" data-filter-value="L" title="<?php echo I18N::translate('Show “leaves” couples or individuals. These are individuals who are alive but have no children recorded in the database.'); ?> " type="button" > <?php echo I18N::translate('Leaves'); ?> </button> </div> </div> </th> </tr> <tr> <th><?php echo I18N::translate('Sosa'); ?> </th> <th><?php echo GedcomTag::getLabel('INDI'); ?> </th> <th><?php echo GedcomTag::getLabel('GIVN'); ?> </th> <th><?php echo GedcomTag::getLabel('SURN'); ?> </th> <th>GIVN</th> <th>SURN</th> <th><?php echo GedcomTag::getLabel('BIRT'); ?> </th> <th>SORT_BIRT</th> <th><?php echo GedcomTag::getLabel('PLAC'); ?> </th> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { ?> <th><i class="icon-source" title="<?php echo I18N::translate('Sourced birth'); ?> " border="0"></i></th> <th>SORT_BIRTSC</th> <?php } else { ?> <th></th> <th></th> <?php } ?> <th><?php echo GedcomTag::getLabel('DEAT'); ?> </th> <th>SORT_DEAT</th> <th><?php echo GedcomTag::getLabel('AGE'); ?> </th> <th>AGE</th> <th><?php echo GedcomTag::getLabel('PLAC'); ?> </th> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { ?> <th><i class="icon-source" title="<?php echo I18N::translate('Sourced death'); ?> " border="0"></i></th> <th>SORT_DEATSC</th> <?php } else { ?> <th></th> <th></th> <?php } ?> <th>SEX</th> <th>BIRT</th> <th>DEAT</th> <th>TREE</th> </tr> </thead> <tbody> <?php foreach ($this->data->get('sosa_list') as $sosa => $person) { /** @var \Fisharebest\Webtrees\Individual $person */ if ($person->isPendingAddtion()) { $class = ' class="new"'; } elseif ($person->isPendingDeletion()) { $class = ' class="old"'; } else { $class = ''; } $dperson = new \MyArtJaub\Webtrees\Individual($person); ?> <tr <?php echo $class; ?> > <td class="transparent"><?php echo $sosa; ?> </td> <td class="transparent"><?php echo $person->getXref(); ?> </td> <td colspan="2"> <?php foreach ($person->getAllNames() as $num => $name) { if ($name['type'] == 'NAME') { $title = ''; } else { $title = 'title="' . strip_tags(GedcomTag::getLabel($name['type'], $person)) . '"'; } if ($num == $person->getPrimaryName()) { $class = ' class="name2"'; $sex_image = $person->getSexImage(); list($surn, $givn) = explode(',', $name['sort']); } else { $class = ''; $sex_image = ''; } ?> <a <?php echo $title . ' ' . $class; ?> href="<?php echo $person->getHtmlUrl(); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($name['full']); ?> </a> <?php echo $sex_image . FunctionsPrint::formatSosaNumbers($dperson->getSosaNumbers(), 1, 'smaller'); ?> <br/> <?php } echo $person->getPrimaryParentsNames('parents details1', 'none'); ?> </td> <td style="display:none;"></td> <td> <?php echo Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)); ?> </td> <td> <?php echo Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)); ?> </td> <td> <?php if ($birth_dates = $person->getAllBirthDates()) { foreach ($birth_dates as $num => $birth_date) { if ($num) { ?> <br/><?php } ?> <?php echo $birth_date->display(true); } } else { $birth_date = new Date(''); if ($person->getTree()->getPreference('SHOW_EST_LIST_DATES')) { $birth_date = $person->getEstimatedBirthDate(); echo $birth_date->display(true); } else { echo ' '; } $birth_dates[0] = new Date(''); } ?> </td> <td><?php echo $birth_date->julianDay(); ?> </td> <td> <?php foreach ($person->getAllBirthPlaces() as $n => $birth_place) { $tmp = new \Fisharebest\Webtrees\Place($birth_place, $person->getTree()); if ($n) { ?> <br><?php } ?> <a href="'<?php echo $tmp->getURL(); ?> " title="<?php echo strip_tags($tmp->getFullName()); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($tmp->getShortName()); ?> </a> <?php } ?> </td> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { $isBSourced = $dperson->isBirthSourced(); ?> <td><?php echo FunctionsPrint::formatIsSourcedIcon('E', $isBSourced, 'BIRT', 1, 'medium'); ?> </td> <td><?php echo $isBSourced; ?> </td> <?php } else { ?> <td> </td> <td></td> <?php } ?> <td> <?php if ($death_dates = $person->getAllDeathDates()) { foreach ($death_dates as $num => $death_date) { if ($num) { ?> <br/><?php } ?> <?php echo $death_date->display(true); } } else { $death_date = $person->getEstimatedDeathDate(); if ($person->getTree()->getPreference('SHOW_EST_LIST_DATES') && $death_date->minimumJulianDay() < WT_CLIENT_JD) { echo $death_date->display(true); } elseif ($person->isDead()) { echo I18N::translate('yes'); $death_date = new Date(''); } else { echo ' '; $death_date = new Date(''); } $death_dates[0] = new Date(''); } ?> </td> <td><?php echo $death_date->julianDay(); ?> </td> <td><?php echo Date::getAge($birth_dates[0], $death_dates[0], 2); ?> </td> <td><?php echo Date::getAge($birth_dates[0], $death_dates[0], 1); ?> </td> <td> <?php foreach ($person->getAllDeathPlaces() as $n => $death_place) { $tmp = new Place($death_place, $person->getTree()); if ($n) { ?> <br><?php } ?> <a href="'<?php echo $tmp->getURL(); ?> " title="<?php echo strip_tags($tmp->getFullName()); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($tmp->getShortName()); ?> </a> <?php } ?> </td> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { $isDSourced = $dperson->isDeathSourced(); ?> <td><?php echo FunctionsPrint::formatIsSourcedIcon('E', $isDSourced, 'DEAT', 1, 'medium'); ?> </td> <td><?php echo $isDSourced; ?> </td> <?php } else { ?> <td> </td> <td></td> <?php } ?> <td><?php echo $person->getSex(); ?> </td> <td> <?php if (!$person->canShow() || Date::compare($birth_date, new Date(date('Y') - 100)) > 0) { echo 'Y100'; } else { echo 'YES'; } ?> </td> <td> <?php if (Date::compare($death_dates[0], new Date(date('Y') - 100)) > 0) { echo 'Y100'; } elseif ($death_dates[0]->minimumJulianDay() || $person->isDead()) { echo 'YES'; } else { echo 'N'; } ?> </td> <td> <?php if (!$person->getChildFamilies()) { echo 'R'; } elseif (!$person->isDead() && $person->getNumberOfChildren() < 1) { echo 'L'; } else { echo ' '; } ?> </td> </tr> <?php } ?> </tbody> <tfoot> <tr> <th class="ui-state-default" colspan="22"> <div class="center"> <?php echo I18N::translate('Number of Sosa ancestors: %1$s known / %2$s theoretical (%3$s)', I18N::number($this->data->get('sosa_count')), I18N::number($this->data->get('sosa_theo')), I18N::percentage($this->data->get('sosa_ratio'), 2)); ?> <?php if ($this->data->get('sosa_hidden') > 0) { echo '[' . I18N::translate('%s hidden', I18N::number($this->data->get('sosa_hidden'))) . ']'; } ?> </div> </th> </tr> <tr> <th colspan="22"> <div class="btn-toolbar"> <div class="btn-group"> <button type="button" class="ui-state-default btn-toggle-parents"> <?php echo I18N::translate('Show parents'); ?> </button> <button id="btn-toggle-statistics-<?php echo $table_id; ?> " type="button" class="ui-state-default btn-toggle-statistics"> <?php echo I18N::translate('Show statistics charts'); ?> </button> </div> </div> </th> </tr> </tfoot> </table> <div id="indi_list_table-charts_<?php echo $table_id; ?> " style="display:none"> <table class="list-charts"> <tr> <td><?php echo $this->data->get('chart_births'); ?> </td> <td><?php echo $this->data->get('chart_deaths'); ?> </td> </tr> <tr> <td colspan="2"><?php echo $this->data->get('chart_ages'); ?> </td> </tr> </table> </div> </div> <?php } }
/** * Returns HTML code for a graph showing the dispersion of ancestors across grand-parents * @return string HTML code */ private function htmlAncestorDispersionG3() { $ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(3); $size = '700x300'; $color_motmot = 'ffd1dc'; $color_motfat = 'b998a0'; $color_fatfat = '577292'; $color_fatmot = '84beff'; $color_shared = '777777'; $total_fatfat = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0; $total_fatmot = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0; $total_motfat = array_key_exists(4, $ancestorsDispGen2) ? $ancestorsDispGen2[4] : 0; $total_motmot = array_key_exists(8, $ancestorsDispGen2) ? $ancestorsDispGen2[8] : 0; $total_sha = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0; $total = $total_fatfat + $total_fatmot + $total_motfat + $total_motmot + $total_sha; $chd = $this->arrayToExtendedEncoding(array(4095 * Functions::safeDivision($total_fatfat, $total), 4095 * Functions::safeDivision($total_fatmot, $total), 4095 * Functions::safeDivision($total_sha, $total), 4095 * Functions::safeDivision($total_motfat, $total), 4095 * Functions::safeDivision($total_motmot, $total))); $chart_title = I18N::translate('Known Sosa ancestors\' dispersion - G3'); $chl = \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatfat, $total), 1) . '|' . \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatmot, $total), 1) . '|' . I18N::translate('Shared') . ' - ' . I18N::percentage(Functions::safeDivision($total_sha, $total), 1) . '|' . \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_motfat, $total), 1) . '|' . \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_motmot, $total), 1); return "<img src=\"https://chart.googleapis.com/chart?cht=p&chp=1.5708&chd=e:{$chd}&chs={$size}&chco={$color_fatfat},{$color_fatmot},{$color_shared},{$color_motfat},{$color_motmot}&chf=bg,s,ffffff00&chl={$chl}\" alt=\"" . $chart_title . "\" title=\"" . $chart_title . "\" />"; }
/** * Print a chart by decade using Google chart API * * @param integer[] $data * @param string $title * * @return string */ public static function chartByDecade($data, $title) { $count = 0; $vmax = 0; foreach ($data as $v) { $n = strlen($v); $vmax = max($vmax, $n); $count += $n; } if ($count < 1) { return ''; } $chart_url = "https://chart.googleapis.com/chart?cht=bvs"; // chart type $chart_url .= "&chs=360x150"; // size $chart_url .= "&chbh=3,3"; // bvg : 4,1,2 $chart_url .= "&chf=bg,s,FFFFFF99"; //background color $chart_url .= "&chco=0000FF,FFA0CB"; // bar color $chart_url .= "&chtt=" . rawurlencode($title); // title $chart_url .= "&chxt=x,y,r"; // axis labels specification $chart_url .= "&chxl=0:|<|||"; // <1570 for ($y = 1600; $y < 2030; $y += 50) { $chart_url .= $y . "|||||"; // x axis } $chart_url .= "|1:||" . rawurlencode(I18N::percentage($vmax / $count)); // y axis $chart_url .= "|2:||"; $step = $vmax; for ($d = $vmax; $d > 0; $d--) { if ($vmax < $d * 10 + 1 && $vmax % $d == 0) { $step = $d; } } if ($step == $vmax) { for ($d = $vmax - 1; $d > 0; $d--) { if ($vmax - 1 < $d * 10 + 1 && ($vmax - 1) % $d == 0) { $step = $d; } } } for ($n = $step; $n < $vmax; $n += $step) { $chart_url .= $n . "|"; } $chart_url .= rawurlencode($vmax . " / " . $count); // r axis $chart_url .= "&chg=100," . round(100 * $step / $vmax, 1) . ",1,5"; // grid $chart_url .= "&chd=s:"; // data : simple encoding from A=0 to 9=61 $CHART_ENCODING61 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for ($y = 1570; $y < 2030; $y += 10) { $chart_url .= $CHART_ENCODING61[(int) (substr_count($data[$y], "M") * 61 / $vmax)]; } $chart_url .= ","; for ($y = 1570; $y < 2030; $y += 10) { $chart_url .= $CHART_ENCODING61[(int) (substr_count($data[$y], "F") * 61 / $vmax)]; } $html = '<img src="' . $chart_url . '" alt="' . $title . '" title="' . $title . '" class="gchart">'; return $html; }
/** * {@inhericDoc} * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent() */ protected function renderContent() { ?> <div id="maj-sosa-stats-page"> <h2><?php echo $this->data->get('title'); ?> </h2> <?php /** @var \Fisharebest\Webtrees\Individual $root_indi */ $root_indi = $this->data->get('root_indi'); if ($root_indi !== null && $root_indi->canShowName()) { ?> <h4 class="center"><?php echo I18N::translate('%s: %s', I18N::translate('Root individual'), $root_indi->getFullName()); ?> <h4> <?php } ?> <?php if ($this->data->get('is_setup')) { $general_stats = $this->data->get('general_stats'); ?> <h3><?php echo I18N::translate('General statistics'); ?> </h3> <div class="maj-table"> <div class="maj-row"> <div class="label"><?php echo I18N::translate('Number of ancestors'); ?> </div> <div class="value"><?php echo I18N::number($general_stats['sosa_count']); ?> </div> </div> <div class="maj-row"> <div class="label"><?php echo I18N::translate('Number of different ancestors'); ?> </div> <div class="value"><?php echo I18N::number($general_stats['distinct_count']); ?> </div> </div> <div class="maj-row"> <div class="label"><?php echo I18N::translate('%% of ancestors in the base'); ?> </div> <div class="value"><?php echo I18N::percentage($general_stats['sosa_rate'], 1); ?> </div> </div> <div class="maj-row"> <div class="label"><?php echo I18N::translate('Pedigree collapse'); ?> </div> <div class="value"><?php echo I18N::percentage($general_stats['pedi_collapse'], 2); ?> </div> </div> <div class="maj-row"> <div class="label"><?php echo I18N::translate('Mean generation time'); ?> </div> <div class="value"><?php echo I18N::plural('%s year', '%s years', $general_stats['mean_gen_time'], I18N::number($general_stats['mean_gen_time'], 1)); ?> </div> </div> </div> <h3><?php echo I18N::translate('Statistics by generations'); ?> </h3> <table class="maj-table"> <thead> <tr class="maj-row"> <th class="label" colspan="2" > </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Theoretical number of ancestors in generation G.'); ?> "> <?php echo I18N::translate('Theoretical'); ?> </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Number of ancestors found in generation G. A same individual can be counted several times.'); ?> "> <?php echo I18N::translate('Known'); ?> </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Ratio of found ancestors in generation G compared to the theoretical number.'); ?> "> <?php echo I18N::translate('%'); ?> </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Number of ancestors not found in generation G, but whose children are known in generation G-1.'); ?> "> <?php echo I18N::translate('Losses G-1'); ?> </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Ratio of not found ancestors in generation G amongst the theoretical ancestors in this generation whose children are known in generation G-1. This is an indicator of the completion of a generation relative to the completion of the previous generation.'); ?> "> <?php echo I18N::translate('%'); ?> </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Cumulative number of ancestors found up to generation G. A same individual can be counted several times.'); ?> "> <?php echo I18N::translate('Total known'); ?> </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Ratio of cumulative found ancestors in generation G compared to the cumulative theoretical number.'); ?> "> <?php echo I18N::translate('%'); ?> </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Number of distinct ancestors found in generation G. A same individual is counted only once.'); ?> "> <?php echo I18N::translate('Different'); ?> </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Ratio of distinct individuals compared to the number of ancestors found in generation G.'); ?> "> <?php echo I18N::translate('%'); ?> </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Number of cumulative distinct ancestors found up to generation G. A same individual is counted only once in the total number, even if present in different generations.'); ?> "> <?php echo I18N::translate('Total Different'); ?> </th> <th class="label help_tooltip" title="<?php echo I18N::translate('Pedigree collapse at generation G. Pedigree collapse is a measure of the real number of ancestors of a person compared to its theorical number. The higher this number is, the more marriages between related persons have happened. Extreme examples of high pedigree collapse are royal families for which this number can be as high as nearly 90%% (Alfonso XII of Spain).'); ?> "> <?php echo I18N::translate('Pedigree collapse'); ?> </th> </tr> </thead> <tbody> <?php foreach ($this->data->get('generation_stats') as $gen => $row) { ?> <tr class="maj-row"> <td class="label"><?php echo I18N::translate('<strong>G%d</strong>', $gen); ?> </td> <td class="label"><?php echo I18N::translate('%1$s <> %2$s', $row['gen_min_birth'], $row['gen_max_birth']); ?> </td> <td class="value"><?php echo I18N::number($row['theoretical']); ?> </td> <td class="value"><?php echo $row['known'] > 0 ? '<a href="' . $this->data->get('sosaanc_url') . $gen . '">' . I18N::number($row['known']) . '</a>' : I18N::number($row['known']); ?> </td> <td class="value"><?php echo I18N::percentage($row['perc_known'], 2); ?> </td> <td class="value"><?php echo $row['missing'] > 0 ? '<a href="' . $this->data->get('missinganc_url') . $gen . '">' . I18N::number($row['missing']) . '</a>' : I18N::number($row['missing']); ?> </td> <td class="value"><?php echo I18N::percentage($row['perc_missing'], 2); ?> </td> <td class="value"><?php echo I18N::number($row['total_known']); ?> </td> <td class="value"><?php echo I18N::percentage($row['perc_total_known'], 2); ?> </td> <td class="value"><?php echo I18N::number($row['different']); ?> </td> <td class="value left percent_container"> <div class="percent_frame"> <div class="percent_cell" style="width:<?php echo 100 * $row['perc_different']; ?> %;"> <?php echo I18N::percentage($row['perc_different']); ?> </div> </div> </td> <td class="value"><?php echo I18N::number($row['total_different']); ?> </td> <td class="value"><?php echo I18N::percentage($row['pedi_collapse'], 2); ?> </td> </tr> <?php } ?> </tbody> <tfoot> <tr class="maj-row"> <td class="label" colspan="13"> <?php echo I18N::translate('Generation-equivalent: %s generations', I18N::number($this->data->get('equivalent_gen'), 2)); ?> </td> </tr> </tfoot> </table> <div class="center"><em><?php echo I18N::translate('Hover the column headers to display some help on their meaning.'); ?> </em></div> <h3><?php echo I18N::translate('Known Sosa ancestors\' family dispersion'); ?> </h3> <div class="center"> <?php echo $this->data->get('chart_img_g2') ?: ''; ?> <?php echo $this->data->get('chart_img_g3') ?: ''; ?> <!-- <canvas id="chart_ancestors_g2" width="300" height="300"></canvas> --> </div> <?php } else { ?> <div class="center warning"><?php echo I18N::translate('No Sosa root individual has been defined.'); ?> </div> <?php } }
/** * {@inheritDoc} * @see \MyArtJaub\Webtrees\Module\GeoDispersion\Views\AbstractGeoAnalysisTabGeneralView::htmlAnalysisData() */ protected function htmlAnalysisData() { /** @var OutlineMap $map */ $map = $this->data->get('map'); $canvas = $map->getCanvas(); $subdvisions_results = $this->data->get('results_by_subdivisions'); $nb_found = $this->data->get('stats_gen_nb_found'); $nb_other = $this->data->get('stats_gen_nb_other'); $html = '<script> var tip = null; var tipText = ""; var over = false; var isin = false; function addTip(node, txt){ jQuery(node).bind({ mouseover : function(){ oldisin = isin; isin = true; if(oldisin != isin){ tipText = txt; tip.stop(true, true).fadeIn(); over = true; } }, mouseout : function(){ oldisin = isin; isin = false; if(oldisin != isin){ tip.stop(true, true).fadeOut("fast"); over = false; } } }); } jQuery(document).ready(function() { tip = $("#geodispersion_tip").hide(); var positionTab = jQuery("#geodispersion-tabs").offset(); jQuery("#geodispersion_map").mousemove(function(e){ if (over){ tip.css("left", e.pageX + 20 - positionTab.left).css("top", e.pageY + 20 - positionTab.top); tip.html(tipText); } }); var paper = new Raphael(document.getElementById("geodispersion_map"), ' . $canvas->width . ', ' . $canvas->height . '); var background = paper.rect(0, 0, ' . $canvas->width . ', ' . $canvas->height . '); background.attr({"fill" : "' . $canvas->background_color . '", "stroke" : "' . $canvas->background_stroke . '", "stroke-width": 1, "stroke-linejoin": "round" }); var attr = { fill: "' . $canvas->default_color . '", stroke: "' . $canvas->default_stroke . '", "stroke-width": 1, "stroke-linejoin": "round" }; var map = {}; '; foreach ($subdvisions_results as $name => $location) { $html .= 'map.area' . $location['id'] . ' = paper.path("' . $location['coord'] . '").attr(attr);'; if (isset($location['transparency'])) { $textToolTip = '<strong>' . $location['displayname'] . '</strong><br/>'; if ($this->data->get('use_flags') && $location['flag'] != '') { $textToolTip .= '<span class="geodispersion_flag">' . FunctionsPrint::htmlPlaceIcon($location['place'], $location['flag']) . '</span><br/>'; } $textToolTip .= I18N::translate('%d individuals', $location['count']) . '<br/>' . I18N::percentage(Functions::safeDivision($location['count'], $nb_found - $nb_other), 1); $html .= 'addTip(map.area' . $location['id'] . '.node, "' . Filter::escapeJs($textToolTip) . '");'; $html .= 'map.area' . $location['id'] . '.attr({"fill" : "' . $canvas->max_color . '", "fill-opacity" : ' . $location['transparency'] . ' });'; $html .= 'map.area' . $location['id'] . '.mouseover(function () {' . 'map.area' . $location['id'] . '.stop().animate({"fill" : "' . $canvas->hover_color . '", "fill-opacity" : 1}, 100, "linear");' . '});' . 'map.area' . $location['id'] . '.mouseout(function () {' . 'map.area' . $location['id'] . '.stop().animate({"fill" : "' . $canvas->max_color . '", "fill-opacity" : ' . $location['transparency'] . '}, 100, "linear");' . '});'; } } $html .= '}); </script> <div id="geodispersion_map"></div> <div id="geodispersion_tip"></div>'; return $html; }
/** * Returns the HTML code fo display a row of the Top Places found for a generation. * * @param array $data Data array * @param int $analysis_level Level of subdivision of analysis * @return string HTML code for Top Places row */ protected function htmlGenerationTopPlacesRow($data, $analysis_level) { $tmp_places = array(); $sum_gen = $data['sum']; $other = $data['other']; foreach ($data['places'] as $placename => $count) { if ($placename != 'other') { $levels = array_map('trim', explode(',', $placename)); $placename = '<span title="' . implode(I18N::$list_separator, array_reverse($levels)) . '">' . $levels[$analysis_level - 1] . '</span>'; } else { $placename = I18N::translate('Other places'); } $tmp_places[] = I18N::translate('<strong>%s</strong> [%d - %s]', $placename, $count, I18N::percentage(Functions::safeDivision($count, $sum_gen + $other), 1)); } return implode(I18N::$list_separator, $tmp_places); }
/** * {@inhericDoc} * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent() */ protected function renderContent() { ?> <div id="maj-sosa-missing-page" class="center"> <h2><?php echo $this->data->get('title'); ?> </h2> <?php if ($this->data->get('is_setup')) { $this->renderSosaHeader(); if ($this->data->get('has_missing', false)) { $table_id = $this->data->get('table_id'); ?> <div id="sosa-indi-missing" class="smissing-list"> <table id="<?php echo $table_id; ?> "> <thead> <tr> <th colspan="16"> <div class="btn-toolbar"> <div class="btn-group"> <button class="ui-state-default" data-filter-column="15" data-filter-value="M" title="<?php I18N::translate('Show only males.'); ?> " type="button" > <?php echo Individual::sexImage('M', 'large'); ?> </button> <button class="ui-state-default" data-filter-column="15" data-filter-value="F" title="<?php I18N::translate('Show only females.'); ?> " type="button" > <?php echo Individual::sexImage('F', 'large'); ?> </button> <button class="ui-state-default" data-filter-column="15" data-filter-value="U" title="<?php I18N::translate('Show only individuals for whom the gender is not known.'); ?> " type="button" > <?php echo Individual::sexImage('U', 'large'); ?> </button> </div> </div> </th> </tr> <tr> <th><?php echo I18N::translate('Sosa'); ?> </th> <th><?php echo GedcomTag::getLabel('INDI'); ?> </th> <th><?php echo GedcomTag::getLabel('GIVN'); ?> </th> <th><?php echo GedcomTag::getLabel('SURN'); ?> </th> <th>GIVN</th> <th>SURN</th> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { ?> <th><i class="icon-source" title="<?php echo I18N::translate('Sourced individual'); ?> " border="0"></i></th> <th>SORT_BIRTSC</th> <?php } else { ?> <th></th> <th></th> <?php } ?> <th><?php echo Functions::getRelationshipNameFromPath('fat'); ?> </th> <th><?php echo Functions::getRelationshipNameFromPath('mot'); ?> </th> <th><?php echo GedcomTag::getLabel('BIRT'); ?> </th> <th>SORT_BIRT</th> <th><?php echo GedcomTag::getLabel('PLAC'); ?> </th> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { ?> <th><i class="icon-source" title="<?php echo I18N::translate('Sourced birth'); ?> " border="0"></i></th> <th>SORT_BIRTSC</th> <?php } else { ?> <th></th> <th></th> <?php } ?> <th>SEX</th> </tr> </thead> <tbody> <?php foreach ($this->data->get('missing_list') as $missing_tab) { $person = $missing_tab['indi']; /** @var \Fisharebest\Webtrees\Individual $person */ if ($person->isPendingAddtion()) { $class = ' class="new"'; } elseif ($person->isPendingDeletion()) { $class = ' class="old"'; } else { $class = ''; } $dperson = new \MyArtJaub\Webtrees\Individual($person); ?> <tr <?php echo $class; ?> > <td class="transparent"><?php echo $missing_tab['sosa']; ?> </td> <td class="transparent"><?php echo $person->getXref(); ?> </td> <td colspan="2"> <?php foreach ($person->getAllNames() as $num => $name) { if ($name['type'] == 'NAME') { $title = ''; } else { $title = 'title="' . strip_tags(GedcomTag::getLabel($name['type'], $person)) . '"'; } if ($num == $person->getPrimaryName()) { $class = ' class="name2"'; $sex_image = $person->getSexImage(); list($surn, $givn) = explode(',', $name['sort']); } else { $class = ''; $sex_image = ''; } ?> <a <?php echo $title . ' ' . $class; ?> href="<?php echo $person->getHtmlUrl(); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($name['full']); ?> </a> <?php echo $sex_image . FunctionsPrint::formatSosaNumbers($dperson->getSosaNumbers(), 1, 'smaller'); ?> <br/> <?php } echo $person->getPrimaryParentsNames('parents details1', 'none'); ?> </td> <td style="display:none;"></td> <td> <?php echo Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)); ?> </td> <td> <?php echo Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)); ?> </td> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { $isISourced = $dperson->isSourced(); ?> <td><?php echo FunctionsPrint::formatIsSourcedIcon('R', $isISourced, 'INDI', 1, 'medium'); ?> </td> <td><?php echo $isISourced; ?> </td> <?php } else { ?> <td> </td> <td></td> <?php } ?> <td><?php echo $missing_tab['has_father'] ? ' ' : 'X'; ?> </td> <td><?php echo $missing_tab['has_mother'] ? ' ' : 'X'; ?> </td> <td> <?php if ($birth_dates = $person->getAllBirthDates()) { foreach ($birth_dates as $num => $birth_date) { if ($num) { ?> <br/><?php } ?> <?php echo $birth_date->display(true); } } else { $birth_date = new Date(''); if ($person->getTree()->getPreference('SHOW_EST_LIST_DATES')) { $birth_date = $person->getEstimatedBirthDate(); echo $birth_date->display(true); } else { echo ' '; } $birth_dates[0] = new Date(''); } ?> </td> <td><?php echo $birth_date->julianDay(); ?> </td> <td> <?php foreach ($person->getAllBirthPlaces() as $n => $birth_place) { $tmp = new \Fisharebest\Webtrees\Place($birth_place, $person->getTree()); if ($n) { ?> <br><?php } ?> <a href="'<?php echo $tmp->getURL(); ?> " title="<?php echo strip_tags($tmp->getFullName()); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($tmp->getShortName()); ?> </a> <?php } ?> </td> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { $isBSourced = $dperson->isBirthSourced(); ?> <td><?php echo FunctionsPrint::formatIsSourcedIcon('E', $isBSourced, 'BIRT', 1, 'medium'); ?> </td> <td><?php echo $isBSourced; ?> </td> <?php } else { ?> <td> </td> <td></td> <?php } ?> <td><?php echo $person->getSex(); ?> </td> </tr> <?php } ?> </tbody> <tfoot> <tr> <td class="ui-state-default" colspan="16"> <div class="center"> <?php echo I18N::translate('Number of different missing ancestors: %s', I18N::number($this->data->get('missing_diff_count'))); ?> <?php if ($this->data->get('missing_hidden') > 0) { echo ' [' . I18N::translate('%s hidden', I18N::number($this->data->get('missing_hidden'))) . ']'; } ?> <?php echo ' - ' . I18N::translate('Generation complete at %s', I18N::percentage($this->data->get('perc_sosa'), 2)); ?> <?php echo ' [' . I18N::translate('Potential %s', I18N::percentage($this->data->get('perc_sosa_potential'), 2)) . ']'; ?> </div> </td> </tr> </tfoot> </table> <?php } else { if ($this->data->get('generation', 0) > 0) { ?> <p><?php echo I18N::translate('No ancestors are missing for this generation. Generation complete at %s.', I18N::percentage($this->data->get('perc_sosa'), 2)); ?> </p> <?php } } } else { ?> <p class="warning"><?php echo I18N::translate('The list could not be displayed. Reasons might be:'); ?> <br/> <ul> <li><?php echo I18N::translate('No Sosa root individual has been defined.'); ?> </li> <li><?php echo I18N::translate('The Sosa ancestors have not been computed yet.'); ?> </li> <li><?php echo I18N::translate('No generation were found.'); ?> </li> </ul> </p> <?php } ?> </div> <?php }