18add1155SRico Sonntag<?php 28add1155SRico Sonntag/** 38add1155SRico Sonntag * webtrees: online genealogy 48add1155SRico Sonntag * Copyright (C) 2018 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; 218add1155SRico Sonntaguse Fisharebest\Webtrees\Statistics\AbstractGoogle; 228add1155SRico Sonntaguse Fisharebest\Webtrees\Statistics\Helper\Century; 238add1155SRico Sonntaguse Fisharebest\Webtrees\Tree; 248add1155SRico Sonntaguse Illuminate\Database\Capsule\Manager as DB; 258add1155SRico Sonntaguse Illuminate\Database\Query\JoinClause; 268add1155SRico Sonntag 278add1155SRico Sonntag/** 288add1155SRico Sonntag * 298add1155SRico Sonntag */ 308add1155SRico Sonntagclass ChartNoChildrenFamilies extends AbstractGoogle 318add1155SRico Sonntag{ 328add1155SRico Sonntag /** 338add1155SRico Sonntag * @var Tree 348add1155SRico Sonntag */ 358add1155SRico Sonntag private $tree; 368add1155SRico Sonntag 378add1155SRico Sonntag /** 388add1155SRico Sonntag * @var Century 398add1155SRico Sonntag */ 408add1155SRico Sonntag private $centuryHelper; 418add1155SRico Sonntag 428add1155SRico Sonntag /** 438add1155SRico Sonntag * Constructor. 448add1155SRico Sonntag * 458add1155SRico Sonntag * @param Tree $tree 468add1155SRico Sonntag */ 478add1155SRico Sonntag public function __construct(Tree $tree) 488add1155SRico Sonntag { 498add1155SRico Sonntag $this->tree = $tree; 508add1155SRico Sonntag $this->centuryHelper = new Century(); 518add1155SRico Sonntag } 528add1155SRico Sonntag 538add1155SRico Sonntag /** 548add1155SRico Sonntag * Returns the related database records. 558add1155SRico Sonntag * 568add1155SRico Sonntag * @param int $year1 578add1155SRico Sonntag * @param int $year2 588add1155SRico Sonntag * 598add1155SRico Sonntag * @return \stdClass[] 608add1155SRico Sonntag */ 618add1155SRico Sonntag private function queryRecords(int $year1, int $year2): array 628add1155SRico Sonntag { 638add1155SRico Sonntag $query = DB::table('families') 64*3dc8167dSGreg Roach ->selectRaw('ROUND((d_year - 50) / 100) AS century') 658add1155SRico Sonntag ->selectRaw('COUNT(*) AS count') 668add1155SRico Sonntag ->join('dates', function (JoinClause $join) { 678add1155SRico Sonntag $join->on('d_file', '=', 'f_file') 688add1155SRico Sonntag ->on('d_gid', '=', 'f_id'); 698add1155SRico Sonntag }) 708add1155SRico Sonntag ->where('f_file', '=', $this->tree->id()) 718add1155SRico Sonntag ->where('f_numchil', '=', 0) 728add1155SRico Sonntag ->where('d_fact', '=', 'MARR') 738add1155SRico Sonntag ->whereIn('d_type', ['@#DGREGORIAN@', '@#DJULIAN@']) 748add1155SRico Sonntag ->groupBy(['century']) 758add1155SRico Sonntag ->orderBy('century'); 768add1155SRico Sonntag 778add1155SRico Sonntag if ($year1 >= 0 && $year2 >= 0) { 788add1155SRico Sonntag $query->whereBetween('d_year', [$year1, $year2]); 798add1155SRico Sonntag } 808add1155SRico Sonntag 818add1155SRico Sonntag return $query->get()->all(); 828add1155SRico Sonntag } 838add1155SRico Sonntag 848add1155SRico Sonntag /** 858add1155SRico Sonntag * Create a chart of children with no families. 868add1155SRico Sonntag * 878add1155SRico Sonntag * @param int $no_child_fam The number of families with no children 888add1155SRico Sonntag * @param string $size 898add1155SRico Sonntag * @param int $year1 908add1155SRico Sonntag * @param int $year2 918add1155SRico Sonntag * 928add1155SRico Sonntag * @return string 938add1155SRico Sonntag */ 948add1155SRico Sonntag public function chartNoChildrenFamilies( 958add1155SRico Sonntag int $no_child_fam, 968add1155SRico Sonntag string $size = '220x200', 978add1155SRico Sonntag int $year1 = -1, 988add1155SRico Sonntag int $year2 = -1 998add1155SRico Sonntag ): string { 1008add1155SRico Sonntag $sizes = explode('x', $size); 1018add1155SRico Sonntag $max = 0; 1028add1155SRico Sonntag $tot = 0; 1038add1155SRico Sonntag $rows = $this->queryRecords($year1, $year2); 1048add1155SRico Sonntag 1058add1155SRico Sonntag if (empty($rows)) { 1068add1155SRico Sonntag return ''; 1078add1155SRico Sonntag } 1088add1155SRico Sonntag 1098add1155SRico Sonntag foreach ($rows as $values) { 1108add1155SRico Sonntag $values->count = (int) $values->count; 1118add1155SRico Sonntag 1128add1155SRico Sonntag if ($max < $values->count) { 1138add1155SRico Sonntag $max = $values->count; 1148add1155SRico Sonntag } 1158add1155SRico Sonntag $tot += $values->count; 1168add1155SRico Sonntag } 1178add1155SRico Sonntag 1188add1155SRico Sonntag $unknown = $no_child_fam - $tot; 1198add1155SRico Sonntag 1208add1155SRico Sonntag if ($unknown > $max) { 1218add1155SRico Sonntag $max = $unknown; 1228add1155SRico Sonntag } 1238add1155SRico Sonntag 1248add1155SRico Sonntag $chm = ''; 1258add1155SRico Sonntag $chxl = '0:|'; 1268add1155SRico Sonntag $i = 0; 1278add1155SRico Sonntag $counts = []; 1288add1155SRico Sonntag 1298add1155SRico Sonntag foreach ($rows as $values) { 1308add1155SRico Sonntag $chxl .= $this->centuryHelper->centuryName((int) $values->century) . '|'; 1318add1155SRico Sonntag $counts[] = intdiv(4095 * $values->count, $max + 1); 1328add1155SRico Sonntag $chm .= 't' . $values->count . ',000000,0,' . $i . ',11,1|'; 1338add1155SRico Sonntag $i++; 1348add1155SRico Sonntag } 1358add1155SRico Sonntag 1368add1155SRico Sonntag $counts[] = intdiv(4095 * $unknown, $max + 1); 1378add1155SRico Sonntag $chd = $this->arrayToExtendedEncoding($counts); 1388add1155SRico Sonntag $chm .= 't' . $unknown . ',000000,0,' . $i . ',11,1'; 1398add1155SRico Sonntag $chxl .= I18N::translateContext('unknown century', 'Unknown') . '|1:||' . I18N::translate('century') . '|2:|0|'; 1408add1155SRico Sonntag $step = $max + 1; 1418add1155SRico Sonntag 1428add1155SRico Sonntag for ($d = ($max + 1); $d > 0; $d--) { 1438add1155SRico Sonntag if (($max + 1) < ($d * 10 + 1) && fmod($max + 1, $d) === 0) { 1448add1155SRico Sonntag $step = $d; 1458add1155SRico Sonntag } 1468add1155SRico Sonntag } 1478add1155SRico Sonntag 1488add1155SRico Sonntag if ($step === ($max + 1)) { 1498add1155SRico Sonntag for ($d = $max; $d > 0; $d--) { 1508add1155SRico Sonntag if ($max < ($d * 10 + 1) && fmod($max, $d) === 0) { 1518add1155SRico Sonntag $step = $d; 1528add1155SRico Sonntag } 1538add1155SRico Sonntag } 1548add1155SRico Sonntag } 1558add1155SRico Sonntag 1568add1155SRico Sonntag for ($n = $step; $n <= ($max + 1); $n += $step) { 1578add1155SRico Sonntag $chxl .= $n . '|'; 1588add1155SRico Sonntag } 1598add1155SRico Sonntag 1608add1155SRico Sonntag $chxl .= '3:||' . I18N::translate('Total families') . '|'; 1618add1155SRico Sonntag 1628add1155SRico Sonntag $chart_url = 'https://chart.googleapis.com/chart?cht=bvg&chs=' . $sizes[0] . 'x' . $sizes[1] 1638add1155SRico Sonntag . '&chf=bg,s,ffffff00|c,s,ffffff00&chm=D,FF0000,0,0:' 1648add1155SRico Sonntag . ($i - 1) . ',3,1|' . $chm . '&chd=e:' 1658add1155SRico Sonntag . $chd . '&chco=0000FF,ffffff00&chbh=30,3&chxt=x,x,y,y&chxl=' 1668add1155SRico Sonntag . rawurlencode($chxl); 1678add1155SRico Sonntag 1688add1155SRico Sonntag return view( 1698add1155SRico Sonntag 'statistics/other/chart-google', 1708add1155SRico Sonntag [ 1718add1155SRico Sonntag 'chart_title' => I18N::translate('Number of families without children'), 1728add1155SRico Sonntag 'chart_url' => $chart_url, 1738add1155SRico Sonntag 'sizes' => $sizes, 1748add1155SRico Sonntag ] 1758add1155SRico Sonntag ); 1768add1155SRico Sonntag } 1778add1155SRico Sonntag} 178