auto_complete); unset($data->expanded_folders); unset($data->file_history); unset($data->find_state->find_history); foreach ($data->groups as &$group) { foreach ($group->sheets as &$sheet) foreach (array ( 'selection', 'translation.x', 'translation.y', ) as $property) { unset($sheet->settings->$property); } } file_put_contents($file, str_replace("\n", PHP_EOL, str_replace(array("\r\n", "\r"), "\n", preg_replace(array_keys($map = array ( '/^(\t*)("[^"]+":) ([{[])/m' => '\1\2'."\n".'\1\3', '/^(\t*)\[]/m' => '\1['."\n".'\1]', '/^(\t*)\{}/m' => '\1{'."\n".'\1}', ) ), array_values($map), preg_replace_callback('/^ +/m', function ($match) { return str_replace(' ', "\t", $match[0]); } , json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION)))))); } $file = substr(__FILE__, 0, -3).'sublime-workspace'; if (true === is_file($file)) { sublime_normalize_workspace($file); } // https://www.insee.fr/fr/information/4190491 foreach (array ( array('7ed71ef5f78579e05d77e50bed090cb169852bda', '2010-01-01', '2018-12-31', 'https://www.insee.fr/fr/statistiques/fichier/4769950/deces-2010-2018-csv.zip'), array('24a1e0fef31c5ad5c7eed1a00c954259909158d4', '2018-01-01', '2018-12-31', 'https://www.insee.fr/fr/statistiques/fichier/4190491/Deces_2018.zip'), array('d32de660b525422907ed938d31a1cd525e69c705', '2019-01-01', '2019-12-31', 'https://www.insee.fr/fr/statistiques/fichier/4190491/Deces_2019.zip'), array('b9625e7ea21b7224084d18328a2ed7a22ee3cb17', '2020-01-01', '2020-12-31', 'https://www.insee.fr/fr/statistiques/fichier/4190491/Deces_2020.zip'), array('1f599e2852b3def54e80e082b8f4827677172322', '2021-01-01', '2021-01-31', 'https://www.insee.fr/fr/statistiques/fichier/4190491/Deces_2021_M01.zip'), ) as $file) { list($hash, $begin, $end, $source) = $file; $target = substr(__FILE__, 0, -4).'-2-'.$begin.'-'.$end.'.zip'; if (true !== is_file($target)) { echo 'download archive from ', $begin, ' to ', $end, PHP_EOL; $content = file_get_contents($source); assert(true === is_string($content)); assert(sha1($content) === $hash); $result = file_put_contents($target, $content); assert(strlen($content) === $result); assert(true === is_file($target)); assert(strlen($content) === filesize($target)); } } foreach (array ( array('e1534a56eab1573b0105d68976f1ad12ccf0fbf3', '2010-01-01', '2010-12-31', '2010-01-01-2018-12-31', 'deces-2010'), array('cc2f5ac5032995b174bd4ac4d0c7bdffb1308d2c', '2011-01-01', '2011-12-31', '2010-01-01-2018-12-31', 'deces-2011'), array('ecf924ab4be6f27b78f10fa04522f3393ade059f', '2012-01-01', '2012-12-31', '2010-01-01-2018-12-31', 'deces-2012'), array('b7cb22efe9783b7d777b8d5fd02545218641c3c9', '2013-01-01', '2013-12-31', '2010-01-01-2018-12-31', 'deces-2013'), array('d4c543359d6ff25fb500a09314f7a10c73accff6', '2014-01-01', '2014-12-31', '2010-01-01-2018-12-31', 'deces-2014'), array('a3ffdd5510042aa1b3173706a491a66b69679e45', '2015-01-01', '2015-12-31', '2010-01-01-2018-12-31', 'deces-2015'), array('9ed276678a94856801685e0cbab20a2d4d15f170', '2016-01-01', '2016-12-31', '2010-01-01-2018-12-31', 'deces-2016'), array('717ff6411ad28618fc07f418d7cc166930fefc30', '2017-01-01', '2017-12-31', '2010-01-01-2018-12-31', 'deces-2017'), array('e072fbb64b928d01fd355dee5507153c2e0d6700', '2018-01-01', '2018-12-31', '2018-01-01-2018-12-31', 'deces-2018'), array('3ba9419aff67752acd7e91fa61a6afb6ad4a6aab', '2019-01-01', '2019-12-31', '2019-01-01-2019-12-31', 'deces-2019'), array('0e7c6ff2d4b6a2efef399a9d031fcb23810fa41e', '2020-01-01', '2020-12-31', '2020-01-01-2020-12-31', 'deces_2020'), array('3231cf18ec319afb8a13c962ddb0f520ba7a6293', '2021-01-01', '2021-01-31', '2021-01-01-2021-01-31', 'Deces_2021_M01'), ) as $file) { list($hash, $begin, $end, $archive, $name) = $file; $target = substr(__FILE__, 0, -4).'-3-'.$begin.'-'.$end.'.csv'; if (true !== is_file($target)) { echo 'extract data from ', $begin, ' to ', $end, PHP_EOL; $source = substr(__FILE__, 0, -4).'-2-'.$archive.'.zip'; assert(true === is_file($source)); $zip = new ZipArchive(); assert(true === is_object($zip)); assert('ZipArchive' === get_class($zip)); assert('fbe34874de4c3b1729f048eb50447b773cddb2d5' === sha1(serialize($zip))); $result = $zip->open($source); assert(true === $result); assert($zip->filename === $source); $name .= '.csv'; $entry = $zip->statName($name); assert(true === is_array($entry)); assert($entry['name'] === $name); $content = $zip->getFromName($name); assert(strlen($content) === $entry['size']); assert(sha1($content) === $hash); $result = file_put_contents($target, $content); assert(strlen($content) === $result); assert(true === is_file($target)); $result = $zip->close(); assert(true === $result); assert('fbe34874de4c3b1729f048eb50447b773cddb2d5' === sha1(serialize($zip))); } } $target = substr(__FILE__, 0, -4).'-4.txt'; if (true !== is_file($target)) { $year_map = array(); foreach (array ( array('2010-01-01', '2010-12-31'), array('2011-01-01', '2011-12-31'), array('2012-01-01', '2012-12-31'), array('2013-01-01', '2013-12-31'), array('2014-01-01', '2014-12-31'), array('2015-01-01', '2015-12-31'), array('2016-01-01', '2016-12-31'), array('2017-01-01', '2017-12-31'), array('2018-01-01', '2018-12-31'), array('2019-01-01', '2019-12-31'), array('2020-01-01', '2020-12-31'), array('2021-01-01', '2021-01-31'), ) as $file) { list($begin, $end) = $file; echo 'reading data from ', $begin, ' to ', $end, PHP_EOL; $line_list = explode("\r\n", file_get_contents(substr(__FILE__, 0, -4).'-3-'.$begin.'-'.$end.'.csv')); $line = array_shift($line_list); assert('"nomprenom";"sexe";"datenaiss";"lieunaiss";"commnaiss";"paysnaiss";"datedeces";"lieudeces";"actedeces"' === $line); $line = array_pop($line_list); assert('' === $line); foreach ($line_list as $line) { assert('"' === $line[0]); assert('"' === substr($line, -1)); $line = explode('";"', substr($line, 1, -1)); assert(9 === count($line)); assert(1 === preg_match('/^[0-9]{4}[012][0-9][0123][0-9]$/', $line[2])); assert(1 === preg_match('/^[0-9]{4}[012][0-9]/', $line[6])); $code = strtolower(substr($line[7], 0, 2)); assert(1 === preg_match('/^(?:|2[ab]|[0-9]{2})$/', $code)); if (!(('2a' === $code) || ('2b' === $code) || ('' === $code))) { $code = (int)$code; assert((0 < $code) && ($code < 100)); } ++$year_map[(int)(substr($line[6], 0, 4))][(int)(substr($line[6], 4, 2))][(int)(substr($line[6], 6, 2))][$line[7]]; } } ksort($year_map); foreach ($year_map as $year => $month_map) { ksort($year_map[$year]); foreach ($month_map as $month => $day_map) { ksort($year_map[$year][$month]); foreach (array_keys($day_map) as $day) { ksort($year_map[$year][$month][$day]); } } } $content = serialize($year_map); assert('4a85dc1e2b48b55d1005167a263ba4c5949771f7' === sha1($content)); $result = file_put_contents($target, $content); assert(strlen($content) === $result); assert(true === is_file($target)); assert(strlen($content) === filesize($target)); } function render_table($target, $year_map, $filter = '', $template_map = array()) { assert(true === is_string($target)); assert(true === is_array($year_map)); assert(true === is_string($filter)); assert(true === is_array($template_map)); echo 'rendering 2017-01-01 to 2020-12-31 ', str_replace('-', ' ', substr($target, strlen(__FILE__) - 1, -4)), PHP_EOL; if (array() !== $template_map) { $template_total = array(); $template_subtotal = array(); foreach ($template_map as $template_month => $template_list) { if (true === in_array($template_month, array('total', 'subtotal'), true)) { continue; } foreach ($template_list as $template_year => $template_count) { $template_total[$template_year] += $template_count; if ($template_month <= 9) { $template_subtotal[$template_year] += $template_count; } } } for ($template_year = 2017; $template_year <= 2020; ++$template_year) { $difference = $template_map['subtotal'][$template_year] - $template_subtotal[$template_year]; assert((0 <= $difference) && ($difference <= 10)); if (true === array_key_exists($template_year, $template_map['total'])) { $difference = $template_map['total'][$template_year] - $template_total[$template_year]; assert((0 <= $difference) && ($difference <= 15)); } } } $target_image = imagecreatefromjpeg(substr(__FILE__, 0, -4).'-1-template.jpg'); assert(true === is_resource($target_image)); assert('gd' === get_resource_type($target_image)); assert(true === imageistruecolor($target_image)); $render_image = imagecreatetruecolor(imagesx($target_image) << 2, imagesy($target_image) << 2); assert(true === is_resource($render_image)); assert('gd' === get_resource_type($render_image)); assert(true === imageistruecolor($render_image)); $result = imagealphablending($render_image, false); assert(true === $result); $result = imagefilledrectangle($render_image, 0, 0, imagesx($render_image) - 1, imagesy($render_image) - 1, 0x7FFF00FF); assert(true === $result); $result = imagealphablending($render_image, true); assert(true === $result); $render_font = str_replace('/', DIRECTORY_SEPARATOR, 'C:/Windows/Fonts/calibrib.ttf'); $result = imageantialias($render_image, true); assert(true === $result); $render_size = 48; $target_x = 122; foreach (array ( 2017 => array(87, 0x8899BB), 2018 => array(88, 0x444477), 2019 => array(87, 0x222233), 2020 => array(87, 0x000000), ) as $target_year => $target_list) { list($target_width, $render_color) = $target_list; $render_x = $target_x << 2; $render_width = $target_width << 2; $target_y = 276; foreach (array ( 1 => 18, 2 => 18, 3 => 19, 4 => 18, 5 => 18, 6 => 19, 7 => 18, 8 => 18, 9 => 18, 'subtotal' => 28, 10 => 33, 11 => 17, 12 => 17, 'total' => 17, ) as $target_month => $target_height) { if ('subtotal' === $target_month) { $render_begin = $target_year.'-01-01'; $render_end = $target_year.'-09-30'; } else if ('total' === $target_month) { $render_begin = $target_year.'-01-01'; $render_end = $target_year.'-12-31'; } else { $render_begin = $target_year.'-'.substr('0'.$target_month, -2).'-01'; $render_end = $target_year.'-'.substr('0'.$target_month, -2).'-31'; } $render_count = 0; foreach ($year_map as $source_year => $month_map) { foreach ($month_map as $source_month => $day_map) { foreach ($day_map as $source_day => $area_map) { $source_date = $source_year.'-'.substr('0'.$source_month, -2).'-'.substr('0'.$source_day, -2); if (($render_begin <= $source_date) && ($source_date <= $render_end)) { if ('' === $filter) { $render_count += array_sum($area_map); } else { foreach ($area_map as $area_code => $area_count) { if (0 === preg_match($filter, $area_code)) { $render_count += $area_count; } } } } } } } if (0 !== $render_count) { $text_color = $render_color; if (array() !== $template_map) { $template_count = 1; if ((true === array_key_exists($target_month, $template_map)) && (true === array_key_exists($target_year, $template_map[$target_month]))) { $template_count = max(1, $template_map[$target_month][$target_year]); } $error_ratio = $render_count / $template_count; if (($error_ratio < 0.95) || (1.05 < $error_ratio)) { $text_color = 0xFF0000; } } $render_text = number_format($render_count, 0, '.', ' '); $render_y = $target_y << 2; $render_height = $target_height << 2; $result = imagefilledrectangle($render_image, $render_x, $render_y, $render_x + $render_width - 1, $render_y + $render_height - 1, 0xFFFFFF); assert(true === $result); $text_box = imagettfbbox($render_size, 0, $render_font, $render_text); assert(true === is_array($text_box)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($text_box)); assert(array(true) === array_unique(array_map('is_integer', $text_box))); $text_width = max($text_box[0], $text_box[2], $text_box[4], $text_box[6]) - min($text_box[0], $text_box[2], $text_box[4], $text_box[6]); assert(0 < $text_width); $text_height = max($text_box[1], $text_box[3], $text_box[5], $text_box[7]) - min($text_box[1], $text_box[3], $text_box[5], $text_box[7]); assert(0 < $text_height); $text_x = $render_x + $render_width - $text_width - 24; $text_y = $render_y + $render_height - 8; if ('subtotal' === $month) { $text_y -= 12; } $result = imagettftext($render_image, $render_size, 0, $text_x, $text_y, $text_color, $render_font, $render_text); assert(true === is_array($result)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($result)); assert(array(true) === array_unique(array_map('is_integer', $result))); } $target_y += $target_height + 3; } $target_x += $target_width + 2; } $render_x = 32 << 2; $render_y = 597 << 2; $render_width = 446 << 2; $render_height = 24 << 2; $result = imagefilledrectangle($render_image, $render_x, $render_y, $render_x + $render_width - 1, $render_y + $render_height - 1, 0xFFFFFF); assert(true === $result); $result = imagettftext($render_image, 48, 0, $render_x + 8, $render_y + $render_height - 16, 0xBBAA99, $render_font, 'https://twitter.com/nicolaslegland/status/1320752230824366081'); assert(true === is_array($result)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($result)); assert(array(true) === array_unique(array_map('is_integer', $result))); $result = imagecopyresampled($target_image, $render_image, 0, 0, 0, 0, imagesx($target_image), imagesy($target_image), imagesx($render_image), imagesy($render_image)); assert(true === $result); assert(true === $result); $result = imagedestroy($render_image); assert(true === $result); $result = imagepng($target_image, $target, 9, PNG_ALL_FILTERS); assert(true === $result); assert(true === is_file($target)); $result = imagedestroy($target_image); assert(true === $result); } $year_map = unserialize(file_get_contents($target)); $target = substr(__FILE__, 0, -4).'-5-table-metropole.png'; if (true !== is_file($target)) { render_table($target, $year_map, '/^9[7-9]/'); assert('7165871b50ca1650152f6c7f1dab5197835450c4' === sha1_file($target)); } $target = substr(__FILE__, 0, -4).'-5-table-world.png'; if (true !== is_file($target)) { render_table($target, $year_map); assert('8f77f1820db6e4f2208c1c0243b21fe5a67b105b' === sha1_file($target)); } $target = substr(__FILE__, 0, -4).'-5-table-world-etchebest.png'; if (true !== is_file($target)) { render_table($target, $year_map, '', array ( 1 => array(2017 => 84917, 2018 => 79753, 2019 => 80155, 2020 => 73404), 2 => array(2017 => 53169, 2018 => 52819, 2019 => 56462, 2020 => 54805), 3 => array(2017 => 50817, 2018 => 61072, 2019 => 54331, 2020 => 60501), 4 => array(2017 => 47497, 2018 => 51008, 2019 => 49719, 2020 => 67213), 5 => array(2017 => 48910, 2018 => 48427, 2019 => 49672, 2020 => 49121), 6 => array(2017 => 44898, 2018 => 45568, 2019 => 46992, 2020 => 40069), 7 => array(2017 => 46818, 2018 => 48862, 2019 => 48670, 2020 => 47407), 8 => array(2017 => 47027, 2018 => 47761, 2019 => 47566, 2020 => 49171), 9 => array(2017 => 46504, 2018 => 46192, 2019 => 46796, 2020 => 40056), 'subtotal' => array(2017 => 470557, 2018 => 481462, 2019 => 480363, 2020 => 481747), 10 => array(2017 => 49625, 2018 => 50101, 2019 => 50503), 11 => array(2017 => 49659, 2018 => 49415, 2019 => 51812), 12 => array(2017 => 43186, 2018 => 39146, 2019 => 42694), 'total' => array(2017 => 613027, 2018 => 620124, 2019 => 625372), )); assert('979f97265197ce791e58806ea164d97a0b4dee2d' === sha1_file($target)); } $target = substr(__FILE__, 0, -4).'-5-table-world-december.png'; if (true !== is_file($target)) { render_table($target, $year_map, '', array ( 1 => array(2017 => 68969, 2018 => 60625, 2019 => 61210, 2020 => 58020), 2 => array(2017 => 53294, 2018 => 52911, 2019 => 56511, 2020 => 51975), 3 => array(2017 => 50965, 2018 => 61207, 2019 => 54393, 2020 => 63721), 4 => array(2017 => 47683, 2018 => 51121, 2019 => 49797, 2020 => 67538), 5 => array(2017 => 49113, 2018 => 48560, 2019 => 49757, 2020 => 49652), 6 => array(2017 => 45176, 2018 => 45702, 2019 => 47083, 2020 => 46770), 7 => array(2017 => 47146, 2018 => 49056, 2019 => 48834, 2020 => 47703), 8 => array(2017 => 47434, 2018 => 48039, 2019 => 47734, 2020 => 49781), 9 => array(2017 => 46925, 2018 => 46495, 2019 => 46828, 2020 => 49789), 'subtotal' => array(2017 => 456715, 2018 => 463726, 2019 => 462153, 2020 => 484955), 10 => array(2017 => 50255, 2018 => 50673, 2019 => 51061, 2021 => 58460), 11 => array(2017 => 50813, 2018 => 50438, 2019 => 52605, 2021 => 66169), 12 => array(2017 => 57793, 2018 => 53745, 2019 => 55660, 2021 => 53974), 'total' => array(2017 => 615578, 2018 => 618587, 2019 => 621482, 2021 => 663560), )); assert('bc2738adb15cc7396b48ca8f57e2682d472bab54' === sha1_file($target)); } function render_curve($year_map, $target, $step, $maximum, $smooth = false, $filter = '/^(?:$|[^9]|9[^7-9])/', $description = '') { assert(true === is_array($year_map)); assert(true === is_string($target)); assert(true === is_integer($step)); assert(true === is_integer($maximum)); assert(true === is_string($filter)); assert(true === is_string($description)); echo 'rendering 2010-01-01 to 2020-12-31 curve'; if ('' !== $description) { echo ' for ', preg_replace('/&([A-Za-z])(?:acute|circ|grave);/', '\1', $description); } if (true === $smooth) { echo ' smooth'; } echo PHP_EOL; $line_map = array(); foreach ($year_map as $year => $month_map) { if (($year < 2010) || (2020 < $year)) { continue; } $line_map[$year] = array(); foreach ($month_map as $month => $day_map) { if ($month < 1) { continue; } foreach ($day_map as $day => $area_map) { if ($day < 1) { continue; } $count = 0; foreach ($area_map as $area_code => $area_count) { if (1 === preg_match($filter, $area_code)) { $count += $area_count; } } $line_map[$year][] = $count; } } if (true === in_array($year, array(2012, 2016, 2020), true)) { assert(count($line_map[$year]) === 366); } else { assert(count($line_map[$year]) === 365); } } $target_width = 1024; $target_height = 512; $border_size = 0; $margin_size = 8; $padding_size = 0; $render_width = ($target_width - (2 * ($margin_size + $border_size + $padding_size))) * 16; $render_height = ($target_height - (2 * ($margin_size + $border_size + $padding_size))) * 16; $render_image = imagecreate($render_width, $render_height); assert(true === is_resource($render_image)); assert('gd' === get_resource_type($render_image)); assert(false === imageistruecolor($render_image)); for ($level = 0; 256 !== $level; ++$level) { $color = imagecolorallocate($render_image, $level, $level, $level); assert($level === $color); } $result = imagefilledrectangle($render_image, 0, 0, $render_width - 1, $render_height - 1, 255); assert(true === $result); for ($month = 2; $month <= 12; ++$month) { $x = (int)(round(((strtotime('1970-'.substr('0'.$month, -2).'-01') / 86400) * ($render_width - 1)) / 364)); $x = ($x >> 4) << 4; $result = imagefilledrectangle($render_image, $x - 16, 0, $x + 15, $render_height - 1, 0xEE); assert(true === $result); } $font = str_replace('/', DIRECTORY_SEPARATOR, 'C:/Windows/Fonts/calibrib.ttf'); $size = 160; for ($count = $step; $count <= $maximum; $count += $step) { $y = (int)(round((($maximum - $count) * ($render_height - 1)) / $maximum)); if ($count < $maximum) { $result = imagefilledrectangle($render_image, 0, $y - 16, $render_width - 1, $y + 15, 0xEE); assert(true === $result); } $result = imagettftext($render_image, $size, 0, 0, $y + $size + 32, 0x7F, $font, $count); assert(true === is_array($result)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($result)); assert(array(true) === array_unique(array_map('is_integer', $result))); } $y = imagesy($render_image) - 128; foreach (array_map('html_entity_decode', array ( 'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre', ) ) as $month => $text) { $x = (int)(round(((strtotime('1970-'.substr('0'.($month + 1), -2).'-01') / 86400) * ($render_width - 1)) / 364)) + 32; $result = imagettftext($render_image, $size, 0, $x, $y, 0x7F, $font, $text); assert(true === is_array($result)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($result)); assert(array(true) === array_unique(array_map('is_integer', $result))); } foreach (array ( 'https://twitter.com/nicolaslegland/status/1320752230824366081', 'https://www.insee.fr/fr/information/4190491', 'https://pastebin.com/s4VZwcYY', ) as $index => $text) { $text_box = imagettfbbox($size, 0, $font, $text); assert(true === is_array($text_box)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($text_box)); assert(array(true) === array_unique(array_map('is_integer', $text_box))); $text_width = max($text_box[0], $text_box[2], $text_box[4], $text_box[6]) - min($text_box[0], $text_box[2], $text_box[4], $text_box[6]); assert(0 < $text_width); $result = imagettftext($render_image, $size, 0, $render_width - $text_width - 32, 640 + (192 * $index), 0xBF, $font, $text); assert(true === is_array($result)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($result)); assert(array(true) === array_unique(array_map('is_integer', $result))); } $caption_x = 896; $caption_y = 192; $text = html_entity_decode('Décès quotidiens'); $text_box = imagettfbbox($size, 0, $font, $text); assert(true === is_array($text_box)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($text_box)); assert(array(true) === array_unique(array_map('is_integer', $text_box))); $text_width = max($text_box[0], $text_box[2], $text_box[4], $text_box[6]) - min($text_box[0], $text_box[2], $text_box[4], $text_box[6]); assert(0 < $text_width); $result = imagettftext($render_image, $size, 0, $caption_x, $caption_y, 0x7F, $font, $text); assert(true === is_array($result)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($result)); assert(array(true) === array_unique(array_map('is_integer', $result))); $text = '2010-2019'; $text_box = imagettfbbox($size, 0, $font, $text); assert(true === is_array($text_box)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($text_box)); assert(array(true) === array_unique(array_map('is_integer', $text_box))); $text_width = max($text_box[0], $text_box[2], $text_box[4], $text_box[6]) - min($text_box[0], $text_box[2], $text_box[4], $text_box[6]); assert(0 < $text_width); $result = imagettftext($render_image, $size, 0, $caption_x, $caption_y + 192, 0xBF, $font, $text); assert(true === is_array($result)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($result)); assert(array(true) === array_unique(array_map('is_integer', $result))); $caption_width = $text_width; for ($year = 2010; 2020 !== $year; ++$year) { $box_x = $caption_x + $caption_width + 128 + (($year - 2010) * 192); $box_color = 240 + (8 * (2010 - $year)); $result = imagefilledrectangle($render_image, $box_x, $caption_y + 64, $box_x + 127, $caption_y + 191, $box_color); assert(true === $result); } $text = '2020'; $text_box = imagettfbbox($size, 0, $font, $text); assert(true === is_array($text_box)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($text_box)); assert(array(true) === array_unique(array_map('is_integer', $text_box))); $text_width = max($text_box[0], $text_box[2], $text_box[4], $text_box[6]) - min($text_box[0], $text_box[2], $text_box[4], $text_box[6]); assert(0 < $text_width); $result = imagettftext($render_image, $size, 0, $caption_x + $caption_width - $text_width, $caption_y + 384, 0xBF, $font, $text); assert(true === is_array($result)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($result)); assert(array(true) === array_unique(array_map('is_integer', $result))); $box_x = $caption_x + $caption_width + 128; $result = imagefilledrectangle($render_image, $box_x, $caption_y + 256, $box_x + 127, $caption_y + 383, 0x00); assert(true === $result); $size = 320; if ('' === $description) { $text = 'France'; } else { $text = html_entity_decode($description); } $text_box = imagettfbbox($size, 0, $font, $text); assert(true === is_array($text_box)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($text_box)); assert(array(true) === array_unique(array_map('is_integer', $text_box))); $text_width = max($text_box[0], $text_box[2], $text_box[4], $text_box[6]) - min($text_box[0], $text_box[2], $text_box[4], $text_box[6]); assert(0 < $text_width); $result = imagettftext($render_image, $size, 0, $render_width - $text_width - 64, 384, 0x7F, $font, $text); assert(true === is_array($result)); assert(array(0, 1, 2, 3, 4, 5, 6, 7) === array_keys($result)); assert(array(true) === array_unique(array_map('is_integer', $result))); $result = imagesetthickness($render_image, 24); assert(true === $result); foreach ($line_map as $year => $point_map) { if (2020 === $year) { $color = 0; } else { $color = 240 + (8 * (2010 - $year)); } $length = count($point_map); $previous_x = null; $previous_y = null; foreach ($point_map as $index => $count) { if (true === $smooth) { $smooth_begin = $index - 3; $smooth_end = $index + 4; $smooth_total = 0; for ($smooth_index = $smooth_begin; $smooth_end !== $smooth_index; ++$smooth_index) { if ($smooth_index < 0) { $smooth_year = $year - 1; $smooth_day = count($line_map[$smooth_year]) + $smooth_index; } else if ($length <= $smooth_index) { $smooth_year = $year + 1; $smooth_day = $smooth_index - $length; } else { $smooth_year = $year; $smooth_day = $smooth_index; } if ((true === array_key_exists($smooth_year, $line_map)) && (true === array_key_exists($smooth_day, $line_map[$smooth_year]))) { $smooth_total += $line_map[$smooth_year][$smooth_day]; } else { assert(true === in_array($smooth_year, array(2009, 2021), true)); $smooth_total += $count; } } $count = $smooth_total / 7; } $x = (int)(round(($index * ($render_width - 1)) / ($length - 1))); $y = (int)(round((($maximum - $count) * ($render_height - 1)) / $maximum)); assert(0 <= $x); assert($x < $render_width); assert(0 <= $y); assert($y < $render_height); if (null === $previous_x) { assert(null === $previous_y); $previous_x = $x; $previous_y = $y; } else { assert(true === is_integer($previous_x)); assert(true === is_integer($previous_y)); imageline($render_image, $previous_x, $previous_y, $x, $y, $color); $previous_x = $x; $previous_y = $y; } } } $target_image = imagecreatetruecolor($target_width, $target_height); assert(true === is_resource($target_image)); assert('gd' === get_resource_type($target_image)); assert(true === imageistruecolor($target_image)); $result = imagefilledrectangle($target_image, 0, 0, $target_width - 1, $target_height - 1, 0xFFFFFF); assert(true === $result); $result = imagefilledrectangle($target_image, $margin_size, $margin_size, $target_width - $margin_size - 1, $target_height - $margin_size - 1, 0xEEEEEE); assert(true === $result); $result = imagefilledrectangle($target_image, $margin_size + $border_size, $margin_size + $border_size, $target_width - $margin_size - $border_size - 1, $target_height - $margin_size - $border_size - 1, 0xFFFFFF); assert(true === $result); $result = imagecopyresampled ( $target_image, $render_image, $margin_size + $border_size + $padding_size, $margin_size + $border_size + $padding_size, 0, 0, $target_width - (2 * ($margin_size + $border_size + $padding_size)), $target_height - (2 * ($margin_size + $border_size + $padding_size)), $render_width, $render_height ); assert(true === $result); $result = imagedestroy($render_image); assert(true === $result); $result = imagepng($target_image, $target, 9, PNG_ALL_FILTERS); assert(true === $result); assert(true === is_file($target)); $result = imagedestroy($target_image); assert(true === $result); } $target = substr(__FILE__, 0, -4).'-6-curve.png'; if (true !== is_file($target)) { render_curve($year_map, $target, 1000, 4000); assert('ecfffb289bc3566293253794e1ddd50a1b479728' === sha1_file($target)); } $target = substr(__FILE__, 0, -4).'-6-curve-smooth.png'; if (true !== is_file($target)) { render_curve($year_map, $target, 1000, 4000, true); assert('880231127a76b14831d2a923f5d8defd4bf40dee' === sha1_file($target)); } foreach (array ( array(7, 'cbc2436af126ec845d3a73c500480e7372eee7cb', '1566de136bbdf7c6b9d5738bf3a1f9f30639a88d', 50, 250, '/^(?:22|29|35|56)/', 'Bretagne'), array(7, 'aacd1fd074c2abbfeaa5abc4510d7a03e353048b', '3fc310ae037db308a0dfe8bcdd206467303032c2', 10, 40, '/^(?:2[AB])/', 'Corse'), array(7, '4f64f3f505165873a957ba56f15788628c3942d8', '9e17b840c0dfb07075c1ffa845894ab165bc0e68', 250, 1000, '/^(?:75|77|78|91|92|93|94|95)/', 'Île-de-France'), array(7, '100c84c8fc1f738899bc089b52982926d9b36ad9', '12146da9295b5ca72401d4c79954fbbd5ba623de', 50, 200, '/^(?:14|27|50|61|76)/', 'Normandie'), array(7, '7b02cdb74cd67dfaf9e061aad2844659ae6a8d3f', 'ca8ec1efaccb4ace8ba276f9082d088e3dd6e4cc', 100, 400, '/^(?:04|05|06|13|83|84)/', 'Provence-Alpes-Côte d\'Azur'), array(8, '0fa8c7a90ec44dfb8c3408a76a4a1978ae495f6f', 'a208fb3eb39ddb1a0c042a08ad60ca022d858799', 50, 200, '/^13/', 'Bouches-du-Rhône'), array(8, '4acf0cb6dde4a30e63ac9efbcb4c74ef0b309ac6', '1ccc54797ab6539788743e52533c08e2a55f1581', 25, 100, '/^35/', 'Ille-et-Vilaine'), array(8, '6d46d2e8da152dd7f934ffb9f1f359a44e5f4957', '43d8ec96f53446191c67c0b218c212404b9a3b62', 25, 100, '/^57/', 'Moselle'), array(8, '4e685ef8eeb0d97f3da4c158bdc76fa0d785f0e7', '98b6dfe0c855208b20dcc0126af313201335eabd', 25, 100, '/^68/', 'Haut-Rhin'), array(9, 'a0a5147ad958f1d76ab9820d50ae42dc5a683d17', '78b67c3d0774875cba36d0c7907d054c1809bf09', 10, 50, '/^69(?:00[1-9]|123|38[1-9])$/', 'Lyon'), array(9, '380e78d3e9b0f2a4b67360537d3e0c5a79ad53ba', '2e22d83bf4ee078ab94021ddf526f198cc77aaee', 10, 40, '/^130(?:0[1-9]|1[0-6])$/', 'Marseille'), array(9, '75d405c7ffde8725129bb1abda1de4bdba740771', 'f651bc1f2328e6877f85b0305a2f4773e24547ad', 50, 200, '/^75/', 'Paris'), array(9, 'f1d7eb39494aaa421cfc507c26720a065ca7bb6d', '8d8a06262fa2d47c3503a053b99bbfb7144e5042', 10, 30, '/^35(?:[027]00|238)$/', 'Rennes'), ) as $list) { list($group, $hash_sharp, $hash_smooth, $step, $maximum, $filter, $description) = $list; $name = strtolower(preg_replace('/&([A-Za-z])(?:acute|circ);/', '\1', $description)); $target = substr(__FILE__, 0, -4).'-'.$group.'-curve-'.$name.'.png'; if (true !== is_file($target)) { render_curve($year_map, $target, $step, $maximum, false, $filter, $description); assert($hash_sharp === sha1_file($target)); } $target = substr(__FILE__, 0, -4).'-'.$group.'-curve-'.$name.'-smooth.png'; if (true !== is_file($target)) { render_curve($year_map, $target, $step, $maximum, true, $filter, $description); assert($hash_smooth === sha1_file($target)); } }