1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2019 webtrees development team 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16declare(strict_types=1); 17 18namespace Fisharebest\Webtrees\Statistics\Google; 19 20use function count; 21use Fisharebest\Webtrees\I18N; 22use Fisharebest\Webtrees\Module\ModuleThemeInterface; 23use Fisharebest\Webtrees\Statistics\Service\ColorService; 24use Fisharebest\Webtrees\Tree; 25 26/** 27 * A chart showing the top surnames. 28 */ 29class ChartCommonSurname 30{ 31 /** 32 * @var ModuleThemeInterface 33 */ 34 private $theme; 35 36 /** 37 * @var string 38 */ 39 private $surname_tradition; 40 41 /** 42 * @var ColorService 43 */ 44 private $color_service; 45 46 /** 47 * Constructor. 48 * 49 * @param Tree $tree 50 */ 51 public function __construct(Tree $tree) 52 { 53 $this->theme = app(ModuleThemeInterface::class); 54 $this->surname_tradition = $tree->getPreference('SURNAME_TRADITION'); 55 $this->color_service = new ColorService(); 56 } 57 58 /** 59 * Count up the different versions of a name and returns the one with the most matches. Takes 60 * different surname traditions into account. 61 * 62 * @param array $surns 63 * 64 * @return array [ name, count ] 65 */ 66 private function getTopNameAndCount(array $surns): array 67 { 68 $max_name = 0; 69 $count_per = 0; 70 $top_name = ''; 71 72 foreach ($surns as $spfxsurn => $count) { 73 $per = $count; 74 $count_per += $per; 75 76 // select most common surname from all variants 77 if ($per > $max_name) { 78 $max_name = $per; 79 $top_name = $spfxsurn; 80 } 81 } 82 83 if ($this->surname_tradition === 'polish') { 84 // Most common surname should be in male variant (Kowalski, not Kowalska) 85 $top_name = preg_replace( 86 [ 87 '/ska$/', 88 '/cka$/', 89 '/dzka$/', 90 '/żka$/', 91 ], 92 [ 93 'ski', 94 'cki', 95 'dzki', 96 'żki', 97 ], 98 $top_name 99 ); 100 } 101 102 return [ 103 $top_name, 104 $count_per 105 ]; 106 } 107 108 /** 109 * Create a chart of common surnames. 110 * 111 * @param int $tot_indi The total number of individuals 112 * @param array $all_surnames The list of common surnames 113 * @param string|null $color_from 114 * @param string|null $color_to 115 * 116 * @return string 117 */ 118 public function chartCommonSurnames( 119 int $tot_indi, 120 array $all_surnames, 121 string $color_from = null, 122 string $color_to = null 123 ): string { 124 $chart_color1 = (string) $this->theme->parameter('distribution-chart-no-values'); 125 $chart_color2 = (string) $this->theme->parameter('distribution-chart-high-values'); 126 $color_from = $color_from ?? $chart_color1; 127 $color_to = $color_to ?? $chart_color2; 128 129 $tot = 0; 130 foreach ($all_surnames as $surn => $surnames) { 131 $tot += array_sum($surnames); 132 } 133 134 $data = [ 135 [ 136 I18N::translate('Name'), 137 I18N::translate('Total') 138 ], 139 ]; 140 141 foreach ($all_surnames as $surns) { 142 $data[] = $this->getTopNameAndCount($surns); 143 } 144 145 $data[] = [ 146 I18N::translate('Other'), 147 $tot_indi - $tot 148 ]; 149 150 $colors = $this->color_service->interpolateRgb($color_from, $color_to, count($data) - 1); 151 152 return view( 153 'statistics/other/charts/pie', 154 [ 155 'title' => null, 156 'data' => $data, 157 'colors' => $colors, 158 ] 159 ); 160 } 161} 162