addExternalJavaScript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js') ->addInlineJavaScript(' jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc" ]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["num-html-asc" ]=function(a,b) {a=parseFloat(a.replace(/<[^<]*>/, "")); b=parseFloat(b.replace(/<[^<]*>/, "")); return (ab ? 1 : 0);}; jQuery.fn.dataTableExt.oSort["num-html-desc"]=function(a,b) {a=parseFloat(a.replace(/<[^<]*>/, "")); b=parseFloat(b.replace(/<[^<]*>/, "")); return (a>b) ? -1 : (a<"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_'.$table_id.'">>\', '.WT_I18N::datatablesI18N().', "bJQueryUI": true, "bAutoWidth":false, "bProcessing": true, "bRetrieve": true, "aoColumns": [ /* 0 givn */ {"iDataSort": 2}, /* 1 surn */ {"iDataSort": 3}, /* 2 GIVN,SURN */ {"sType": "unicode", "bVisible": false}, /* 3 SURN,GIVN */ {"sType": "unicode", "bVisible": false}, /* 4 sosa */ {"iDataSort": 5, "sClass": "center", "bVisible": '.($option=='sosa'?'true':'false').'}, /* 5 SOSA */ {"sType": "numeric", "bVisible": false}, /* 6 birt date */ {"iDataSort": 7}, /* 7 BIRT:DATE */ {"bVisible": false}, /* 8 anniv */ {"bSortable": false, "sClass": "center"}, /* 9 birt plac */ {"sType": "unicode"}, /* 10 children */ {"iDataSort": 11, "sClass": "center"}, /* 11 children */ {"sType": "numeric", "bVisible": false}, /* 12 deat date */ {"iDataSort": 13}, /* 13 DEAT:DATE */ {"bVisible": false}, /* 14 anniv */ {"bSortable": false, "sClass": "center"}, /* 15 age */ {"iDataSort": 16, "sClass": "center"}, /* 16 AGE */ {"sType": "numeric", "bVisible": false}, /* 17 deat plac */ {"sType": "unicode"}, /* 18 CHAN */ {"bVisible": '.($SHOW_LAST_CHANGE?'true':'false').'}, /* 19 SEX */ {"bVisible": false}, /* 20 BIRT */ {"bVisible": false}, /* 21 DEAT */ {"bVisible": false}, /* 22 TREE */ {"bVisible": false} ], "aaSorting": [[1, "asc"]], "iDisplayLength": 20, "sPaginationType": "full_numbers" }); jQuery("div.filtersH_'.$table_id.'").html("'.addslashes( ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. '' ).'"); jQuery("div.filtersF_'.$table_id.'").html("'.addslashes( ''. '' ).'"); /* Add event listeners for filtering inputs */ jQuery("#SEX_M_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("M", 19 ); jQuery("#SEX_M_'.$table_id.'").addClass("ui-state-active"); jQuery("#SEX_F_'.$table_id.'").removeClass("ui-state-active"); jQuery("#SEX_U_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#SEX_F_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("F", 19 ); jQuery("#SEX_M_'.$table_id.'").removeClass("ui-state-active"); jQuery("#SEX_F_'.$table_id.'").addClass("ui-state-active"); jQuery("#SEX_U_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#SEX_U_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("U", 19 ); jQuery("#SEX_M_'.$table_id.'").removeClass("ui-state-active"); jQuery("#SEX_F_'.$table_id.'").removeClass("ui-state-active"); jQuery("#SEX_U_'.$table_id.'").addClass("ui-state-active"); }); jQuery("#BIRT_YES_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("YES", 20 ); jQuery("#BIRT_YES_'.$table_id.'").addClass("ui-state-active"); jQuery("#BIRT_Y100_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#BIRT_Y100_'.$table_id.'").click( function() { oTable'.$table_id.'.fnFilter("Y100", 20 ); jQuery("#BIRT_YES_'.$table_id.'").removeClass("ui-state-active"); jQuery("#BIRT_Y100_'.$table_id.'").addClass("ui-state-active"); }); jQuery("#DEAT_N_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("N", 21 ); jQuery("#DEAT_N_'.$table_id.'").addClass("ui-state-active"); jQuery("#DEAT_Y_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_YES_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_Y100_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#DEAT_Y_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("^Y", 21, true, false ); jQuery("#DEAT_N_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_Y_'.$table_id.'").addClass("ui-state-active"); jQuery("#DEAT_YES_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_Y100_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#DEAT_YES_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("YES", 21 ); jQuery("#DEAT_N_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_Y_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_YES_'.$table_id.'").addClass("ui-state-active"); jQuery("#DEAT_Y100_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#DEAT_Y100_'.$table_id.'").click( function() { oTable'.$table_id.'.fnFilter("Y100", 21 ); jQuery("#DEAT_N_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_Y_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_YES_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_Y100_'.$table_id.'").addClass("ui-state-active"); }); jQuery("#TREE_R_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("R", 22 ); jQuery("#TREE_R_'.$table_id.'").addClass("ui-state-active"); jQuery("#TREE_L_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#TREE_L_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("L", 22 ); jQuery("#TREE_R_'.$table_id.'").removeClass("ui-state-active"); jQuery("#TREE_L_'.$table_id.'").addClass("ui-state-active"); }); jQuery("#RESET_'. $table_id.'").click( function() { for (i=19; i<=22; i++){ oTable'.$table_id.'.fnFilter("", i ); }; jQuery("div.filtersH_'.$table_id.' button").removeClass("ui-state-active"); }); /* This code is a temporary fix for Datatables bug http://www.datatables.net/forums/discussion/4730/datatables_sort_wrapper-being-added-to-columns-with-bsortable-false/p1*/ jQuery("th div span:eq(3)").css("display", "none"); jQuery("th div:eq(3)").css("margin", "auto").css("text-align", "center"); jQuery("th span:eq(8)").css("display", "none"); jQuery("th div:eq(8)").css("margin", "auto").css("text-align", "center"); jQuery(".indi-list").css("visibility", "visible"); jQuery(".loading-image").css("display", "none"); '); $stats = new WT_Stats($GEDCOM); // Bad data can cause "longest life" to be huge, blowing memory limits $max_age = min($MAX_ALIVE_AGE, $stats->LongestLifeAge())+1; //-- init chart data for ($age=0; $age<=$max_age; $age++) $deat_by_age[$age]=""; for ($year=1550; $year<2030; $year+=10) $birt_by_decade[$year]=""; for ($year=1550; $year<2030; $year+=10) $deat_by_decade[$year]=""; //--table wrapper $html .= '
 
'; $html .= '
'; //-- table header $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''. WT_Gedcom_Tag::getLabel('CHAN'). ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; //-- table body $html .= ''; $d100y=new WT_Date(date('Y')-100); // 100 years ago $dateY = date('Y'); $unique_indis=array(); // Don't double-count indis with multiple names. foreach ($datalist as $key=>$value) { if (is_object($value)) { // Array of objects $person=$value; } elseif (!is_array($value)) { // Array of IDs $person = WT_Person::getInstance($value); } else { // Array of search results $gid = $key; if (isset($value['gid'])) $gid = $value['gid']; // from indilist if (isset($value[4])) $gid = $value[4]; // from indilist ALL $person = WT_Person::getInstance($gid); } if (is_null($person)) continue; if ($person->getType() !== 'INDI') continue; if (!$person->canDisplayName()) { continue; } //-- place filtering if ($option=='BIRT_PLAC' && strstr($person->getBirthPlace(), $filter)===false) continue; if ($option=='DEAT_PLAC' && strstr($person->getDeathPlace(), $filter)===false) continue; $html .= ''; //-- Indi name(s) $html .= ''; // Dummy column to match colspan in header $html .= ''; //-- GIVN/SURN // Use "AAAA" as a separator (instead of ",") as JavaScript.localeCompare() ignores // punctuation and "ANN,ROACH" would sort after "ANNE,ROACH", instead of before it. // Similarly, @N.N. would sort as NN. $html .= ''; $html .= ''; //-- SOSA if ($option=='sosa') { $html .= ''; } else { $html .= ''; } //-- Birth date $html .= ''; //-- Event date (sortable)hidden by datatables code $html .= ''; //-- Birth anniversary $html .= ''; //-- Birth place $html .= ''; //-- Number of children $nchi=$person->getNumberOfChildren(); $html .= ''; //-- Death date $html .= ''; //-- Event date (sortable)hidden by datatables code $html .= ''; //-- Death anniversary $html .= ''; //-- Age at death if ($birth_dates[0]->isOK() && $death_dates[0]->isOK()) { $age=WT_Date::GetAgeYears($birth_dates[0], $death_dates[0]); if (!isset($unique_indis[$person->getXref()])) { $deat_by_age[max(0, min($max_age, $age))] .= $person->getSex(); } } else { $age=''; } // Need both display and sortable age $html .= ''; //-- Death place $html .= ''; //-- Last change if ($SHOW_LAST_CHANGE) { $html .= ''; } else { $html .= ''; } //-- Sorting by gender $html .= ''; //-- Filtering by birth date $html .= ''; //-- Filtering by death date $html .= ''; //-- Roots or Leaves ? $html .= ''; $html .= ''; $unique_indis[$person->getXref()]=true; } $html .= '
'. WT_Gedcom_Tag::getLabel('GIVN'). ''. WT_Gedcom_Tag::getLabel('SURN'). 'GIVNSURN'. /* I18N: Abbreviation for "Sosa-Stradonitz number". This is a person's surname, so may need transliterating into non-latin alphabets. */ WT_I18N::translate('Sosa'). 'SOSA'. WT_Gedcom_Tag::getLabel('BIRT'). 'SORT_BIRT'. WT_I18N::translate('Anniversary'). ''. WT_Gedcom_Tag::getLabel('PLAC'). ''. WT_I18N::translate('Children'). 'NCHI'. WT_Gedcom_Tag::getLabel('DEAT'). 'SORT_DEAT'. WT_I18N::translate('Anniversary'). ''. WT_Gedcom_Tag::getLabel('AGE'). 'AGE'. WT_Gedcom_Tag::getLabel('PLAC'). 'SEXBIRTDEATTREE
'; foreach ($person->getAllNames() as $num=>$name) { if ($name['type']=='NAME') { $title=''; } else { $title='title="'.strip_tags(WT_Gedcom_Tag::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=''; } $html .= ''. highlight_search_hits($name['full']). ''. $sex_image. '
'; } // Indi parents $html .= $person->getPrimaryParentsNames('parents_indi_list_table_'.$table_id.' details1', 'none'); $html .= '
'. htmlspecialchars(str_replace('@P.N.', 'AAAA', $givn)). 'AAAA'. htmlspecialchars(str_replace('@N.N.', 'AAAA', $surn)). ''. htmlspecialchars(str_replace('@N.N.', 'AAAA', $surn)). 'AAAA'. htmlspecialchars(str_replace('@P.N.', 'AAAA', $givn)). ''. WT_I18N::number($key). ''. $key. ' 0'; if ($birth_dates=$person->getAllBirthDates()) { foreach ($birth_dates as $num=>$birth_date) { if ($num) { $html .= '
'; } $html .= $birth_date->Display(!$SEARCH_SPIDER); } if ($birth_dates[0]->gregorianYear()>=1550 && $birth_dates[0]->gregorianYear()<2030 && !isset($unique_indis[$person->getXref()])) { $birt_by_decade[floor($birth_dates[0]->gregorianYear()/10)*10] .= $person->getSex(); } } else { $birth_date=$person->getEstimatedBirthDate(); $birth_jd=$birth_date->JD(); if ($SHOW_EST_LIST_DATES) { $html .= $birth_date->Display(!$SEARCH_SPIDER); } else { $html .= ' '; } $birth_dates[0]=new WT_Date(''); } $html .= '
'. $birth_date->JD(). ''; if ($birth_dates[0]->isOK()) { $html .= WT_I18N::number(WT_Date::GetAgeYears($birth_dates[0])); } else { $html .= ' '; } $html .= ''; foreach ($person->getAllBirthPlaces() as $n=>$birth_place) { if ($n) { $html .= '
'; } if ($SEARCH_SPIDER) { $html .= get_place_short($birth_place). ' '; } else { $html .= ''; $html .= highlight_search_hits(get_place_short($birth_place)). ''; } } $html .= '
'. WT_I18N::number($nchi). ''. $nchi. ''; if ($death_dates=$person->getAllDeathDates()) { foreach ($death_dates as $num=>$death_date) { if ($num) { $html .= '
'; } $html .= $death_date->Display(!$SEARCH_SPIDER); } if ($death_dates[0]->gregorianYear()>=1550 && $death_dates[0]->gregorianYear()<2030 && !isset($unique_indis[$person->getXref()])) { $deat_by_decade[floor($death_dates[0]->gregorianYear()/10)*10] .= $person->getSex(); } } else { $death_date=$person->getEstimatedDeathDate(); $death_jd=$death_date->JD(); if ($SHOW_EST_LIST_DATES) { $html .= $death_date->Display(!$SEARCH_SPIDER); } else if ($person->isDead()) { $html .= WT_I18N::translate('yes'); } else { $html .= ' '; } $death_dates[0]=new WT_Date(''); } $html .= '
'. $death_date->JD(). ''; if ($death_dates[0]->isOK()) { $html .= WT_I18N::number(WT_Date::GetAgeYears($death_dates[0])); } else { $html .= ' '; } $html .= ''. WT_I18N::number($age). ''. $age. ''; foreach ($person->getAllDeathPlaces() as $n=>$death_place) { if ($n) { $html .= '
'; } if ($SEARCH_SPIDER) { $html .= get_place_short($death_place). ' '; } else { $html .= ''; $html .= highlight_search_hits(get_place_short($death_place)). ''; } } $html .= '
'. $person->LastChangeTimestamp(empty($SEARCH_SPIDER)). ' '; $html .= $person->getSex(); $html .= ''; if (!$person->canDisplayDetails() || WT_Date::Compare($birth_dates[0], $d100y)>0) { $html .= 'Y100'; } else { $html .= 'YES'; } $html .= ''; if ($person->isDead()) { if (WT_Date::Compare($death_dates[0], $d100y)>0) { $html .= 'Y100'; } else { $html .= 'YES'; } } else { $html .= 'N'; } $html .= ''; if (!$person->getChildFamilies()) { $html .= 'R'; } // roots elseif (!$person->isDead() && $person->getNumberOfChildren()<1) { $html .= 'L'; } // leaves else { $html .= ' '; } $html .= '
'; //-- charts $html .= '
'; // Close "indi-list" return $html; } // print a table of families function format_fam_table($datalist, $option='') { global $GEDCOM, $SHOW_LAST_CHANGE, $WT_IMAGES, $SEARCH_SPIDER, $controller; $table_id = 'ID'.floor(microtime()*1000000); // lists requires a unique ID in case there are multiple lists per page if ($option=='BIRT_PLAC' || $option=='DEAT_PLAC') return; $html = ''; $controller ->addExternalJavaScript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js') ->addInlineJavaScript(' jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; var oTable'.$table_id.'=jQuery("#'.$table_id.'").dataTable( { "sDom": \'<"H"<"filtersH_'.$table_id.'"><"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_'.$table_id.'">>\', '.WT_I18N::datatablesI18N().', "bJQueryUI": true, "bAutoWidth":false, "bProcessing": true, "bRetrieve": true, "aoColumns": [ /* 0 husb givn */ {"iDataSort": 2}, /* 1 husb surn */ {"iDataSort": 3}, /* 2 GIVN,SURN */ {"sType": "unicode", "bVisible": false}, /* 3 SURN,GIVN */ {"sType": "unicode", "bVisible": false}, /* 4 age */ {"iDataSort": 5, "sClass": "center"}, /* 5 AGE */ {"sType": "numeric", "bVisible": false}, /* 6 wife givn */ {"iDataSort": 8}, /* 7 wife surn */ {"iDataSort": 9}, /* 8 GIVN,SURN */ {"sType": "unicode", "bVisible": false}, /* 9 SURN,GIVN */ {"sType": "unicode", "bVisible": false}, /* 10 age */ {"iDataSort": 11, "sClass": "center"}, /* 11 AGE */ {"sType": "numeric", "bVisible": false}, /* 12 marr date */ {"iDataSort": 11}, /* 13 MARR:DATE */ {"bVisible": false}, /* 14 anniv */ {"bSortable": false, "sClass": "center"}, /* 15 marr plac */ {"sType": "unicode"}, /* 16 children */ {"iDataSort": 17, "sClass": "center"}, /* 17 NCHI */ {"sType": "numeric", "bVisible": false}, /* 18 CHAN */ {"bVisible": '.($SHOW_LAST_CHANGE?'true':'false').'}, /* 19 MARR */ {"bVisible": false}, /* 20 DEAT */ {"bVisible": false}, /* 21 TREE */ {"bVisible": false} ], "aaSorting": [[1, "asc"]], "iDisplayLength": 20, "sPaginationType": "full_numbers" }); jQuery("div.filtersH_'.$table_id.'").html("'.addslashes( ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. '' ).'"); jQuery("div.filtersF_'.$table_id.'").html("'.addslashes( ''. '' ).'"); /* Add event listeners for filtering inputs */ jQuery("#MARR_U_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("U", 19); jQuery("#MARR_U_'.$table_id.'").addClass("ui-state-active"); jQuery("#MARR_YES_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_Y100_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_DIV_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MULTI_MARR_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#MARR_YES_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("YES", 19); jQuery("#MARR_U_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_YES_'.$table_id.'").addClass("ui-state-active"); jQuery("#MARR_Y100_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_DIV_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MULTI_MARR_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#MARR_Y100_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("Y100", 19); jQuery("#MARR_U_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_YES_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_Y100_'.$table_id.'").addClass("ui-state-active"); jQuery("#MARR_DIV_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MULTI_MARR_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#MARR_DIV_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("D", 19); jQuery("#MARR_U_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_YES_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_Y100_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_DIV_'.$table_id.'").addClass("ui-state-active"); jQuery("#MULTI_MARR_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#MULTI_MARR_'.$table_id.'").click( function() { oTable'.$table_id.'.fnFilter("M", 19); jQuery("#MARR_U_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_YES_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_Y100_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MARR_DIV_'.$table_id.'").removeClass("ui-state-active"); jQuery("#MULTI_MARR_'.$table_id.'").addClass("ui-state-active"); }); jQuery("#DEAT_N_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("N", 20); jQuery("#DEAT_N_'.$table_id.'").addClass("ui-state-active"); jQuery("#DEAT_W_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_H_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_Y_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#DEAT_W_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("W", 20); jQuery("#DEAT_N_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_W_'.$table_id.'").addClass("ui-state-active"); jQuery("#DEAT_H_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_Y_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#DEAT_H_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("H", 20); jQuery("#DEAT_N_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_W_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_H_'.$table_id.'").addClass("ui-state-active"); jQuery("#DEAT_Y_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#DEAT_Y_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("Y", 20); jQuery("#DEAT_N_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_W_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_H_'.$table_id.'").removeClass("ui-state-active"); jQuery("#DEAT_Y_'.$table_id.'").addClass("ui-state-active"); }); jQuery("#TREE_R_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("R", 21); jQuery("#TREE_R_'.$table_id.'").addClass("ui-state-active"); jQuery("#TREE_L_'.$table_id.'").removeClass("ui-state-active"); }); jQuery("#TREE_L_'. $table_id.'").click( function() { oTable'.$table_id.'.fnFilter("L", 21); jQuery("#TREE_R_'.$table_id.'").removeClass("ui-state-active"); jQuery("#TREE_L_'.$table_id.'").addClass("ui-state-active"); }); jQuery("#RESET_'. $table_id.'").click( function() { for (i=19; i<=21; i++) { oTable'.$table_id.'.fnFilter("", i ); }; jQuery("div.filtersH_'.$table_id.' button").removeClass("ui-state-active"); }); /* This code is a temporary fix for Datatables bug http://www.datatables.net/forums/discussion/4730/datatables_sort_wrapper-being-added-to-columns-with-bsortable-false/p1*/ jQuery("th span:eq(9)").css("display", "none"); jQuery("th div:eq(9)").css("margin", "auto").css("text-align", "center"); jQuery(".fam-list").css("visibility", "visible"); jQuery(".loading-image").css("display", "none"); '); $stats = new WT_Stats($GEDCOM); $max_age = max($stats->oldestMarriageMaleAge(), $stats->oldestMarriageFemaleAge())+1; //-- init chart data for ($age=0; $age<=$max_age; $age++) $marr_by_age[$age]=''; for ($year=1550; $year<2030; $year+=10) $birt_by_decade[$year]=''; for ($year=1550; $year<2030; $year+=10) $marr_by_decade[$year]=''; //--table wrapper $html .= '
 
'; $html .= '
'; //-- table header $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; $html .= ''; //-- table body $html .= ''; $num = 0; $d100y=new WT_Date(date('Y')-100); // 100 years ago foreach ($datalist as $key => $value) { if (is_object($value)) { // Array of objects $family=$value; } elseif (!is_array($value)) { // Array of IDs $family=WT_Family::getInstance($value); } else { // Array of search results $gid = ""; if (isset($value['gid'])) $gid = $value['gid']; if (isset($value['gedcom'])) $family = new WT_Family($value['gedcom']); else $family = WT_Family::getInstance($gid); } if (is_null($family)) continue; if ($family->getType() !== 'FAM') continue; //-- Retrieve husband and wife $husb = $family->getHusband(); if (is_null($husb)) $husb = new WT_Person(''); $wife = $family->getWife(); if (is_null($wife)) $wife = new WT_Person(''); if (!$family->canDisplayDetails()) { continue; } //-- place filtering if ($option=='MARR_PLAC' && strstr($family->getMarriagePlace(), $filter)===false) continue; $html .= ''; //-- Husband name(s) $html .= ''; // Dummy column to match colspan in header $html .= ''; //-- Husb GIVN // Use "AAAA" as a separator (instead of ",") as JavaScript.localeCompare() ignores // punctuation and "ANN,ROACH" would sort after "ANNE,ROACH", instead of before it. // Similarly, @N.N. would sort as NN. $html .= ''; $html .= ''; $mdate=$family->getMarriageDate(); //-- Husband age $html .= ''; //-- Wife name(s) $html .= ''; // Dummy column to match colspan in header $html .= ''; //-- Wife GIVN //-- Husb GIVN // Use "AAAA" as a separator (instead of ",") as JavaScript.localeCompare() ignores // punctuation and "ANN,ROACH" would sort after "ANNE,ROACH", instead of before it. // Similarly, @N.N. would sort as NN. $html .= ''; $html .= ''; $mdate=$family->getMarriageDate(); //-- Wife age $html .= ''; //-- Marriage date $html .= ''; //-- Event date (sortable)hidden by datatables code $html .= ''; //-- Marriage anniversary $html .= ''; //-- Marriage place $html .= ''; //-- Number of children $nchi=$family->getNumberOfChildren(); $html .= ''; //-- Last change if ($SHOW_LAST_CHANGE) { $html .= ''; } else { $html .= ''; } //-- Sorting by marriage date $html .= ''; //-- Sorting alive/dead $html .= ''; //-- Roots or Leaves $html .= ''; } $html .= ''. '
'. WT_Gedcom_Tag::getLabel('GIVN'). ''. WT_Gedcom_Tag::getLabel('SURN'). 'HUSB:GIVN_SURNHUSB:SURN_GIVN'. WT_Gedcom_Tag::getLabel('AGE'). 'AGE'. WT_Gedcom_Tag::getLabel('GIVN'). ''. WT_Gedcom_Tag::getLabel('SURN'). 'WIFE:GIVN_SURNWIFE:SURN_GIVN'. WT_Gedcom_Tag::getLabel('AGE'). 'AGE'. WT_Gedcom_Tag::getLabel('MARR'). 'MARR:DATE'. WT_I18N::translate('Anniversary'). ''. WT_Gedcom_Tag::getLabel('PLAC'). ''. WT_I18N::translate('Children'). 'NCHI'. WT_Gedcom_Tag::getLabel('CHAN'). 'MARRDEATTREE
'; foreach ($husb->getAllNames() as $num=>$name) { if ($name['type']=='NAME') { $title=''; } else { $title='title="'.strip_tags(WT_Gedcom_Tag::getLabel($name['type'], $husb)).'"'; } if ($num==$husb->getPrimaryName()) { $class=' class="name2"'; $sex_image=$husb->getSexImage(); list($surn, $givn)=explode(',', $name['sort']); } else { $class=''; $sex_image=''; } // Only show married names if they are the name we are filtering by. if ($name['type']!='_MARNM' || $num==$husb->getPrimaryName()) { $html .= ''. highlight_search_hits($name['full']). ''. $sex_image. '
'; } } // Husband parents $html .= $husb->getPrimaryParentsNames('parents_'.$table_id.' details1', 'none'); $html .= '
'. htmlspecialchars(str_replace('@P.N.', 'AAAA', $givn)). 'AAAA'. htmlspecialchars(str_replace('@N.N.', 'AAAA', $surn)). ''. htmlspecialchars(str_replace('@N.N.', 'AAAA', $surn)). 'AAAA'. htmlspecialchars(str_replace('@P.N.', 'AAAA', $givn)). ''; $hdate=$husb->getBirthDate(); if ($hdate->isOK() && $mdate->isOK()) { if ($hdate->gregorianYear()>=1550 && $hdate->gregorianYear()<2030) { $birt_by_decade[floor($hdate->gregorianYear()/10)*10] .= $husb->getSex(); } $hage=WT_Date::GetAgeYears($hdate, $mdate); $hage_jd = $mdate->MinJD()-$hdate->MinJD(); $html .= WT_I18N::number($hage); $marr_by_age[max(0, min($max_age, $hage))] .= $husb->getSex(); } else { $hage=0; } $html .= ''. $hage. ''; foreach ($wife->getAllNames() as $num=>$name) { if ($name['type']=='NAME') { $title=''; } else { $title='title="'.strip_tags(WT_Gedcom_Tag::getLabel($name['type'], $wife)).'"'; } if ($num==$wife->getPrimaryName()) { $class=' class="name2"'; $sex_image=$wife->getSexImage(); list($surn, $givn)=explode(',', $name['sort']); } else { $class=''; $sex_image=''; } // Only show married names if they are the name we are filtering by. if ($name['type']!='_MARNM' || $num==$wife->getPrimaryName()) { $html .= ''. highlight_search_hits($name['full']). ''. $sex_image. '
'; } } // Wife parents $html .= $wife->getPrimaryParentsNames("parents_".$table_id." details1", 'none'); $html .= '
'. htmlspecialchars(str_replace('@P.N.', 'AAAA', $givn)). 'AAAA'. htmlspecialchars(str_replace('@N.N.', 'AAAA', $surn)). ''. htmlspecialchars(str_replace('@N.N.', 'AAAA', $surn)). 'AAAA'. htmlspecialchars(str_replace('@P.N.', 'AAAA', $givn)). ''; $wdate=$wife->getBirthDate(); if ($wdate->isOK() && $mdate->isOK()) { if ($wdate->gregorianYear()>=1550 && $wdate->gregorianYear()<2030) { $birt_by_decade[floor($wdate->gregorianYear()/10)*10] .= $wife->getSex(); } $wage=WT_Date::GetAgeYears($wdate, $mdate); $wage_jd = $mdate->MinJD()-$wdate->MinJD(); $html .= WT_I18N::number($wage); $marr_by_age[max(0, min($max_age, $wage))] .= $wife->getSex(); } else { $wage=0; } $html .= ''. $wage. ''; if ($marriage_dates=$family->getAllMarriageDates()) { foreach ($marriage_dates as $n=>$marriage_date) { if ($n) { $html .= '
'; } $html .= '
'. $marriage_date->Display(!$SEARCH_SPIDER). '
'; } if ($marriage_dates[0]->gregorianYear()>=1550 && $marriage_dates[0]->gregorianYear()<2030) { $marr_by_decade[floor($marriage_dates[0]->gregorianYear()/10)*10] .= $husb->getSex().$wife->getSex(); } } else if (get_sub_record(1, '1 _NMR', $family->getGedcomRecord())) { $hus = $family->getHusband(); $wif = $family->getWife(); if (empty($wif) && !empty($hus)) $html .= WT_Gedcom_Tag::getLabel('_NMR', $hus); else if (empty($hus) && !empty($wif)) $html .= WT_Gedcom_Tag::getLabel('_NMR', $wif); else $html .= WT_Gedcom_Tag::getLabel('_NMR'); } else if (get_sub_record(1, '1 _NMAR', $family->getGedcomRecord())) { $hus = $family->getHusband(); $wif = $family->getWife(); if (empty($wif) && !empty($hus)) $html .= WT_Gedcom_Tag::getLabel('_NMAR', $hus); else if (empty($hus) && !empty($wif)) $html .= WT_Gedcom_Tag::getLabel('_NMAR', $wif); else $html .= WT_Gedcom_Tag::getLabel('_NMAR'); } else { $factdetail = explode(' ', trim($family->getMarriageRecord())); if (isset($factdetail)) { if (count($factdetail) >= 3) { if (strtoupper($factdetail[2]) != "N") { $html .= WT_I18N::translate('yes'); } else { $html .= WT_I18N::translate('no'); } } else { $html .= ' '; } } } $html .= '
'; if ($marriage_dates) { $html .= $marriage_date->JD(); } else { $html .= 0; } $html .= ''; $mage=WT_Date::GetAgeYears($mdate); if ($mage) { $html .= WT_I18N::number($mage); } else { $html .= ' '; } $html .= ''; foreach ($family->getAllMarriagePlaces() as $n=>$marriage_place) { if ($n) { $html .= '
'; } if ($SEARCH_SPIDER) { $html .= get_place_short($marriage_place). ' '; } else { $html .= ''; $html .= highlight_search_hits(get_place_short($marriage_place)). ''; } } $html .= '
'. WT_I18N::number($nchi). ''. $nchi. ''. $family->LastChangeTimestamp(empty($SEARCH_SPIDER)). ' '; if (!$family->canDisplayDetails() || !$mdate->isOK()) { $html .= 'U'; } else { if (WT_Date::Compare($mdate, $d100y)>0) { $html .= 'Y100'; } else { $html .= 'YES'; } } if ($family->isDivorced()) { $html .= 'D'; } if (count($husb->getSpouseFamilies())>1 || count($wife->getSpouseFamilies())>1) { $html .= 'M'; } $html .= ''; if ($husb->isDead() && $wife->isDead()) $html .= 'Y'; if ($husb->isDead() && !$wife->isDead()) { if ($wife->getSex()=='F') $html .= 'H'; if ($wife->getSex()=='M') $html .= 'W'; // male partners } if (!$husb->isDead() && $wife->isDead()) { if ($husb->getSex()=='M') $html .= 'W'; if ($husb->getSex()=='F') $html .= 'H'; // female partners } if (!$husb->isDead() && !$wife->isDead()) $html .= 'N'; $html .= ''; if (!$husb->getChildFamilies() && !$wife->getChildFamilies()) { $html .= 'R'; } // roots elseif (!$husb->isDead() && !$wife->isDead() && $family->getNumberOfChildren()<1) { $html .= 'L'; } // leaves else { $html .= ' '; } $html .= '
'; //-- charts $html .= '
'; // Close "fam-list" return $html; } // print a table of sources function print_sour_table($datalist) { global $SHOW_LAST_CHANGE, $WT_IMAGES, $controller; $table_id = "ID".floor(microtime()*1000000); // lists requires a unique ID in case there are multiple lists per page $controller ->addExternalJavaScript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js') ->addInlineJavaScript(' jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; jQuery("#'.$table_id.'").dataTable( { "sDom": \'<"H"pf<"dt-clear">irl>t<"F"pl>\', '.WT_I18N::datatablesI18N().', "bJQueryUI": true, "bAutoWidth":false, "bProcessing": true, "aoColumns": [ /* 0 title */ {"iDataSort": 1}, /* 1 TITL */ {"bVisible": false, "sType": "unicode"}, /* 2 author */ {"sType": "unicode"}, /* 3 #indi */ {"iDataSort": 4, "sClass": "center"}, /* 4 #INDI */ {"sType": "numeric", "bVisible": false}, /* 5 #fam */ {"iDataSort": 6, "sClass": "center"}, /* 6 #FAM */ {"sType": "numeric", "bVisible": false}, /* 7 #obje */ {"iDataSort": 8, "sClass": "center"}, /* 8 #OBJE */ {"sType": "numeric", "bVisible": false}, /* 9 #note */ {"iDataSort": 10, "sClass": "center"}, /* 10 #NOTE */ {"sType": "numeric", "bVisible": false}, /* 11 CHAN */ {"bVisible": '.($SHOW_LAST_CHANGE?'true':'false').'}, /* 12 DELETE */ {"bVisible": '.(WT_USER_GEDCOM_ADMIN?'true':'false').', "bSortable": false} ], "iDisplayLength": 20, "sPaginationType": "full_numbers" }); jQuery(".source-list").css("visibility", "visible"); jQuery(".loading-image").css("display", "none"); '); //--table wrapper echo '
 
'; echo '
'; //-- table header echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '';//delete echo ''; //-- table body echo ''; $n=0; foreach ($datalist as $key=>$value) { if (is_object($value)) { // Array of objects $source=$value; } elseif (!is_array($value)) { // Array of IDs $source=WT_Source::getInstance($key); // from placelist if (is_null($source)) { $source=WT_Source::getInstance($value); } unset($value); } else { // Array of search results $gid=''; if (isset($value['gid'])) { $gid=$value['gid']; } if (isset($value['gedcom'])) { $source=new WT_Source($value['gedcom']); } else { $source=WT_Source::getInstance($gid); } } if (!$source || !$source->canDisplayDetails()) { continue; } echo ''; //-- Source name(s) echo ''; // Sortable name echo ''; //-- Author echo ''; //-- Linked INDIs $num=$source->countLinkedIndividuals(); echo ''; //-- Linked FAMs $num=$source->countLinkedfamilies(); echo ''; //-- Linked OBJEcts $num=$source->countLinkedMedia(); echo ''; //-- Linked NOTEs $num=$source->countLinkedNotes(); echo ''; //-- Last change if ($SHOW_LAST_CHANGE) { echo ''; } else { echo ''; } //-- Delete if (WT_USER_GEDCOM_ADMIN) { echo ''; } else { echo ''; } echo ''; } echo '', '
', WT_Gedcom_Tag::getLabel('TITL'), 'TITL', WT_Gedcom_Tag::getLabel('AUTH'), '', WT_I18N::translate('Individuals'), '#INDI', WT_I18N::translate('Families'), '#FAM', WT_I18N::translate('Media objects'), '#OBJE', WT_I18N::translate('Shared notes'), '#NOTE', WT_Gedcom_Tag::getLabel('CHAN'), ' 
'; foreach ($source->getAllNames() as $n=>$name) { if ($n) { echo '
'; } if ($n==$source->getPrimaryName()) { echo '', highlight_search_hits($name['full']), ''; } else { echo '', highlight_search_hits($name['full']), ''; } } echo '
', strip_tags($source->getFullName()), '', highlight_search_hits(htmlspecialchars($source->getAuth())), '', WT_I18N::number($num), '', $num, '', WT_I18N::number($num), '', $num, '', WT_I18N::number($num), '', $num, '', WT_I18N::number($num), '', $num, '', $source->LastChangeTimestamp(empty($SEARCH_SPIDER)), ' 
', WT_I18N::translate('Delete'), '
 
', '
'; } // print a table of shared notes function print_note_table($datalist) { global $SHOW_LAST_CHANGE, $WT_IMAGES, $controller; $table_id = 'ID'.floor(microtime()*1000000); // lists requires a unique ID in case there are multiple lists per page $controller ->addExternalJavaScript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js') ->addInlineJavaScript(' jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; jQuery("#'.$table_id.'").dataTable({ "sDom": \'<"H"pf<"dt-clear">irl>t<"F"pl>\', '.WT_I18N::datatablesI18N().', "bJQueryUI": true, "bAutoWidth":false, "bProcessing": true, "aoColumns": [ /* 0 title */ {"sType": "unicode"}, /* 1 #indi */ {"iDataSort": 2, "sClass": "center"}, /* 2 #INDI */ {"sType": "numeric", "bVisible": false}, /* 3 #fam */ {"iDataSort": 4, "sClass": "center"}, /* 4 #FAM */ {"sType": "numeric", "bVisible": false}, /* 5 #obje */ {"iDataSort": 6, "sClass": "center"}, /* 6 #OBJE */ {"sType": "numeric", "bVisible": false}, /* 7 #sour */ {"iDataSort": 8, "sClass": "center"}, /* 8 #SOUR */ {"sType": "numeric", "bVisible": false}, /* 9 CHAN */ {"bVisible": '.($SHOW_LAST_CHANGE?'true':'false').'}, /* 10 DELETE */ {"bVisible": '.(WT_USER_GEDCOM_ADMIN?'true':'false').', "bSortable": false} ], "iDisplayLength": 20, "sPaginationType": "full_numbers" }); jQuery(".note-list").css("visibility", "visible"); jQuery(".loading-image").css("display", "none"); '); //--table wrapper echo '
 
'; echo '
'; //-- table header echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '';//delete echo ''; //-- table body echo ''; foreach ($datalist as $note) { if (!$note->canDisplayDetails()) { continue; } echo ''; //-- Shared Note name echo ''; //-- Linked INDIs $num=$note->countLinkedIndividuals(); echo ''; //-- Linked FAMs $num=$note->countLinkedfamilies(); echo ''; //-- Linked OBJEcts $num=$note->countLinkedMedia(); echo ''; //-- Linked SOURs $num=$note->countLinkedSources(); echo ''; //-- Last change if ($SHOW_LAST_CHANGE) { echo ''; } else { echo ''; } //-- Delete if (WT_USER_GEDCOM_ADMIN) { echo ''; } else { echo ''; } echo ''; } echo '', '
', WT_Gedcom_Tag::getLabel('TITL'), '', WT_I18N::translate('Individuals'), '#INDI', WT_I18N::translate('Families'), '#FAM', WT_I18N::translate('Media objects'), '#OBJE', WT_I18N::translate('Sources'), '#SOUR', WT_Gedcom_Tag::getLabel('CHAN'), ' 
', highlight_search_hits($note->getFullName()), '', WT_I18N::number($num), '', $num, '', WT_I18N::number($num), '', $num, '', WT_I18N::number($num), '', $num, '', WT_I18N::number($num), '', $num, '', $note->LastChangeTimestamp(empty($SEARCH_SPIDER)), '
', WT_I18N::translate('Delete'), '
', '
'; } // print a table of repositories function print_repo_table($repos) { global $SHOW_LAST_CHANGE, $WT_IMAGES, $SEARCH_SPIDER, $controller; $table_id = 'ID'.floor(microtime()*1000000); // lists requires a unique ID in case there are multiple lists per page $controller ->addExternalJavaScript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js') ->addInlineJavaScript(' jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; jQuery("#'.$table_id.'").dataTable({ "sDom": \'<"H"pf<"dt-clear">irl>t<"F"pl>\', '.WT_I18N::datatablesI18N().', "bJQueryUI": true, "bAutoWidth":false, "bProcessing": true, "aoColumns": [ /* 0 name */ {"sType": "unicode"}, /* 1 #sour */ {"iDataSort": 2, "sClass": "center"}, /* 2 #SOUR */ {"sType": "numeric", "bVisible": false}, /* 3 CHAN */ {"bVisible": '.($SHOW_LAST_CHANGE?'true':'false').'}, /* 4 DELETE */ {"bVisible": '.(WT_USER_GEDCOM_ADMIN?'true':'false').', "bSortable": false} ], "iDisplayLength": 20, "sPaginationType": "full_numbers" }); jQuery(".repo-list").css("visibility", "visible"); jQuery(".loading-image").css("display", "none"); '); //--table wrapper echo '
 
'; echo '
'; //-- table header echo ''; echo ''; echo ''; echo ''; echo ''; echo '';//delete echo ''; //-- table body echo ''; $n=0; foreach ($repos as $repo) { if (!$repo->canDisplayDetails()) { continue; } echo ''; //-- Repository name(s) echo ''; //-- Linked SOURces $num=$repo->countLinkedSources(); echo ''; //-- Last change if ($SHOW_LAST_CHANGE) { echo ''; } else { echo ''; } //-- Delete if (WT_USER_GEDCOM_ADMIN) { echo ''; } else { echo ''; } echo ''; } echo '', '
', WT_I18N::translate('Repository name'), '', WT_I18N::translate('Sources'), '#SOUR', WT_Gedcom_Tag::getLabel('CHAN'), ' 
'; foreach ($repo->getAllNames() as $n=>$name) { if ($n) { echo '
'; } if ($n==$repo->getPrimaryName()) { echo '', highlight_search_hits($name['full']), ''; } else { echo '', highlight_search_hits($name['full']), ''; } } echo '
', WT_I18N::number($num), '', $num, '', $repo->LastChangeTimestamp(!$SEARCH_SPIDER), ' 
', WT_I18N::translate('Delete'), '
 
', '
'; } // print a table of media objects function print_media_table($datalist) { global $SHOW_LAST_CHANGE, $WT_IMAGES, $controller; $table_id = 'ID'.floor(microtime()*1000000); // lists requires a unique ID in case there are multiple lists per page $controller ->addExternalJavaScript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js') ->addInlineJavaScript(' jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; jQuery("#'.$table_id.'").dataTable({ "sDom": \'<"H"pf<"dt-clear">irl>t<"F"pl>\', '.WT_I18N::datatablesI18N().', "bJQueryUI": true, "bAutoWidth":false, "bProcessing": true, "aoColumns": [ /* 0 media */ {"bSortable": false}, /* 1 title */ {"sType": "unicode"}, /* 2 #indi */ {"iDataSort": 3, "sClass": "center"}, /* 3 #INDI */ {"sType": "numeric", "bVisible": false}, /* 4 #fam */ {"iDataSort": 5, "sClass": "center"}, /* 5 #FAM */ {"sType": "numeric", "bVisible": false}, /* 6 #sour */ {"iDataSort": 7, "sClass": "center"}, /* 7 #SOUR */ {"sType": "numeric", "bVisible": false}, /* 8 CHAN */ {"bVisible": '.($SHOW_LAST_CHANGE?'true':'false').'}, ], "iDisplayLength": 20, "sPaginationType": "full_numbers" }); jQuery(".media-list").css("visibility", "visible"); jQuery(".loading-image").css("display", "none"); '); //--table wrapper echo '
 
'; echo '
'; //-- table header echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; //-- table body echo ''; $n = 0; foreach ($datalist as $key => $value) { if (is_object($value)) { // Array of objects $media=$value; } else { $media = new WT_Media($value["GEDCOM"]); if (is_null($media)) $media = WT_Media::getInstance($key); if (is_null($media)) continue; } if ($media->canDisplayDetails()) { $name = $media->getFullName(); echo ""; //-- Object thumbnail echo ''; //-- Object name(s) echo ''; //-- Linked INDIs $num=$media->countLinkedIndividuals(); echo ''; //-- Linked FAMs $num=$media->countLinkedfamilies(); echo ''; //-- Linked SOURces $num=$media->countLinkedSources(); echo ''; //-- Last change if ($SHOW_LAST_CHANGE) { echo ''; } else { echo ''; } echo ''; } } echo '', '
', WT_I18N::translate('Media'), '', WT_Gedcom_Tag::getLabel('TITL'), '', WT_I18N::translate('Individuals'), '#INDI', WT_I18N::translate('Families'), '#FAM', WT_I18N::translate('Sources'), '#SOUR', WT_Gedcom_Tag::getLabel('CHAN'), '
', htmlspecialchars(strip_tags($name)), ''; echo ''; echo highlight_search_hits($name), ''; if (WT_USER_CAN_EDIT || WT_USER_CAN_ACCEPT) echo '
', basename($media->getFilename()), ''; if ($media->getNote()) echo '
', print_fact_notes('1 NOTE '.$media->getNote(), 1); echo '
', WT_I18N::number($num), '', $num, '', WT_I18N::number($num), '', $num, '', WT_I18N::number($num), '', $num, '', $media->LastChangeTimestamp(empty($SEARCH_SPIDER)), ' 
', '
'; } // Print a table of surnames, for the top surnames block, the indi/fam lists, etc. // $surnames - array (of SURN, of array of SPFX_SURN, of array of PID) // $type - "indilist.php" (counts of individuals) or "famlist.php" (counts of spouses) function format_surname_table($surnames, $script) { global $controller; $controller ->addExternalJavaScript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js') ->addInlineJavaScript(' jQuery.fn.dataTableExt.oSort["num-asc" ]=function(a,b) {a=parseFloat(a); b=parseFloat(b); return (ab ? 1 : 0);}; jQuery.fn.dataTableExt.oSort["num-desc"]=function(a,b) {a=parseFloat(a); b=parseFloat(b); return (a>b) ? -1 : (a'.WT_Gedcom_Tag::getLabel('SURN').''. ' '. ''.$col_heading.''. ' '. ''; $tbody=''; $unique_surn=array(); $unique_indi=array(); $n=0; // We have already sorted the data - use this as a surrogate sort key foreach ($surnames as $surn=>$surns) { // Each surname links back to the indi/fam surname list if ($surn) { $url=$script.'?surname='.rawurlencode($surn).'&ged='.WT_GEDURL; } else { $url=$script.'?alpha=,&ged='.WT_GEDURL; } // Row counter $tbody.=''; // Surname $tbody.=''; if (count($surns)==1) { // Single surname variant foreach ($surns as $spfxsurn=>$indis) { $tbody.=''.htmlspecialchars($spfxsurn).''; $unique_surn[$spfxsurn]=true; foreach (array_keys($indis) as $pid) { $unique_indi[$pid]=true; } } } else { // Multiple surname variants, e.g. von Groot, van Groot, van der Groot, etc. foreach ($surns as $spfxsurn=>$indis) { $tbody.=''.htmlspecialchars($spfxsurn).'
'; $unique_surn[$spfxsurn]=true; foreach (array_keys($indis) as $pid) { $unique_indi[$pid]=true; } } } $tbody.=''; // Sort column for name $tbody.=''.$n++.''; // Surname count $tbody.=''; if (count($surns)==1) { // Single surname variant foreach ($surns as $spfxsurn=>$indis) { $subtotal=count($indis); $tbody.= WT_I18N::number($subtotal); } } else { $subtotal=0; // Multiple surname variants, e.g. von Groot, van Groot, van der Groot, etc. foreach ($surns as $spfxsurn=>$indis) { $subtotal+=count($indis); $tbody.=WT_I18N::number(count($indis)).'
'; } $tbody.=WT_I18N::number($subtotal); } $tbody.=''; // add hidden numeric sort column $tbody.=''. $subtotal. ''; } return ''. ''.$thead.''. ''.$tbody.''. '
'; } // Print a tagcloud of surnames. // @param $surnames array (of SURN, of array of SPFX_SURN, of array of PID) // @param $type string, indilist or famlist // @param $totals, boolean, show totals after each name function format_surname_tagcloud($surnames, $script, $totals) { $cloud=new Zend_Tag_Cloud( array( 'tagDecorator'=>array( 'decorator'=>'HtmlTag', 'options'=>array( 'htmlTags'=>array(), 'fontSizeUnit'=>'%', 'minFontSize'=>80, 'maxFontSize'=>250 ) ), 'cloudDecorator'=>array( 'decorator'=>'HtmlCloud', 'options'=>array( 'htmlTags'=>array( 'div'=>array( 'class'=>'tag_cloud' ) ) ) ) ) ); foreach ($surnames as $surn=>$surns) { foreach ($surns as $spfxsurn=>$indis) { $cloud->appendTag(array( 'title'=>$totals ? WT_I18N::translate('%1$s (%2$d)', $spfxsurn, count($indis)) : $spfxsurn, 'weight'=>count($indis), 'params'=>array( 'url'=>$surn ? $script.'?surname='.urlencode($surn).'&ged='.WT_GEDURL : $script.'?alpha=,&ged='.WT_GEDURL ) )); } } return (string)$cloud; } // Print a list of surnames. // @param $surnames array (of SURN, of array of SPFX_SURN, of array of PID) // @param $style, 1=bullet list, 2=semicolon-separated list, 3=tabulated list with up to 4 columns // @param $totals, boolean, show totals after each name // @param $type string, indilist or famlist function format_surname_list($surnames, $style, $totals, $script) { global $GEDCOM; $html=array(); foreach ($surnames as $surn=>$surns) { // Each surname links back to the indilist if ($surn) { $url=$script.'?surname='.urlencode($surn).'&ged='.rawurlencode($GEDCOM); } else { $url=$script.'?alpha=,&ged='.rawurlencode($GEDCOM); } // If all the surnames are just case variants, then merge them into one // Comment out this block if you want SMITH listed separately from Smith $first_spfxsurn=null; foreach ($surns as $spfxsurn=>$indis) { if ($first_spfxsurn) { if (utf8_strtoupper($spfxsurn)==utf8_strtoupper($first_spfxsurn)) { $surns[$first_spfxsurn]=array_merge($surns[$first_spfxsurn], $surns[$spfxsurn]); unset ($surns[$spfxsurn]); } } else { $first_spfxsurn=$spfxsurn; } } $subhtml=''.htmlspecialchars(implode(', ', array_keys($surns))).''; if ($totals) { $subtotal=0; foreach ($surns as $spfxsurn=>$indis) { $subtotal+=count($indis); } $subhtml.=' ('.$subtotal.')'; } $html[]=$subhtml; } switch ($style) { case 1: return '
  • '.implode('
  • ', $html).'
'; case 2: return implode('; ', $html); case 3: $i = 0; $count = count($html); $count_indi = 0; $col = 1; if ($count>36) $col=4; else if ($count>18) $col=3; else if ($count>6) $col=2; $newcol=ceil($count/$col); $html2 =''; $html2.='
'; foreach ($html as $surn=>$surns) { $html2.= $surns.'
'; $i++; if ($i==$newcol && $i<$count) { $html2.='
'; $newcol=$i+ceil($count/$col); } } $html2.='
'; return $html2; } } // print a list of recent changes function print_changes_list($change_ids, $sort) { $n = 0; $arr=array(); foreach ($change_ids as $change_id) { $record = WT_GedcomRecord::getInstance($change_id); if (!$record || !$record->canDisplayDetails()) { continue; } // setup sorting parameters $arr[$n]['record'] = $record; $arr[$n]['jd'] = ($sort == 'name') ? 1 : $n; $arr[$n]['anniv'] = $record->LastChangeTimestamp(false, true); $arr[$n++]['fact'] = $record->getSortName(); // in case two changes have same timestamp } switch ($sort) { case 'name': uasort($arr, 'event_sort_name'); break; case 'date_asc': uasort($arr, 'event_sort'); $arr = array_reverse($arr); break; case 'date_desc': uasort($arr, 'event_sort'); } $return = ''; foreach ($arr as $value) { $return .= '' . $value['record']->getFullName() . ''; $return .= '
'; if ($value['record']->getType() == 'INDI') { if ($value['record']->getAddName()) { $return .= '' . $value['record']->getAddName() . ''; } } $return .= /* I18N: [a record was] Changed on by */ WT_I18N::translate('Changed on %1$s by %2$s', $value['record']->LastChangeTimestamp(false), $value['record']->LastChangeUser()); $return .= '
'; } return $return; } // print a table of recent changes function print_changes_table($change_ids, $sort) { global $WT_IMAGES, $controller; $return = ''; $n = 0; $table_id = "ID" . floor(microtime() * 1000000); // create a unique ID switch ($sort) { case 'name': //name $aaSorting = "[5,'asc'], [4,'desc']"; break; case 'date_asc': //date ascending $aaSorting = "[4,'asc'], [5,'asc']"; break; case 'date_desc': //date descending $aaSorting = "[4,'desc'], [5,'asc']"; break; } $controller ->addExternalJavaScript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js') ->addInlineJavaScript(' jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; jQuery("#'.$table_id.'").dataTable({ "sDom": \'t\', "bPaginate": false, "bAutoWidth":false, "bLengthChange": false, "bFilter": false, '.WT_I18N::datatablesI18N().', "bJQueryUI": true, "aaSorting": ['.$aaSorting.'], "aoColumns": [ /* 0-Type */ {"bSortable": false, "sClass": "center"}, /* 1-Record */ {"iDataSort": 5}, /* 2-Change */ {"iDataSort": 4}, /* 3-By */ null, /* 4-DATE */ {"bVisible": false}, /* 5-SORTNAME */{"sType": "unicode", "bVisible": false} ] }); '); //-- table header $return .= ""; $return .= ""; $return .= ""; $return .= ""; $return .= ""; $return .= ""; $return .= ""; //hidden by datatables code $return .= ""; //hidden by datatables code $return .= ""; //-- table body foreach ($change_ids as $change_id) { $record = WT_GedcomRecord::getInstance($change_id); if (!$record || !$record->canDisplayDetails()) { continue; } $return .= ""; ++$n; //-- Record name(s) $name = $record->getFullName(); $return .= '"; //-- Last change date/time $return .= ""; //-- Last change user $return .= ""; //-- change date (sortable) hidden by datatables code $return .= ""; //-- names (sortable) hidden by datatables code $return .= ""; } $return .= '
 " . WT_I18N::translate('Record') . "" . WT_Gedcom_Tag::getLabel('CHAN') . "" . WT_Gedcom_Tag::getLabel('_WT_USER') . "DATESORTNAME
"; $indi = false; switch ($record->getType()) { case "INDI": $return .= $record->getSexImage('small', '', '', false); $indi = true; break; case "FAM": $return .= ''; break; case "OBJE": $return .= ''; break; case "NOTE": $return .= ''; break; case "SOUR": $return .= ''; break; case "REPO": $return .= ''; break; default: $return .= ' '; break; } $return .= "'; $return .= ''. $name . ''; if ($indi) { $addname = $record->getAddName(); if ($addname) { $return .= ''; } } $return .= "" . $record->LastChangeTimestamp(empty($SEARCH_SPIDER)) . "" . $record->LastChangeUser() . "" . $record->LastChangeTimestamp(false, true) . "" . $record->getSortName() . "
'; return $return; } // print a table of events function print_events_table($startjd, $endjd, $events='BIRT MARR DEAT', $only_living=false, $sort_by='anniv') { global $WT_IMAGES, $controller; $table_id = "ID".floor(microtime()*1000000); // each table requires a unique ID $controller ->addExternalJavaScript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js') ->addInlineJavaScript(' jQuery("#'.$table_id.'").dataTable({ "sDom": \'t\', '.WT_I18N::datatablesI18N().', "bAutoWidth":false, "bPaginate": false, "bLengthChange": false, "bFilter": false, "bInfo": true, "bJQueryUI": true, "aaSorting": [[ '.($sort_by=='alpha' ? 1 : 3).', "asc"]], "aoColumns": [ /* 0-Record */ { "iDataSort": 1}, /* 1-NAME */ { "bVisible": false }, /* 2-Date */ { "iDataSort": 3 }, /* 3-DATE */ { "bVisible": false }, /* 4-Anniv. */ { "iDataSort": 5, "sClass": "center"}, /* 5-ANNIV */ { "sType": "numeric", "bVisible": false}, /* 6-Event */ { "sClass": "center" } ] }); '); // Did we have any output? Did we skip anything? $output = 0; $filter = 0; $return = ''; $filtered_events = array(); foreach (get_events_list($startjd, $endjd, $events) as $value) { $record=$value['record']; //-- only living people ? if ($only_living) { if ($record->getType()=="INDI" && $record->isDead()) { $filter ++; continue; } if ($record->getType()=="FAM") { $husb = $record->getHusband(); if (is_null($husb) || $husb->isDead()) { $filter ++; continue; } $wife = $record->getWife(); if (is_null($wife) || $wife->isDead()) { $filter ++; continue; } } } // Privacy if (!$record->canDisplayDetails() || !canDisplayFact($record->getXref(), $record->getGedId(), $value['factrec'])) { continue; } //-- Counter $output ++; if ($output==1) { //-- table body $return .= ''; $return .= ''; $return .= ''; $return .= ''; //hidden by datatables code $return .= ''; $return .= ''; //hidden by datatables code $return .= ''; $return .= ''; $return .= ''; $return .= ''."\n"; } $value['name'] = $record->getFullName(); $value['url'] = $record->getHtmlUrl(); if ($record->getType()=="INDI") { $value['sex'] = $record->getSexImage(); } else { $value['sex'] = ''; } $filtered_events[] = $value; } foreach ($filtered_events as $n=>$value) { $return .= ""; //-- Record name(s) $name = $value['name']; $return .= ''; //-- NAME $return .= ''; //-- Event date $return .= ''; //-- Event date (sortable) $return .= ''; //-- Anniversary $anniv = $value['anniv']; $return .= ''; //-- Event name $return .= ''; $return .= ''."\n"; } if ($output!=0) { $return .= '
'.WT_I18N::translate('Record').'NAME'.WT_Gedcom_Tag::getLabel('DATE').'DATE'.WT_I18N::translate('Anniversary').'ANNIV'.WT_Gedcom_Tag::getLabel('EVEN').'
'; $return .= ''.$name.''; if ($value['record']->getType()=="INDI") { $return .= $value['sex']; } $return .= ''; //hidden by datatables code $return .= $value['record']->getSortName(); $return .= ''; $return .= $value['date']->Display(empty($SEARCH_SPIDER)); $return .= ''; //hidden by datatables code $return .= $n; $return .= ''.($anniv ? WT_I18N::number($anniv) : ' ').''.$anniv.''; $return .= ''.WT_Gedcom_Tag::getLabel($value['fact']).''; $return .= ' 
'; } // Print a final summary message about restricted/filtered facts $summary = ""; if ($endjd==WT_CLIENT_JD) { // We're dealing with the Today's Events block if ($output==0) { if ($filter==0) { $summary = WT_I18N::translate('No events exist for today.'); } else { $summary = WT_I18N::translate('No events for living people exist for today.'); } } } else { // We're dealing with the Upcoming Events block if ($output==0) { if ($filter==0) { if ($endjd==$startjd) { $summary = WT_I18N::translate('No events exist for tomorrow.'); } else { // I18N: tanslation for %d==1 is unused; it is translated separately as tomorrow $summary = WT_I18N::plural('No events exist for the next %d day.', 'No events exist for the next %d days.', $endjd-$startjd+1, $endjd-$startjd+1); } } else { if ($endjd==$startjd) { $summary = WT_I18N::translate('No events for living people exist for tomorrow.'); } else { // I18N: tanslation for %d==1 is unused; it is translated separately as tomorrow $summary = WT_I18N::plural('No events for living people exist for the next %d day.', 'No events for living people exist for the next %d days.', $endjd-$startjd+1, $endjd-$startjd+1); } } } } if ($summary!="") { $return .= ''. $summary. ''; } return $return; } /** * print a list of events * * This performs the same function as print_events_table(), but formats the output differently. */ function print_events_list($startjd, $endjd, $events='BIRT MARR DEAT', $only_living=false, $sort_by='anniv') { // Did we have any output? Did we skip anything? $output = 0; $filter = 0; $return = ''; $filtered_events = array(); foreach (get_events_list($startjd, $endjd, $events) as $value) { $record = WT_GedcomRecord::getInstance($value['id']); //-- only living people ? if ($only_living) { if ($record->getType()=="INDI" && $record->isDead()) { $filter ++; continue; } if ($record->getType()=="FAM") { $husb = $record->getHusband(); if (is_null($husb) || $husb->isDead()) { $filter ++; continue; } $wife = $record->getWife(); if (is_null($wife) || $wife->isDead()) { $filter ++; continue; } } } // Privacy if (!$record->canDisplayDetails() || !canDisplayFact($record->getXref(), $record->getGedId(), $value['factrec'])) { continue; } $output ++; $value['name'] = $record->getFullName(); $value['url'] = $record->getHtmlUrl(); if ($record->getType()=="INDI") { $value['sex'] = $record->getSexImage(); } else { $value['sex'] = ''; } $filtered_events[] = $value; } // Now we've filtered the list, we can sort by event, if required switch ($sort_by) { case 'anniv': uasort($filtered_events, 'event_sort'); break; case 'alpha': uasort($filtered_events, 'event_sort_name'); break; } foreach ($filtered_events as $value) { $return .= "".$value['name']."".$value['sex']; $return .= "
"; $return .= WT_Gedcom_Tag::getLabel($value['fact']).' - '.$value['date']->Display(true); if ($value['anniv']!=0) $return .= " (" . WT_I18N::translate('%s year anniversary', $value['anniv']).")"; if (!empty($value['plac'])) $return .= " - ".$value['plac'].""; $return .= "
"; } // Print a final summary message about restricted/filtered facts $summary = ""; if ($endjd==WT_CLIENT_JD) { // We're dealing with the Today's Events block if ($output==0) { if ($filter==0) { $summary = WT_I18N::translate('No events exist for today.'); } else { $summary = WT_I18N::translate('No events for living people exist for today.'); } } } else { // We're dealing with the Upcoming Events block if ($output==0) { if ($filter==0) { if ($endjd==$startjd) { $summary = WT_I18N::translate('No events exist for tomorrow.'); } else { // I18N: tanslation for %d==1 is unused; it is translated separately as tomorrow $summary = WT_I18N::plural('No events exist for the next %d day.', 'No events exist for the next %d days.', $endjd-$startjd+1, $endjd-$startjd+1); } } else { if ($endjd==$startjd) { $summary = WT_I18N::translate('No events for living people exist for tomorrow.'); } else { // I18N: tanslation for %d==1 is unused; it is translated separately as tomorrow $summary = WT_I18N::plural('No events for living people exist for the next %d day.', 'No events for living people exist for the next %d days.', $endjd-$startjd+1, $endjd-$startjd+1); } } } } if ($summary) { $return .= "". $summary. ""; } return $return; } // print a chart by age using Google chart API function print_chart_by_age($data, $title) { $count = 0; $agemax = 0; $vmax = 0; $avg = 0; foreach ($data as $age=>$v) { $n = strlen($v); $vmax = max($vmax, $n); $agemax = max($agemax, $age); $count += $n; $avg += $age*$n; } if ($count<1) return; $avg = round($avg/$count); $chart_url = "http://chart.apis.google.com/chart?cht=bvs"; // chart type $chart_url .= "&chs=725x150"; // size $chart_url .= "&chbh=3,2,2"; // bvg : 4,1,2 $chart_url .= "&chf=bg,s,FFFFFF99"; //background color $chart_url .= "&chco=0000FF,FFA0CB,FF0000"; // bar color $chart_url .= "&chdl=".rawurlencode(WT_I18N::translate('Males'))."|".rawurlencode(WT_I18N::translate('Females'))."|".rawurlencode(WT_I18N::translate('Average age').": ".$avg); // legend & average age $chart_url .= "&chtt=".rawurlencode($title); // title $chart_url .= "&chxt=x,y,r"; // axis labels specification $chart_url .= "&chm=V,FF0000,0,".($avg-0.3).",1"; // average age line marker $chart_url .= "&chxl=0:|"; // label for ($age=0; $age<=$agemax; $age+=5) { $chart_url .= $age."|||||"; // x axis } $chart_url .= "|1:||".rawurlencode(WT_I18N::percentage($vmax/$count)); // y axis $chart_url .= "|2:||"; $step = $vmax; for ($d=floor($vmax); $d>0; $d--) { if ($vmax<($d*10+1) && fmod($vmax, $d)==0) $step = $d; } if ($step==floor($vmax)) { for ($d=floor($vmax-1); $d>0; $d--) { if (($vmax-1)<($d*10+1) && fmod(($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 ($age=0; $age<=$agemax; $age++) { $chart_url .= $CHART_ENCODING61[floor(substr_count($data[$age], "M")*61/$vmax)]; } $chart_url .= ","; for ($age=0; $age<=$agemax; $age++) { $chart_url .= $CHART_ENCODING61[floor(substr_count($data[$age], "F")*61/$vmax)]; } $html = ''. $title. ''; return $html; } // print a chart by decade using Google chart API function print_chart_by_decade($data, $title) { $count = 0; $vmax = 0; foreach ($data as $age=>$v) { $n = strlen($v); $vmax = max($vmax, $n); $count += $n; } if ($count<1) return; $chart_url = "http://chart.apis.google.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(WT_I18N::percentage($vmax/$count)); // y axis $chart_url .= "|2:||"; $step = $vmax; for ($d=floor($vmax); $d>0; $d--) { if ($vmax<($d*10+1) && fmod($vmax, $d)==0) $step = $d; } if ($step==floor($vmax)) { for ($d=floor($vmax-1); $d>0; $d--) { if (($vmax-1)<($d*10+1) && fmod(($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[floor(substr_count($data[$y], "M")*61/$vmax)]; } $chart_url .= ","; for ($y=1570; $y<2030; $y+=10) { $chart_url .= $CHART_ENCODING61[floor(substr_count($data[$y], "F")*61/$vmax)]; } $html = ''. $title. ''; return $html; }