xref: /webtrees/app/Statistics/Google/ChartNoChildrenFamilies.php (revision 7ef421a4290b6b468944b845497d6139b0eddd3f)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2019 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Statistics\Google;
21
22use Fisharebest\Localization\Locale\LocaleInterface;
23use Fisharebest\Webtrees\I18N;
24use Fisharebest\Webtrees\Statistics\Service\CenturyService;
25use Fisharebest\Webtrees\Tree;
26use Illuminate\Database\Capsule\Manager as DB;
27use Illuminate\Database\Query\JoinClause;
28use Psr\Http\Message\ServerRequestInterface;
29use stdClass;
30
31use function app;
32use function assert;
33
34/**
35 * A chart showing the number of families with no children by century.
36 */
37class ChartNoChildrenFamilies
38{
39    /**
40     * @var Tree
41     */
42    private $tree;
43
44    /**
45     * @var CenturyService
46     */
47    private $century_service;
48
49    /**
50     * Constructor.
51     *
52     * @param Tree $tree
53     */
54    public function __construct(Tree $tree)
55    {
56        $this->tree            = $tree;
57        $this->century_service = new CenturyService();
58    }
59
60    /**
61     * Returns the related database records.
62     *
63     * @param int $year1
64     * @param int $year2
65     *
66     * @return stdClass[]
67     */
68    private function queryRecords(int $year1, int $year2): array
69    {
70        $query = DB::table('families')
71            ->selectRaw('ROUND((d_year + 49) / 100) AS century')
72            ->selectRaw('COUNT(*) AS total')
73            ->join('dates', static function (JoinClause $join): void {
74                $join->on('d_file', '=', 'f_file')
75                    ->on('d_gid', '=', 'f_id');
76            })
77            ->where('f_file', '=', $this->tree->id())
78            ->where('f_numchil', '=', 0)
79            ->where('d_fact', '=', 'MARR')
80            ->whereIn('d_type', ['@#DGREGORIAN@', '@#DJULIAN@'])
81            ->groupBy(['century'])
82            ->orderBy('century');
83
84        if ($year1 >= 0 && $year2 >= 0) {
85            $query->whereBetween('d_year', [$year1, $year2]);
86        }
87
88        return $query->get()->all();
89    }
90
91    /**
92     * Create a chart of children with no families.
93     *
94     * @param int $no_child_fam The number of families with no children
95     * @param int $year1
96     * @param int $year2
97     *
98     * @return string
99     */
100    public function chartNoChildrenFamilies(
101        int $no_child_fam,
102        int $year1 = -1,
103        int $year2 = -1
104    ): string {
105        $data = [
106            [
107                I18N::translate('Century'),
108                I18N::translate('Total')
109            ]
110        ];
111
112        $total = 0;
113
114        foreach ($this->queryRecords($year1, $year2) as $record) {
115            $total += $record->total;
116
117            $data[] = [
118                $this->century_service->centuryName((int) $record->century),
119                $record->total
120            ];
121        }
122
123        if ($total) {
124            $data[] = [
125                I18N::translateContext('unknown century', 'Unknown'),
126                $no_child_fam - $total
127            ];
128        }
129
130        $chart_title   = I18N::translate('Number of families without children');
131        $chart_options = [
132            'title' => $chart_title,
133            'subtitle' => '',
134            'legend' => [
135                'position'  => 'none',
136            ],
137            'vAxis' => [
138                'title' => I18N::translate('Total families'),
139            ],
140            'hAxis' => [
141                'title' => I18N::translate('Century'),
142            ],
143            'colors' => [
144                '#84beff'
145            ],
146        ];
147
148        $locale = app(ServerRequestInterface::class)->getAttribute('locale');
149        assert($locale instanceof LocaleInterface);
150
151        return view('statistics/other/charts/column', [
152            'data'          => $data,
153            'chart_options' => $chart_options,
154            'chart_title'   => $chart_title,
155            'language'      => $locale->languageTag(),
156        ]);
157    }
158}
159