18add1155SRico Sonntag<?php 28add1155SRico Sonntag/** 38add1155SRico Sonntag * webtrees: online genealogy 4242a7862SGreg Roach * Copyright (C) 2019 webtrees development team 58add1155SRico Sonntag * This program is free software: you can redistribute it and/or modify 68add1155SRico Sonntag * it under the terms of the GNU General Public License as published by 78add1155SRico Sonntag * the Free Software Foundation, either version 3 of the License, or 88add1155SRico Sonntag * (at your option) any later version. 98add1155SRico Sonntag * This program is distributed in the hope that it will be useful, 108add1155SRico Sonntag * but WITHOUT ANY WARRANTY; without even the implied warranty of 118add1155SRico Sonntag * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 128add1155SRico Sonntag * GNU General Public License for more details. 138add1155SRico Sonntag * You should have received a copy of the GNU General Public License 148add1155SRico Sonntag * along with this program. If not, see <http://www.gnu.org/licenses/>. 158add1155SRico Sonntag */ 168add1155SRico Sonntagdeclare(strict_types=1); 178add1155SRico Sonntag 188add1155SRico Sonntagnamespace Fisharebest\Webtrees\Statistics\Google; 198add1155SRico Sonntag 208add1155SRico Sonntaguse Fisharebest\Webtrees\I18N; 21*93ccd686SRico Sonntaguse Fisharebest\Webtrees\Statistics\Service\CenturyService; 228add1155SRico Sonntaguse Fisharebest\Webtrees\Tree; 230892c7deSRico Sonntaguse Illuminate\Database\Capsule\Manager as DB; 240892c7deSRico Sonntaguse Illuminate\Database\Query\JoinClause; 258add1155SRico Sonntag 268add1155SRico Sonntag/** 27*93ccd686SRico Sonntag * A chart showing the marriage ages by century. 288add1155SRico Sonntag */ 29*93ccd686SRico Sonntagclass ChartMarriageAge 308add1155SRico Sonntag{ 318add1155SRico Sonntag /** 32*93ccd686SRico Sonntag * @var Tree 338add1155SRico Sonntag */ 34*93ccd686SRico Sonntag private $tree; 35*93ccd686SRico Sonntag 36*93ccd686SRico Sonntag /** 37*93ccd686SRico Sonntag * @var CenturyService 38*93ccd686SRico Sonntag */ 39*93ccd686SRico Sonntag private $century_service; 408add1155SRico Sonntag 418add1155SRico Sonntag /** 428add1155SRico Sonntag * Constructor. 438add1155SRico Sonntag * 448add1155SRico Sonntag * @param Tree $tree 458add1155SRico Sonntag */ 468add1155SRico Sonntag public function __construct(Tree $tree) 478add1155SRico Sonntag { 48*93ccd686SRico Sonntag $this->tree = $tree; 49*93ccd686SRico Sonntag $this->century_service = new CenturyService(); 508add1155SRico Sonntag } 518add1155SRico Sonntag 528add1155SRico Sonntag /** 538add1155SRico Sonntag * Returns the related database records. 548add1155SRico Sonntag * 558add1155SRico Sonntag * @return \stdClass[] 568add1155SRico Sonntag */ 570892c7deSRico Sonntag private function queryRecords(): array 588add1155SRico Sonntag { 590892c7deSRico Sonntag $prefix = DB::connection()->getTablePrefix(); 600892c7deSRico Sonntag 610892c7deSRico Sonntag $male = DB::table('dates as married') 620892c7deSRico Sonntag ->select([ 630892c7deSRico Sonntag DB::raw('ROUND(AVG(' . $prefix . 'married.d_julianday2 - ' . $prefix . 'birth.d_julianday1 - 182.5) / 365.25, 1) AS age'), 64*93ccd686SRico Sonntag DB::raw('ROUND((' . $prefix . 'married.d_year + 49) / 100) AS century'), 650892c7deSRico Sonntag DB::raw("'M' as sex") 660892c7deSRico Sonntag ]) 670892c7deSRico Sonntag ->join('families as fam', function (JoinClause $join) { 680892c7deSRico Sonntag $join->on('fam.f_id', '=', 'married.d_gid') 690892c7deSRico Sonntag ->on('fam.f_file', '=', 'married.d_file'); 700892c7deSRico Sonntag }) 710892c7deSRico Sonntag ->join('dates as birth', function (JoinClause $join) { 720892c7deSRico Sonntag $join->on('birth.d_gid', '=', 'fam.f_husb') 730892c7deSRico Sonntag ->on('birth.d_file', '=', 'fam.f_file'); 740892c7deSRico Sonntag }) 750892c7deSRico Sonntag ->whereIn('married.d_type', ['@#DGREGORIAN@', '@#DJULIAN@']) 760892c7deSRico Sonntag ->where('married.d_file', '=', $this->tree->id()) 770892c7deSRico Sonntag ->where('married.d_fact', '=', 'MARR') 780892c7deSRico Sonntag ->where('married.d_julianday1', '>', 'birth.d_julianday1') 790892c7deSRico Sonntag ->whereIn('birth.d_type', ['@#DGREGORIAN@', '@#DJULIAN@']) 800892c7deSRico Sonntag ->where('birth.d_fact', '=', 'BIRT') 810892c7deSRico Sonntag ->where('birth.d_julianday1', '<>', 0) 820892c7deSRico Sonntag ->groupBy(['century', 'sex']); 830892c7deSRico Sonntag 840892c7deSRico Sonntag $female = DB::table('dates as married') 850892c7deSRico Sonntag ->select([ 860892c7deSRico Sonntag DB::raw('ROUND(AVG(' . $prefix . 'married.d_julianday2 - ' . $prefix . 'birth.d_julianday1 - 182.5) / 365.25, 1) AS age'), 87*93ccd686SRico Sonntag DB::raw('ROUND((' . $prefix . 'married.d_year + 49) / 100) AS century'), 880892c7deSRico Sonntag DB::raw("'F' as sex") 890892c7deSRico Sonntag ]) 900892c7deSRico Sonntag ->join('families as fam', function (JoinClause $join) { 910892c7deSRico Sonntag $join->on('fam.f_id', '=', 'married.d_gid') 920892c7deSRico Sonntag ->on('fam.f_file', '=', 'married.d_file'); 930892c7deSRico Sonntag }) 940892c7deSRico Sonntag ->join('dates as birth', function (JoinClause $join) { 950892c7deSRico Sonntag $join->on('birth.d_gid', '=', 'fam.f_wife') 960892c7deSRico Sonntag ->on('birth.d_file', '=', 'fam.f_file'); 970892c7deSRico Sonntag }) 980892c7deSRico Sonntag ->whereIn('married.d_type', ['@#DGREGORIAN@', '@#DJULIAN@']) 990892c7deSRico Sonntag ->where('married.d_file', '=', $this->tree->id()) 1000892c7deSRico Sonntag ->where('married.d_fact', '=', 'MARR') 1010892c7deSRico Sonntag ->where('married.d_julianday1', '>', 'birth.d_julianday1') 1020892c7deSRico Sonntag ->whereIn('birth.d_type', ['@#DGREGORIAN@', '@#DJULIAN@']) 1030892c7deSRico Sonntag ->where('birth.d_fact', '=', 'BIRT') 1040892c7deSRico Sonntag ->where('birth.d_julianday1', '<>', 0) 1050892c7deSRico Sonntag ->groupBy(['century', 'sex']); 1060892c7deSRico Sonntag 1070892c7deSRico Sonntag return $male->unionAll($female) 1080892c7deSRico Sonntag ->orderBy('century') 1090892c7deSRico Sonntag ->get() 1100892c7deSRico Sonntag ->all(); 1118add1155SRico Sonntag } 1128add1155SRico Sonntag 1138add1155SRico Sonntag /** 1148add1155SRico Sonntag * General query on ages at marriage. 1158add1155SRico Sonntag * 1168add1155SRico Sonntag * @return string 1178add1155SRico Sonntag */ 11888de55fdSRico Sonntag public function chartMarriageAge(): string 1198add1155SRico Sonntag { 1208add1155SRico Sonntag $out = []; 1218add1155SRico Sonntag 1220892c7deSRico Sonntag foreach ($this->queryRecords() as $record) { 12388de55fdSRico Sonntag $out[(int) $record->century][$record->sex] = (float) $record->age; 1248add1155SRico Sonntag } 1258add1155SRico Sonntag 12688de55fdSRico Sonntag $data = [ 12788de55fdSRico Sonntag [ 12888de55fdSRico Sonntag I18N::translate('Century'), 12988de55fdSRico Sonntag I18N::translate('Males'), 13088de55fdSRico Sonntag I18N::translate('Females'), 13188de55fdSRico Sonntag I18N::translate('Average age'), 13288de55fdSRico Sonntag ] 13388de55fdSRico Sonntag ]; 13488de55fdSRico Sonntag 1358add1155SRico Sonntag foreach ($out as $century => $values) { 13688de55fdSRico Sonntag $female_age = $values['F'] ?? 0; 13788de55fdSRico Sonntag $male_age = $values['M'] ?? 0; 13888de55fdSRico Sonntag $average_age = ($female_age + $male_age) / 2.0; 1398add1155SRico Sonntag 14088de55fdSRico Sonntag $data[] = [ 141*93ccd686SRico Sonntag $this->century_service->centuryName($century), 14288de55fdSRico Sonntag $male_age, 14388de55fdSRico Sonntag $female_age, 14488de55fdSRico Sonntag $average_age, 14588de55fdSRico Sonntag ]; 1468add1155SRico Sonntag } 1478add1155SRico Sonntag 1481b860509SRico Sonntag $chart_title = I18N::translate('Average age in century of marriage'); 1491b860509SRico Sonntag $chart_options = [ 1501b860509SRico Sonntag 'title' => $chart_title, 1511b860509SRico Sonntag 'subtitle' => I18N::translate('Average age at marriage'), 1521b860509SRico Sonntag 'vAxis' => [ 1531b860509SRico Sonntag 'title' => I18N::translate('Age'), 1541b860509SRico Sonntag ], 1551b860509SRico Sonntag 'hAxis' => [ 1561b860509SRico Sonntag 'title' => I18N::translate('Century'), 1571b860509SRico Sonntag ], 1581b860509SRico Sonntag 'colors' => [ 1591b860509SRico Sonntag '#84beff', 1601b860509SRico Sonntag '#ffd1dc', 1611b860509SRico Sonntag '#ff0000', 1621b860509SRico Sonntag ], 1631b860509SRico Sonntag ]; 1641b860509SRico Sonntag 1658add1155SRico Sonntag return view( 16688de55fdSRico Sonntag 'statistics/other/charts/combo', 1678add1155SRico Sonntag [ 16888de55fdSRico Sonntag 'data' => $data, 1691b860509SRico Sonntag 'chart_options' => $chart_options, 1701b860509SRico Sonntag 'chart_title' => $chart_title, 1718add1155SRico Sonntag ] 1728add1155SRico Sonntag ); 1738add1155SRico Sonntag } 1748add1155SRico Sonntag} 175