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\Webtrees\I18N; 23use Fisharebest\Webtrees\Module\ModuleThemeInterface; 24use Fisharebest\Webtrees\Statistics\Service\ColorService; 25use Fisharebest\Webtrees\Tree; 26 27use function count; 28 29/** 30 * A chart showing the top surnames. 31 */ 32class ChartCommonSurname 33{ 34 /** 35 * @var ModuleThemeInterface 36 */ 37 private $theme; 38 39 /** 40 * @var string 41 */ 42 private $surname_tradition; 43 44 /** 45 * @var ColorService 46 */ 47 private $color_service; 48 49 /** 50 * Constructor. 51 * 52 * @param Tree $tree 53 */ 54 public function __construct(Tree $tree) 55 { 56 $this->theme = app(ModuleThemeInterface::class); 57 $this->surname_tradition = $tree->getPreference('SURNAME_TRADITION'); 58 $this->color_service = new ColorService(); 59 } 60 61 /** 62 * Count up the different versions of a name and returns the one with the most matches. Takes 63 * different surname traditions into account. 64 * 65 * @param array $surns 66 * 67 * @return array [ name, count ] 68 */ 69 private function getTopNameAndCount(array $surns): array 70 { 71 $max_name = 0; 72 $count_per = 0; 73 $top_name = ''; 74 75 foreach ($surns as $spfxsurn => $count) { 76 $per = $count; 77 $count_per += $per; 78 79 // select most common surname from all variants 80 if ($per > $max_name) { 81 $max_name = $per; 82 $top_name = $spfxsurn; 83 } 84 } 85 86 if ($this->surname_tradition === 'polish') { 87 // Most common surname should be in male variant (Kowalski, not Kowalska) 88 $top_name = preg_replace( 89 [ 90 '/ska$/', 91 '/cka$/', 92 '/dzka$/', 93 '/żka$/', 94 ], 95 [ 96 'ski', 97 'cki', 98 'dzki', 99 'żki', 100 ], 101 $top_name 102 ); 103 } 104 105 return [ 106 $top_name, 107 $count_per 108 ]; 109 } 110 111 /** 112 * Create a chart of common surnames. 113 * 114 * @param int $tot_indi The total number of individuals 115 * @param array $all_surnames The list of common surnames 116 * @param string|null $color_from 117 * @param string|null $color_to 118 * 119 * @return string 120 */ 121 public function chartCommonSurnames( 122 int $tot_indi, 123 array $all_surnames, 124 string $color_from = null, 125 string $color_to = null 126 ): string { 127 $chart_color1 = (string) $this->theme->parameter('distribution-chart-no-values'); 128 $chart_color2 = (string) $this->theme->parameter('distribution-chart-high-values'); 129 $color_from = $color_from ?? $chart_color1; 130 $color_to = $color_to ?? $chart_color2; 131 132 $tot = 0; 133 foreach ($all_surnames as $surn => $surnames) { 134 $tot += array_sum($surnames); 135 } 136 137 $data = [ 138 [ 139 I18N::translate('Name'), 140 I18N::translate('Total') 141 ], 142 ]; 143 144 foreach ($all_surnames as $surns) { 145 $data[] = $this->getTopNameAndCount($surns); 146 } 147 148 $data[] = [ 149 I18N::translate('Other'), 150 $tot_indi - $tot 151 ]; 152 153 $colors = $this->color_service->interpolateRgb($color_from, $color_to, count($data) - 1); 154 155 return view( 156 'statistics/other/charts/pie', 157 [ 158 'title' => null, 159 'data' => $data, 160 'colors' => $colors, 161 ] 162 ); 163 } 164} 165