Skip to content

Instantly share code, notes, and snippets.

@renecnielsen
Created March 1, 2017 09:39
Show Gist options
  • Save renecnielsen/1d6e242aeab533c856301c831051bb48 to your computer and use it in GitHub Desktop.
Save renecnielsen/1d6e242aeab533c856301c831051bb48 to your computer and use it in GitHub Desktop.
annotate a map
license: mit
Country Code Urban Agglomeration Latitude Longitude 2015 2030
4.0 Herat 34.34817 62.19967 337.381 564.793
4.0 Kabul 34.528887 69.17246 4634.875 8279.607
4.0 Kandahar 31.61332 65.71013 428.849 717.068
8.0 Tiranë (Tirana) 41.3275 19.81889 453.509 601.109
12.0 Annaba 36.9 7.76667 351.556 456.78
12.0 Batna 35.55597 6.17414 307.101 416.594
12.0 Blida 36.480781 2.831943 409.22 587.237
12.0 El Djazaïr (Algiers) 36.7525 3.04197 2594.112 3404.575
12.0 El Djelfa 34.67279 3.263 388.35 612.107
12.0 Qacentina 36.354921 6.607293 427.085 531.563
12.0 Wahran (Oran) 35.69111 -0.64167 858.272 1126.731
24.0 Huambo -12.77611 15.73917 1269.211 2536.751
24.0 Luanda -8.83682 13.23432 5506.0 10428.756
24.0 Lubango -14.91717 13.4925 370.679 751.231
32.0 Bahia Blanca -38.7196 -62.27243 324.95 388.376
32.0 Buenos Aires -34.605083 -58.400368 15180.176 16956.491
32.0 Córdoba -31.4135 -64.18105 1510.913 1718.192
32.0 Corrientes -27.4806 -58.8341 383.774 459.276
32.0 La Plata -34.92145 -57.95453 846.133 1005.537
32.0 Mar Del Plata -38.00228 -57.55754 649.51 767.788
32.0 Mendoza -32.89084 -68.82717 1009.4 1181.223
32.0 Neuquén-Plottier-Cipolletti -38.95143 -68.064809 365.588 442.502
32.0 Posadas -27.36708 -55.89608 317.268 373.675
32.0 Resistencia -27.46056 -58.98389 413.843 487.309
32.0 Rosario -32.94682 -60.63932 1380.918 1606.993
32.0 Salta -24.7859 -65.41166 579.209 692.156
32.0 San Juan -31.5375 -68.53639 497.081 587.513
32.0 San Miguel de Tucumán -26.82414 -65.2226 910.069 1077.952
32.0 San Salvador de Jujuy -24.19456 -65.29712 330.348 394.037
32.0 Santa Fe -31.632717 -60.698281 791.698 990.313
32.0 Santiago Del Estero -27.79511 -64.26149 397.483 475.441
51.0 Yerevan 40.181998 44.514619 1044.443 1057.459
36.0 Adelaide -34.92866 138.59863 1255.516 1505.422
36.0 Brisbane -27.46794 153.02809 2201.93 2721.325
36.0 Canberra -35.28346 149.12807 422.674 542.789
36.0 Gold Coast -28.00029 153.43088 588.415 774.964
36.0 Melbourne -37.814 144.96332 4203.416 5070.873
36.0 Newcastle and Lake Macquarie -32.924878 151.740852 372.633 463.098
36.0 Perth -31.947841 115.852514 1861.108 2329.184
36.0 Sunshine Coast -26.66008 153.09953 347.963 454.005
36.0 Sydney -33.86785 151.20732 4505.341 5300.933
40.0 Wien (Vienna) 48.206443 16.370725 1752.845 1959.109
31.0 Baku 40.37767 49.89201 2373.633 2971.498
31.0 Gäncä 40.68278 46.36056 323.755 382.171
31.0 Sumquayit 40.58972 49.66861 329.9 397.499
48.0 Al-Manamah (Manama) 26.21536 50.5832 411.162 549.834
50.0 Barisal 22.70194 90.37111 408.041 652.917
50.0 Bogra 24.85 89.36667 564.254 1014.827
50.0 Chittagong 22.33306 91.83639 4539.393 6718.801
50.0 Comilla 23.45778 91.20444 493.473 792.663
50.0 Dhaka 23.7104 90.40744 17598.228 27373.593
50.0 Khulna 22.80978 89.56439 1021.903 1336.055
50.0 Mymensingh 24.75 90.4 429.416 632.8
50.0 Rajshahi 24.36667 88.6 844.15 1240.216
50.0 Rangpur 25.75 89.25 370.28 557.896
50.0 Sylhet 24.89667 91.87167 671.646 1130.478
112.0 Brest 52.09755 23.68775 320.759 336.696
112.0 Gomel 52.4345 30.9754 483.093 490.845
112.0 Grodno 53.6884 23.8258 339.811 356.705
112.0 Minsk 53.9 27.56667 1915.396 1941.714
112.0 Mogilev 53.9141 30.33764 350.842 316.223
112.0 Vitebsk 55.19048 30.2033 352.743 364.13
56.0 Antwerpen 51.21989 4.40346 993.511 1067.865
56.0 Bruxelles-Brussel 50.846735 4.349919 2044.993 2202.566
56.0 Charleroi 50.41136 4.44448 392.863 422.624
56.0 Gent 51.05 3.71667 435.341 476.873
56.0 Liège 50.63373 5.56749 660.055 708.975
204.0 Abomey-Calavi 6.44852 2.35566 756.605 1407.379
204.0 Cotonou 6.36536 2.41833 682.459 979.379
68.0 Cochabamba -17.3895 -66.1568 1240.363 1703.163
68.0 La Paz -16.5 -68.15 1816.453 2308.274
68.0 Santa Cruz -17.79891 -63.169825 2106.682 2989.471
68.0 Sucre -19.03332 -65.26274 371.933 541.745
70.0 Sarajevo 43.84864 18.35644 318.447 338.554
76.0 Anápolis -16.32667 -48.95278 346.538 409.648
76.0 Aracaju -10.91111 -37.07167 825.267 996.902
76.0 Baixada Santista -23.957 -46.326609 1538.531 1768.738
76.0 Bauru -22.31472 -49.06056 351.747 411.239
76.0 Belém -1.456142 -48.478988 2181.607 2540.446
76.0 Belo Horizonte -19.92083 -43.93778 5716.422 6438.83
76.0 Blumenau -26.91944 -49.06611 318.979 385.704
76.0 Boa Vista 2.81972 -60.67333 330.735 431.688
76.0 Brasília -15.77972 -47.92972 4155.476 4929.044
76.0 Campina Grande -7.23056 -35.88111 386.405 455.263
76.0 Campinas -22.910942 -47.065587 3047.102 3559.55
76.0 Campo Grande -20.456697 -54.618515 840.612 999.798
76.0 Campos dos Goytacazes -21.766369 -41.319567 447.129 531.712
76.0 Caruaru -8.28333 -35.97611 315.315 394.289
76.0 Caxias Do Sul -29.16806 -51.17944 467.097 574.196
76.0 Cuiabá -15.59611 -56.09667 586.07 691.316
76.0 Curitiba -25.42778 -49.27306 3473.681 4115.999
76.0 Feira De Santana -12.26667 -38.96667 552.841 662.286
76.0 Florianópolis -27.59667 -48.54917 1180.322 1480.573
76.0 Fortaleza -3.74117 -38.543575 3880.202 4550.936
76.0 Franca -20.53861 -47.40083 328.498 387.28
76.0 Goiânia -16.67861 -49.25389 2284.828 2729.645
76.0 Grande São Luís -2.538539 -44.283186 1436.781 1714.4
76.0 Grande Vitória -20.305424 -40.307915 1636.141 1907.583
76.0 João Pessoa -7.115 -34.86306 1093.168 1297.881
76.0 Joinville -26.30444 -48.84556 1218.709 1450.023
76.0 Juazeiro Do Norte -7.21306 -39.31528 357.651 429.537
76.0 Juiz De Fora -21.76417 -43.35028 541.289 637.987
76.0 Jundiaí -23.188254 -46.891347 619.669 747.174
76.0 Londrina -23.31028 -51.16278 797.953 953.391
76.0 Macapá 0.03889 -51.06639 449.433 578.854
76.0 Maceió -9.66583 -35.73528 1266.029 1508.261
76.0 Manaus -3.10194 -60.025 2025.379 2454.074
76.0 Maringá -23.42528 -51.93861 390.378 482.274
76.0 Montes Claros -16.735 -43.86167 374.171 452.594
76.0 Natal -5.795 -35.20944 1166.515 1399.318
76.0 Pelotas -31.77194 -52.3425 307.978 351.283
76.0 Petrolina -9.39861 -40.50083 425.684 526.629
76.0 Piracicaba -22.72528 -47.64917 376.763 445.409
76.0 Ponta Grossa -25.095 -50.16194 324.426 387.05
76.0 Pôrto Alegre -30.03306 -51.23 3602.526 4028.31
76.0 Pôrto Velho -8.76194 -63.90389 463.663 599.996
76.0 Recife -8.05389 -34.88111 3738.526 4222.465
76.0 Ribeirão Preto -21.1775 -47.81028 650.502 779.376
76.0 Rio Branco -9.97472 -67.81 358.026 457.082
76.0 Rio de Janeiro -22.90278 -43.2075 12902.306 14173.748
76.0 Salvador -12.97111 -38.51083 3582.967 4114.902
76.0 São José do Rio Preto -20.81972 -49.37944 407.276 482.99
76.0 São José dos Campos -23.17944 -45.88694 571.601 660.98
76.0 São Paulo -23.5475 -46.63611 21066.245 23444.363
76.0 Sorocaba -23.50167 -47.45806 727.116 865.214
76.0 Teresina -5.08917 -42.80194 958.884 1121.863
76.0 Uberaba -19.74833 -47.93194 313.605 379.778
76.0 Uberlândia -18.91861 -48.27722 639.387 768.627
76.0 Vale do Aço -19.940497 -43.935443 497.065 581.519
76.0 Volta Redonda -22.52306 -44.10417 446.933 517.235
100.0 Plovdiv 42.15 24.75 338.041 324.248
100.0 Sofia 42.69751 23.32415 1226.155 1229.925
100.0 Varna 43.21667 27.91667 341.706 359.068
854.0 Bobo-Dioulasso 11.17715 -4.2979 721.339 1381.482
854.0 Ouagadougou 12.36423 -1.53834 2741.128 5853.943
108.0 Bujumbura -3.3822 29.3644 750.862 1734.514
116.0 Phnum Pénh (Phnom Penh) 11.56245 104.91601 1731.286 2584.336
120.0 Bafoussam 5.47366 10.41786 350.054 563.843
120.0 Bamenda 5.95266 10.15824 424.196 703.285
120.0 Douala 4.04827 9.70428 2943.318 4774.365
120.0 Loum 4.7182 9.7351 361.518 645.921
120.0 Mbouda 5.62578 10.25517 332.003 623.676
120.0 Yaoundé 3.86667 11.51667 3065.692 5157.957
124.0 Calgary 51.044072 -114.059314 1337.106 1630.262
124.0 Edmonton 53.543409 -113.503721 1272.069 1546.963
124.0 Halifax 44.647712 -63.581778 404.748 475.42
124.0 Hamilton 43.249459 -79.847539 744.0 860.98
124.0 Kitchener 43.42537 -80.5112 498.909 588.648
124.0 London 42.98339 -81.23304 488.615 567.99
124.0 Montréal 45.50884 -73.58781 3980.708 4517.425
124.0 Oshawa 43.90012 -78.84957 378.185 454.946
124.0 Ottawa-Gatineau 45.416598 -75.697997 1325.846 1576.927
124.0 Québec 46.81228 -71.21454 805.113 947.47
124.0 St. Catharines-Niagara 43.16681 -79.24958 393.176 447.321
124.0 Toronto 43.70011 -79.4163 5992.739 6956.552
124.0 Vancouver 49.24966 -123.11934 2485.173 2929.898
124.0 Victoria 48.4329 -123.3693 356.552 418.799
124.0 Windsor 42.281051 -83.007948 315.475 355.29
124.0 Winnipeg 49.895451 -97.129437 759.365 885.305
140.0 Bangui 4.36122 18.55496 794.022 1148.335
148.0 N'Djaména 12.10672 15.0444 1260.146 2346.978
152.0 Antofagasta -23.65 -70.4 450.979 575.79
152.0 Concepción -36.82699 -73.04977 816.22 955.141
152.0 Iquique -20.22083 -70.14306 358.105 466.606
152.0 La Serena-Coquimbo -29.90453 -71.24894 457.108 575.854
152.0 Santiago -33.45694 -70.64827 6507.4 7122.444
152.0 Temuco -38.73333 -72.6 361.62 442.923
152.0 Valparaíso -33.03932 -71.62725 906.967 1029.397
156.0 Akesu 41.169547 80.262646 340.27 474.942
156.0 Ankang 32.691183 109.029694 486.44 717.082
156.0 Anqing 30.542972 117.0533 639.802 838.695
156.0 Anqiu 36.43417 119.1925 492.6 760.408
156.0 Anshan 41.12361 122.99 1559.151 1886.382
156.0 Anshun 26.24441 105.932401 408.714 576.38
156.0 Anyang 36.094436 114.35034 1140.285 1632.59
156.0 Baicheng 45.618331 122.841797 309.588 392.165
156.0 Baishan 41.937333 126.422863 636.747 925.166
156.0 Baiyin 36.548652 104.183117 381.793 478.061
156.0 Baoding 38.85111 115.49028 1105.986 1377.007
156.0 Baoji 34.365118 107.200449 1000.502 1329.0
156.0 Baotou 40.65222 109.82222 1957.044 2494.597
156.0 Bayannaoer 40.750478 107.40523 393.874 515.788
156.0 Bazhong 31.866216 106.732539 678.792 1088.8
156.0 Beihai 21.478511 109.119973 473.222 575.219
156.0 Beijing 39.9075 116.39723 20383.994 27706.032
156.0 Bengbu 32.94083 117.36083 841.924 1048.29
156.0 Benxi 41.28861 123.765 1070.3 1338.384
156.0 Bijie 27.306953 105.28368 513.757 725.553
156.0 Binzhou 37.381079 118.010852 692.548 955.419
156.0 Botou 38.06667 116.56667 316.299 451.557
156.0 Bozhou 33.870279 115.776985 587.73 839.877
156.0 Cangzhou 38.31667 116.86667 526.781 657.233
156.0 Cenxi 22.919083 110.994456 432.055 638.309
156.0 Changchun 43.882494 125.293964 3762.39 4742.114
156.0 Changde 29.04638 111.6783 713.779 951.881
156.0 Changge 34.222382 113.773631 367.453 552.467
156.0 Changji 44.011737 87.303752 343.39 457.026
156.0 Changning 26.407769 112.395699 408.415 581.656
156.0 Changsha 28.227394 112.938269 3761.018 5013.202
156.0 Changshu 31.653905 120.746654 726.067 1054.373
156.0 Changyi 36.854566 119.391267 371.652 553.849
156.0 Changzhi 36.192128 113.115533 738.456 972.845
156.0 Changzhou, Jiangsu 31.794314 119.958917 2584.418 3380.623
156.0 Chaohu 31.6 117.86667 440.626 566.126
156.0 Chaoyang 41.577292 120.451132 505.92 633.848
156.0 Chaozhou 23.66513 116.63786 1332.938 1649.534
156.0 Chengde 40.967162 117.932222 682.999 990.532
156.0 Chengdu 30.66667 104.06667 7555.705 10104.406
156.0 Chenzhou 25.8 113.03333 740.477 1077.198
156.0 Chifeng 42.264602 118.915236 1018.266 1333.243
156.0 Chizhou 30.65778 117.48306 363.278 528.93
156.0 Chongqing 29.56278 106.55278 13331.579 17380.364
156.0 Chuxiong 25.044539 101.541009 404.152 571.914
156.0 Chuzhou 32.29853 118.316399 449.419 602.75
156.0 Cixi 30.176116 121.252392 1303.03 1828.772
156.0 Dafeng 33.196372 120.456129 396.142 530.352
156.0 Dali 25.590024 100.223521 433.6 597.367
156.0 Dalian 38.913811 121.602322 4489.38 5850.602
156.0 Dandong 40.119831 124.373852 820.947 1020.625
156.0 Danyang 32.000797 119.574455 598.348 829.018
156.0 Daqing 46.58333 125.0 1621.439 2112.875
156.0 Dashiqiao 40.63732 122.50251 338.66 433.08
156.0 Datong 40.080522 113.293045 1531.736 1987.673
156.0 Daye 30.098674 114.970308 506.755 668.883
156.0 Dazhou 31.21592 107.50092 567.86 780.103
156.0 Dengfeng 34.45528 113.02806 393.422 605.439
156.0 Dengzhou 32.68222 112.08194 523.539 760.796
156.0 Deyang 31.13019 104.38198 628.815 864.926
156.0 Dezhou 37.451765 116.300973 596.436 789.766
156.0 Donggang 39.883429 124.146248 326.052 431.26
156.0 Dongguan 23.02116 113.741411 7434.935 8700.622
156.0 Dongtai 32.85231 120.30947 574.428 783.492
156.0 Dongyang 29.275294 120.230273 504.89 657.012
156.0 Dongying 37.453273 118.578519 967.272 1277.751
156.0 Dujiangyan 30.996625 103.628081 346.416 447.34
156.0 Enshi 30.290188 109.47854 428.327 656.464
156.0 Erduosi (Ordoss) 39.591741 109.766573 589.337 808.051
156.0 Ezhou 30.400061 114.884582 634.5 782.662
156.0 Fangchenggang 21.765917 108.35395 339.284 480.945
156.0 Feicheng 36.185412 116.767394 507.84 643.839
156.0 Fengcheng 28.178737 115.775836 410.344 524.26
156.0 Foshan 23.022778 113.119953 7035.945 8353.315
156.0 Fuan 27.088055 119.645351 383.798 528.197
156.0 Fuqing 25.725 119.37944 521.417 678.223
156.0 Fushun, Liaoning 41.880737 123.946698 1298.344 1507.924
156.0 Fuxin 42.01556 121.65889 789.748 977.934
156.0 Fuyang 32.889497 115.815213 892.588 1184.928
156.0 Fuyang 30.058484 119.943957 509.804 722.855
156.0 Fuzhou, Fujian 26.075352 119.298946 3282.932 4335.389
156.0 Fuzhou, Jiangxi 27.98119 116.355676 557.214 749.854
156.0 Ganzhou 25.85 114.93333 801.667 1207.294
156.0 Gaoan 28.427086 115.3722 364.961 523.598
156.0 Gaocheng 38.023261 114.840049 344.03 482.808
156.0 Gaomi 36.38333 119.75278 572.939 812.44
156.0 Gaoyou 32.779085 119.447041 412.598 580.573
156.0 Gaozhou 21.915852 110.849874 419.039 609.254
156.0 Gongyi 34.76 112.97139 429.417 587.987
156.0 Gongzhuling 43.50075 124.81979 353.488 440.473
156.0 Guang'an 30.463918 106.63512 388.594 552.727
156.0 Guangyuan 32.44202 105.823 449.702 618.754
156.0 Guangzhou, Guangdong 23.125457 113.257374 12458.13 17574.395
156.0 Guigang 23.09639 109.60917 760.624 1019.541
156.0 Guilin 25.28194 110.28639 1039.864 1310.13
156.0 Guiping 23.39336 110.07437 671.666 1012.136
156.0 Guiyang 26.58333 106.71667 2870.895 3733.956
156.0 Haerbin 45.756325 126.646688 5457.414 6860.038
156.0 Haicheng 40.855239 122.743396 731.645 915.805
156.0 Haikou 20.027423 110.330071 1903.037 2702.173
156.0 Haimen 31.895193 121.168399 528.955 718.59
156.0 Haining 30.527288 120.68968 454.854 609.306
156.0 Hami 42.825945 93.516917 351.036 467.324
156.0 Hanchuan 30.651646 113.832908 573.848 811.726
156.0 Handan 36.60056 114.46778 1634.008 2304.432
156.0 Hangzhou 30.29365 120.16142 6390.637 8821.757
156.0 Hanzhong 33.07278 107.03028 368.689 461.609
156.0 Hebi 35.747018 114.295632 518.491 663.045
156.0 Hefei 31.86389 117.28083 3347.591 4152.23
156.0 Hegang 47.344338 130.293701 617.138 750.912
156.0 Hejian 38.442546 116.094913 326.696 503.853
156.0 Hengshui 37.741068 115.678068 478.365 680.499
156.0 Hengyang 26.884064 112.62509 1301.25 1746.245
156.0 Heshan 22.765897 112.959032 330.233 452.616
156.0 Heyuan 23.750937 114.699168 483.488 612.407
156.0 Heze 35.245103 115.459799 575.447 701.634
156.0 Hezhou 24.41518 111.554009 482.462 706.052
156.0 Hohhot 40.81056 111.65222 1784.685 2429.052
156.0 Hsinchu 24.805781 120.9703 518.809 665.305
156.0 Huai'an 33.606953 119.014801 2000.195 2950.852
156.0 Huaibei 33.954851 116.792878 980.72 1303.098
156.0 Huaihua 27.54944 109.95917 590.382 849.343
156.0 Huainan 32.62639 116.99694 1327.431 1657.041
156.0 Huangshan 29.712665 118.322512 335.883 460.025
156.0 Huangshi 30.20678 115.085462 752.808 959.455
156.0 Huizhou 23.08333 114.4 2312.397 3329.825
156.0 Huludao 40.75242 120.83552 703.947 898.707
156.0 Huzhou 30.8703 120.0933 854.029 1131.565
156.0 Jiamusi 46.797936 130.330183 668.684 835.108
156.0 Ji'an, Jiangxi 27.1177 114.980419 375.27 503.795
156.0 Jiangmen 22.58333 113.08333 1572.383 1943.442
156.0 Jiangyin 31.915679 120.28096 685.661 957.213
156.0 Jianyang 30.392089 104.544758 418.873 562.872
156.0 Jiaozhou 36.28389 120.00333 470.972 640.633
156.0 Jiaozuo 35.23972 113.23306 731.741 898.984
156.0 Jiaxing 30.766487 120.748231 970.23 1407.931
156.0 Jieyang 23.552629 116.372145 908.57 1289.974
156.0 Jilin 43.85083 126.56028 1520.496 1853.881
156.0 Jimo 36.38972 120.46222 633.583 830.482
156.0 Ji'nan, Shandong 36.676721 116.997142 4032.15 5234.047
156.0 Jincheng 35.486475 112.851484 586.233 832.021
156.0 Jingdezhen 29.2947 117.20789 377.616 467.832
156.0 Jingjiang 32.011966 120.262719 472.348 666.785
156.0 Jingmen 31.041652 112.200343 438.532 569.238
156.0 Jingzhou, Hubei 30.327567 112.248367 963.971 1203.355
156.0 Jinhua 29.080651 119.646369 970.089 1494.985
156.0 Jining, Shandong 35.414595 116.584704 1384.942 1722.382
156.0 Jinjiang 24.810636 118.577293 441.904 578.812
156.0 Jinzhong 37.688161 112.734878 512.183 689.959
156.0 Jinzhou 41.10778 121.14167 1034.924 1319.197
156.0 Jiujiang 29.704105 116.001302 682.276 889.938
156.0 Jixi, Heilongjiang 45.295804 130.970134 889.816 1103.847
156.0 Jiyuan 35.09264 112.583273 374.696 485.384
156.0 Jurong 31.949802 119.160916 359.737 504.776
156.0 Kaifeng 34.79111 114.34833 804.351 1040.727
156.0 Kaili 26.583431 107.971854 308.297 408.342
156.0 Kaiping 22.372447 112.702597 384.053 473.649
156.0 Kaohsiung 22.625962 120.31546 1522.779 1796.094
156.0 Keelung 25.130874 121.736127 374.313 443.839
156.0 Kelamayi 45.594143 84.872929 399.306 530.479
156.0 Kuerle 41.764562 86.147227 567.871 865.488
156.0 Kunming 25.03889 102.71833 3779.558 4804.552
156.0 Kunshan 31.388114 120.962872 581.871 834.351
156.0 Laibin 23.737978 109.226765 354.997 470.134
156.0 Laiwu 36.207444 117.672021 773.419 1037.987
156.0 Laixi 36.865132 120.52381 415.425 578.685
156.0 Laiyang 36.97583 120.71361 371.179 458.525
156.0 Laizhou 37.179653 119.943045 385.505 467.537
156.0 Langfang 39.50972 116.69472 621.722 846.099
156.0 Lanzhou 36.05639 103.79222 2723.114 3484.521
156.0 Leiyang 26.416884 112.850257 635.389 966.096
156.0 Leping 28.971963 117.128335 314.853 409.961
156.0 Leshan 29.576174 103.75896 811.591 1119.922
156.0 Lianyungang 34.59687 119.175775 1099.332 1541.987
156.0 Liaocheng 36.455124 115.982616 677.419 884.442
156.0 Liaoyang 41.27194 123.17306 788.88 993.177
156.0 Liaoyuan 42.90361 125.13583 376.235 446.962
156.0 Liling 27.66667 113.5 603.089 922.709
156.0 Lin'an 30.23583 119.71806 352.149 527.45
156.0 Linfen 36.08889 111.51889 698.523 984.593
156.0 Linhai 28.852887 121.140343 595.948 819.005
156.0 Linqing 36.84556 115.71167 361.708 453.289
156.0 Linyi, Shandong 35.054142 118.333365 1706.0 2204.013
156.0 Linzhou 36.071045 113.815557 360.101 475.105
156.0 Lishui, Zhejiang 28.456982 119.919233 351.506 490.84
156.0 Liuan 31.754268 116.498142 879.069 1326.304
156.0 Liupanshui 26.592289 104.837711 809.436 1201.427
156.0 Liuyang 28.15 113.63333 818.578 1285.649
156.0 Liuzhou 24.301725 109.378368 1619.165 2136.669
156.0 Liyang 31.422985 119.483691 408.015 532.587
156.0 Longhai 24.446231 117.809024 512.198 719.105
156.0 Longkou 37.641712 120.519875 446.622 600.693
156.0 Longyan 25.10722 117.0225 485.941 607.656
156.0 Loudi 27.73444 111.99444 520.033 736.426
156.0 Luoding 22.770797 111.565963 320.126 424.932
156.0 Luohe 33.573149 114.024063 772.468 1176.377
156.0 Luoyang 34.618562 112.456179 2014.999 2687.563
156.0 Luzhou 28.877528 105.440814 778.005 960.113
156.0 Lvliang 37.519533 111.131763 328.751 498.166
156.0 Ma'anshan 31.707085 118.503768 858.274 1161.23
156.0 Macheng 31.17833 115.03194 324.884 414.246
156.0 Maoming 21.662659 110.923448 608.88 844.666
156.0 Meishan 30.076148 103.845638 409.638 563.824
156.0 Meizhou 24.298896 116.12139 373.373 468.346
156.0 Mianyang, Sichuan 31.483888 104.737019 1064.818 1364.43
156.0 Miluo 28.806933 113.072064 519.842 934.739
156.0 Mudanjiang 44.58333 129.6 850.834 1072.51
156.0 Nanchang 28.68333 115.88333 2526.814 3285.277
156.0 Nanchong 30.79508 106.08474 1049.782 1426.112
156.0 Nanjing, Jiangsu 32.048183 118.789812 7369.157 9754.28
156.0 Nankang 25.665464 114.755751 334.999 477.12
156.0 Nanning 22.81667 108.31667 3234.379 4438.356
156.0 Nantong 31.990413 120.865451 1978.255 2755.401
156.0 Nanyang, Henan 32.999941 112.52593 1011.389 1319.716
156.0 Neijiang 29.58354 105.06216 612.687 756.572
156.0 Ningbo 29.87819 121.54945 3131.921 4290.448
156.0 Panjin 41.121893 122.070073 692.622 853.256
156.0 Panzhihua 26.58509 101.71276 664.958 825.943
156.0 Pingdingshan, Henan 33.74166 113.304003 995.333 1323.446
156.0 Pingdu 36.780791 119.959214 471.052 610.722
156.0 Pinghu 30.703667 121.009699 351.769 503.451
156.0 Pingxiang, Jiangxi 27.634816 113.847689 810.12 1066.206
156.0 Pizhou 34.31139 117.95028 810.9 1188.998
156.0 Pulandian 39.400329 121.969362 347.731 447.687
156.0 Puning 23.296655 116.164678 1004.867 1335.745
156.0 Putian 25.43944 119.01028 1437.548 2110.806
156.0 Puyang 35.77051 115.043769 523.136 722.961
156.0 Qianjiang 30.422118 112.892537 470.787 598.113
156.0 Qingdao 36.09861 120.37194 4565.549 5920.149
156.0 Qingyuan 23.714582 113.029707 692.533 858.209
156.0 Qingzhou 36.684528 118.479622 443.926 599.852
156.0 Qinhuangdao 39.93167 119.58833 1109.249 1469.79
156.0 Qinzhou 21.96808 108.62136 557.482 742.402
156.0 Qiqihaer 47.34083 123.96722 1451.529 1797.941
156.0 Qitaihe 45.767053 130.975 537.276 676.581
156.0 Quanzhou 24.896763 118.599688 1395.334 1927.923
156.0 Qufu 35.59667 116.99111 331.798 430.435
156.0 Qujing 25.489377 103.797682 565.078 789.688
156.0 Quzhou 28.95944 118.86861 559.555 846.567
156.0 Renqiu 38.69889 116.09361 520.693 729.58
156.0 Rizhao 35.40336 119.511996 1062.34 1441.267
156.0 Rongcheng 37.15396 122.436268 383.087 479.847
156.0 Ruian 27.780759 120.675519 973.064 1326.327
156.0 Sanhe 39.981938 117.07133 436.834 649.34
156.0 Sanmenxia 34.771452 111.20379 311.072 402.39
156.0 Sanming 26.264076 117.619053 348.22 438.554
156.0 Sanya 18.267573 109.503412 540.522 747.69
156.0 Shanghai 31.22222 121.45806 23740.778 30750.671
156.0 Shangqiu 34.424422 115.651378 709.893 947.737
156.0 Shangrao 28.460359 117.953064 361.788 510.16
156.0 Shangyu 30.031143 120.872182 444.162 591.014
156.0 Shantou 23.36814 116.71479 3948.813 4899.353
156.0 Shanwei 22.778662 115.356782 396.952 503.779
156.0 Shaoguan 24.8 113.58333 740.723 893.692
156.0 Shaoxing 30.011 120.5715 2075.769 2840.849
156.0 Shaoyang 27.240329 111.470907 636.324 825.419
156.0 Shengzhou 29.593023 120.821389 370.383 470.67
156.0 Shenyang 41.79222 123.43278 6315.47 7910.905
156.0 Shenzhen 22.541487 114.063427 10749.473 12672.821
156.0 Shihezi 44.307503 86.03204 320.434 391.67
156.0 Shijiazhuang 38.041845 114.510846 3264.498 4362.033
156.0 Shishi 24.736683 118.634046 521.225 678.815
156.0 Shiyan 32.644469 110.783587 830.719 1106.328
156.0 Shizuishan 39.2333 106.7694 452.88 596.521
156.0 Shouguang 36.878792 118.748212 506.562 636.847
156.0 Shuangyashan 46.63611 131.15389 490.504 595.081
156.0 Shuozhou 39.31583 112.4225 462.601 651.092
156.0 Sihui 23.346173 112.695815 453.839 667.354
156.0 Siping 43.16333 124.36861 547.22 693.409
156.0 Songyuan 27.6217 119.0592 486.314 603.026
156.0 Suihua 46.636597 126.982968 389.934 494.801
156.0 Suining, Sichuan 30.523613 105.563901 616.2 807.768
156.0 Suizhou 31.71111 113.36306 416.458 523.186
156.0 Suqian 33.968102 118.292384 1049.812 1590.71
156.0 Suzhou, Anhui 33.635918 116.974726 923.274 1314.603
156.0 Suzhou, Jiangsu 31.302068 120.585259 5472.033 8098.45
156.0 Taian, Shandong 36.190371 117.119081 1219.58 1540.791
156.0 Taicang 31.454873 121.117171 528.974 744.681
156.0 Taichung 24.141613 120.67274 1224.935 1527.993
156.0 Tainan 23.131587 120.259004 814.971 995.554
156.0 Taipei 25.047009 121.54568 2665.656 3116.192
156.0 Taishan 22.250432 112.794336 452.031 606.056
156.0 Taixing 32.16667 120.01361 638.284 857.46
156.0 Taiyuan, Shanxi 37.861899 112.551572 3481.81 4396.454
156.0 Taizhou, Jiangsu 32.494536 119.902861 1183.925 1541.171
156.0 Taizhou, Zhejiang 28.637219 121.418459 1648.025 2188.605
156.0 Tangshan, Hebei 39.628484 118.179931 2743.252 3801.198
156.0 Tengzhou 35.084539 117.162387 956.863 1341.313
156.0 Tianjin 39.108842 117.18862 11210.329 14655.411
156.0 Tianmen 30.653449 113.160506 724.043 991.001
156.0 Tianshui 34.580929 105.723718 643.951 883.286
156.0 Tieling 42.29306 123.84139 396.367 487.197
156.0 Tongcheng 31.053789 116.95557 332.589 477.708
156.0 Tongchuan 34.8988 108.95056 500.833 637.863
156.0 Tonghua 41.720071 125.928089 521.219 670.511
156.0 Tongliao 43.6125 122.26528 611.813 809.147
156.0 Tongling 30.936306 117.810916 489.803 641.748
156.0 Tongxiang 30.629604 120.55359 497.317 713.778
156.0 Ürümqi (Wulumqi) 43.82532 87.603835 3498.591 4831.078
156.0 Wafangdian 39.626683 121.994937 434.262 540.8
156.0 Weifang 36.71 119.10194 2194.524 2972.724
156.0 Weihai 37.50167 122.11361 845.156 1176.88
156.0 Weinan 34.50355 109.50891 355.847 435.329
156.0 Wenling 28.375791 121.378138 874.592 1181.424
156.0 Wenzhou 27.99942 120.66682 3207.846 4335.572
156.0 Wuchuan 21.431015 110.776222 339.386 414.127
156.0 Wuhai 39.66472 106.81222 559.346 729.752
156.0 Wuhan 30.58333 114.26667 7905.572 9441.574
156.0 Wuhu, Anhui 31.333557 118.381175 1424.491 2074.276
156.0 Wuwei 37.925127 102.633659 361.848 467.464
156.0 Wuxi, Jiangsu 31.536681 120.298556 3049.042 3862.473
156.0 Wuzhou 23.483239 111.274132 603.678 802.019
156.0 Xiamen 24.47979 118.08187 4430.081 6911.028
156.0 Xi'an, Shaanxi 34.289413 108.940242 6043.7 7903.831
156.0 Xiangcheng 33.444151 114.898161 359.269 542.626
156.0 Xiangtan, Hunan 27.828265 112.926952 1009.562 1311.127
156.0 Xiangyang 32.008764 112.144038 1533.332 1907.361
156.0 Xianning 29.835577 114.330269 344.475 417.025
156.0 Xiantao 30.371768 113.448402 568.767 693.722
156.0 Xianyang, Shaanxi 34.338637 108.701548 679.696 836.659
156.0 Xiaogan 30.925566 113.91746 670.573 898.437
156.0 Xinghua 32.937332 119.838732 669.57 905.406
156.0 Xingning 24.145484 115.725321 361.87 548.924
156.0 Xingtai 37.06306 114.49417 741.757 959.566
156.0 Xingyang 34.791577 113.383427 324.381 455.815
156.0 Xingyi, Guizhou 25.09446 104.898285 350.455 436.421
156.0 Xining 36.61667 101.76667 1322.966 1749.812
156.0 Xinmi 34.535524 113.389003 450.281 652.393
156.0 Xintai 35.90056 117.75194 785.12 1067.094
156.0 Xinxiang 35.298867 113.901477 990.826 1249.324
156.0 Xinyang 32.128856 114.074643 701.489 918.669
156.0 Xinyi 34.366827 118.343018 470.724 642.792
156.0 Xinyi 22.358519 110.938758 363.93 469.292
156.0 Xinyu 27.80429 114.93335 691.59 971.66
156.0 Xinzheng 34.398508 113.736824 384.321 514.311
156.0 Xinzhou 38.417329 112.733107 321.417 434.198
156.0 Xuancheng 30.948973 118.752396 380.17 534.411
156.0 Xuchang 34.01667 113.81667 516.044 670.881
156.0 Xuzhou 34.263685 117.186605 1917.791 2444.725
156.0 Yanan 36.596722 109.483756 430.164 633.498
156.0 Yancheng, Jiangsu 33.356867 120.155148 1435.817 2059.252
156.0 Yangjiang 21.861445 111.956303 542.177 693.399
156.0 Yangquan 37.85578 113.582568 699.22 915.247
156.0 Yangzhou 32.391492 119.423807 1765.449 2269.036
156.0 Yanji 42.9075 129.50778 588.297 796.893
156.0 Yanshi 34.729344 112.779926 386.647 573.563
156.0 Yantai 37.465087 121.437152 2114.415 2838.009
156.0 Yibin 28.76667 104.62383 733.603 941.829
156.0 Yichang 30.71444 111.28472 1263.722 1743.488
156.0 Yichun, Heilongjiang 47.724475 128.83367 643.781 717.822
156.0 Yichun, Jiangxi 27.806158 114.389221 642.83 1013.091
156.0 Yinchuan 38.46806 106.27306 1596.395 2460.659
156.0 Yingde 24.197408 113.405468 384.224 501.958
156.0 Yingkou 40.66482 122.22833 1025.941 1380.354
156.0 Yining 43.919634 81.316125 325.801 417.864
156.0 Yiwu 29.31506 120.07676 1080.473 1520.453
156.0 Yixing 31.359926 119.776306 385.393 503.758
156.0 Yiyang, Hunan 28.566585 112.348737 472.039 642.325
156.0 Yongcheng 33.93177 116.44338 390.067 543.183
156.0 Yongkang 28.903339 120.032761 441.413 604.518
156.0 Yongzhou 26.435132 111.606348 648.82 900.555
156.0 Yuanjiang 28.843025 112.364162 309.137 402.692
156.0 Yueqing 28.1194 120.9612 870.094 1201.871
156.0 Yueyang 29.372239 113.115285 961.629 1175.911
156.0 Yulin, Guangxi 22.633869 110.153301 577.127 718.24
156.0 Yulin, Shaanxi 38.28384 109.731486 369.743 468.208
156.0 Yuncheng 35.02306 110.99278 535.318 765.186
156.0 Yushu 44.824348 126.551011 314.438 415.645
156.0 Yuxi 24.3567 102.539544 383.734 555.986
156.0 Yuyao 30.042582 121.15306 596.274 783.72
156.0 Zaoyang 32.12722 112.75417 495.536 651.343
156.0 Zaozhuang 34.86472 117.55417 1028.183 1263.922
156.0 Zengcheng 23.294152 113.825552 504.779 683.459
156.0 Zhangjiagang 31.865 120.53889 519.55 743.793
156.0 Zhangjiakou 40.81 114.87944 983.441 1224.814
156.0 Zhangqiu 36.701031 117.52711 569.315 786.592
156.0 Zhangye 38.93417 100.45167 419.23 521.117
156.0 Zhangzhou 24.5133 117.6556 726.117 993.203
156.0 Zhanjiang 21.266159 110.359639 1149.05 1476.491
156.0 Zhaodong 46.066829 125.989643 440.154 626.484
156.0 Zhaoqing 23.05116 112.45972 626.111 819.052
156.0 Zhaoyuan 37.35917 120.39639 311.095 406.55
156.0 Zhengzhou 34.75778 113.64861 4387.118 5899.771
156.0 Zhenjiang, Jiangsu 32.202713 119.44894 1049.853 1349.022
156.0 Zhongshan 22.517992 113.383938 3691.36 5517.538
156.0 Zhongxiang 31.16611 112.58306 462.428 577.316
156.0 Zhoukou 33.617368 114.646126 543.671 744.317
156.0 Zhoushan 29.988548 122.213475 590.816 756.623
156.0 Zhuanghe 39.705122 122.968765 373.011 531.671
156.0 Zhucheng 35.99472 119.3975 716.674 1008.974
156.0 Zhuhai 22.2769 113.5678 1541.9 2002.936
156.0 Zhuji 29.713158 120.236819 682.27 895.72
156.0 Zhumadian 32.97944 114.02944 560.584 809.021
156.0 Zhuzhou 27.83333 113.15 1083.065 1368.72
156.0 Zibo 36.79056 118.06333 2430.356 3014.5
156.0 Zigong 29.34162 104.77689 697.647 861.618
156.0 Ziyang 30.12563 104.630483 430.767 577.801
156.0 Zunyi 27.711309 106.936512 802.723 1049.73
344.0 Hong Kong 22.279588 114.188697 7313.557 7885.155
446.0 Macao 22.20056 113.54611 584.42 701.551
170.0 Armenia 4.53389 -75.68111 399.62 496.73
170.0 Barranquilla 10.96389 -74.79639 1991.158 2369.516
170.0 Bogotá 4.60971 -74.08175 9764.769 11966.118
170.0 Bucaramanga 7.12539 -73.1198 1215.066 1506.917
170.0 Buenaventura 3.885028 -77.07001 412.365 543.301
170.0 Cali 3.43722 -76.5225 2645.941 3202.673
170.0 Cartagena 10.39972 -75.51444 1092.336 1372.243
170.0 Cúcuta 7.89391 -72.50782 851.312 1046.933
170.0 Ibagué 4.43889 -75.23222 611.95 777.836
170.0 Manizales 5.06889 -75.51738 448.951 545.546
170.0 Medellín 6.25184 -75.56359 3910.989 4747.383
170.0 Monteria 8.74798 -75.88143 370.762 473.239
170.0 Neiva 2.9273 -75.28188 355.131 440.284
170.0 Pasto 1.21361 -77.28111 363.298 444.21
170.0 Pereira 4.81333 -75.69611 598.019 711.861
170.0 Santa Marta 11.24079 -74.19904 517.627 667.255
170.0 Valledupar 10.46314 -73.25322 414.567 542.855
170.0 Villavicencio 4.142 -73.62664 552.094 746.836
178.0 Brazzaville -4.26583 15.28318 1887.625 2979.227
178.0 Pointe-Noire -4.77609 11.86352 968.526 1525.239
188.0 San José 9.927817 -84.080685 1170.188 1500.555
384.0 Abidjan 5.345339 -4.026789 4859.798 7772.628
384.0 Bouake 7.69385 -5.03031 761.547 1218.641
384.0 San Pedro 4.7333333 -6.6166667 347.358 630.097
191.0 Zagreb 45.81444 15.97798 686.902 731.507
192.0 Camaguey 21.38083 -77.91694 315.03 330.659
192.0 Holguin 20.88722 -76.26306 306.323 330.106
192.0 La Habana (Havana) 23.119541 -82.378493 2137.097 2104.358
192.0 Santiago de Cuba 20.02472 -75.82194 475.081 505.204
203.0 Brno 49.19522 16.60796 390.247 427.938
203.0 Praha (Prague) 50.08804 14.42076 1313.557 1436.942
408.0 Chongjin 41.79556 129.77583 630.562 746.249
408.0 Hamhung 39.91833 127.53639 575.534 647.053
408.0 P'yongyang 39.03385 125.75432 2862.921 3277.211
408.0 Sinuiju 40.10056 124.39806 326.215 384.994
408.0 Wonsan 39.15278 127.44361 342.41 413.577
180.0 Bukavu -2.50833 28.86083 832.238 1509.907
180.0 Bunia 1.566666667 30.25 485.013 940.399
180.0 Goma -1.679166667 29.22277778 474.007 885.428
180.0 Kananga -5.89624 22.41659 1168.687 2053.452
180.0 Kikwit -5.04098 18.81619 427.245 724.708
180.0 Kinshasa -4.32758 15.31357 11586.914 19996.156
180.0 Kisangani 0.51667 25.2 1039.612 1786.295
180.0 Kolwezi -10.71484 25.46674 480.6 725.045
180.0 Likasi -10.98139 26.73333 494.449 815.43
180.0 Lubumbashi -11.66089 27.47938 2015.091 3489.454
180.0 Matadi -5.8177 13.4717 336.74 559.85
180.0 Mbandaka 0.04865 18.26034 375.621 633.873
180.0 Mbuji-Mayi -6.15 23.6 2006.641 3540.552
180.0 Tshikapa -6.41621 20.79995 689.55 1281.816
180.0 Uvira -3.39534 29.13779 442.399 824.193
208.0 København (Copenhagen) 55.67594 12.56553 1268.052 1454.647
262.0 Djibouti 11.58767 43.14468 528.627 639.311
214.0 Santiago 19.460205 -70.699686 577.246 736.024
214.0 Santo Domingo 18.489591 -69.901805 2945.353 3887.701
218.0 Cuenca -2.88333 -78.98333 360.505 482.8
218.0 Guayaquil -2.16667 -79.9 2709.329 3493.183
218.0 Quito -0.22985 -78.52495 1726.075 2228.316
218.0 Santo Domingo -0.253431 -79.169555 316.172 449.194
818.0 Al-Fayyum 29.30995 30.8418 372.108 506.835
818.0 Al-Iskandariyah (Alexandria) 31.192471 29.904596 4777.677 6312.644
818.0 Al-Ismailiyah 30.60427 32.27225 329.99 440.891
818.0 Al-Mahallah al-Kubra 30.9745 31.16499 488.254 642.779
818.0 Al-Mansurah 31.03637 31.38069 509.35 685.908
818.0 Al-Qahirah (Cairo) 30.039173 31.239411 18771.769 24502.15
818.0 As-Suways 29.968133 32.547497 583.108 785.971
818.0 Aswan 24.09343 32.90704 313.396 427.889
818.0 Asyut 27.18096 31.18368 432.801 572.929
818.0 Az-Zaqazig 30.5875 31.50194444 336.54 446.9
818.0 Bur Sa'id 31.25654 32.28412 670.47 905.188
818.0 Kafr-ad-Dawwar 31.13385 30.12843 316.019 427.15
818.0 Tanta 30.787176 30.999539 470.513 622.42
222.0 San Salvador 13.68935 -89.18718 1098.494 1253.614
232.0 Asmara 15.33333 38.93333 803.791 1556.633
233.0 Tallinn 59.43696 24.75353 391.111 382.188
231.0 Addis Ababa 9.02497 38.74689 3237.525 5850.804
231.0 Mekele 13.49667 39.47528 314.595 633.236
246.0 Helsinki 60.169246 24.940216 1179.916 1293.234
246.0 Tampere 61.49911 23.78712 323.75 363.759
250.0 Avignon 43.94834 4.80892 459.893 531.49
250.0 Béthune 50.53333 2.63333 355.852 403.263
250.0 Bordeaux 44.84044 -0.5805 890.76 1029.906
250.0 Douai-Lens 50.368243 3.079497 503.977 560.108
250.0 Grenoble 45.16667 5.71667 503.406 569.0
250.0 Lille 50.63297 3.05858 1027.178 1142.143
250.0 Lyon 45.74846 4.84671 1608.712 1813.801
250.0 Marseille-Aix-en-Provence 43.528414 5.443298 1605.046 1798.495
250.0 Montpellier 43.61092 3.87723 413.309 484.984
250.0 Nantes 47.21725 -1.55336 613.441 703.921
250.0 Nice-Cannes 43.6646 7.15339 966.529 1090.776
250.0 Paris 48.85341 2.3488 10843.285 11803.252
250.0 Rennes 48.11198 -1.67429 329.373 388.978
250.0 Rouen 49.44313 1.09932 464.492 521.094
250.0 Saint-Étienne 45.43333 4.4 367.175 409.533
250.0 Strasbourg 48.58342 7.74296 460.529 525.689
250.0 Toulon 43.123989 5.933225 575.737 658.885
250.0 Toulouse 43.60426 1.44367 937.827 1091.415
250.0 Tours 47.38333 0.68333 352.551 402.852
250.0 Valenciennes 50.35 3.53333 335.094 377.967
266.0 Libreville 0.3925 9.45365 707.225 953.501
270.0 Banjul 13.453099 -16.679433 503.648 833.568
268.0 Tbilisi 41.69411 44.83368 1147.486 1118.578
276.0 Berlin 52.52437 13.41053 3563.194 3657.659
276.0 Bielefeld 52.03333 8.53333 321.279 337.71
276.0 Bochum 51.48333 7.21667 367.305 380.032
276.0 Bonn 50.73438 7.09548 336.845 367.401
276.0 Bremen 53.07516 8.80777 548.98 575.61
276.0 Dortmund 51.51667 7.45 576.642 598.078
276.0 Dresden 51.05089 13.73832 549.637 600.041
276.0 Duesseldorf 51.22172 6.77616 602.747 642.388
276.0 Duisburg 51.43333 6.75 475.319 488.083
276.0 Essen 51.45374 7.010388 566.488 584.578
276.0 Frankfurt am Main 50.11667 8.68333 715.192 773.69
276.0 Hamburg 53.55 10.0 1830.673 1906.25
276.0 Hannover 52.37052 9.73322 532.542 566.007
276.0 Karlsruhe 49.00472 8.38583 304.686 331.912
276.0 Köln (Cologne) 50.93333 6.95 1036.771 1094.562
276.0 Leipzig 51.33962 12.37129 550.752 600.011
276.0 Mannheim 49.48833 8.46472 318.966 342.754
276.0 Muenster (Westfalen) 51.96236 7.62571 304.432 338.728
276.0 München (Munich) 48.137076 11.573377 1437.9 1548.031
276.0 Nurenberg 49.450418 11.075791 517.098 549.962
276.0 Stuttgart 48.78232 9.17702 625.511 667.821
276.0 Wuppertal 51.26667 7.18333 343.854 356.995
288.0 Accra 5.55602 -0.1969 2277.298 3262.379
288.0 Kumasi 6.68848 -1.62443 2598.789 4214.991
288.0 Sekondi Takoradi 4.934 -1.7137 710.751 1197.101
288.0 Tamale 9.40078 -0.8393 485.905 816.579
300.0 Athínai (Athens) 37.95342 23.74897 3051.899 3169.181
300.0 Thessaloniki 40.64028 22.94389 736.628 778.635
320.0 Ciudad de Guatemala (Guatemala City) 14.612652 -90.530746 2918.337 4650.489
324.0 Conakry 9.571642 -13.647602 1936.045 3133.801
324.0 Nzérékoré 7.75624 -8.8179 345.543 641.69
624.0 Bissau 11.86357 -15.59767 492.069 820.944
332.0 Port-au-Prince 18.53917 -72.335 2439.775 3524.841
340.0 Choloma 15.61444 -87.95302 453.105 850.484
340.0 San Pedro Sula 15.5 -88.03333 852.261 1304.707
340.0 Tegucigalpa 14.0818 -87.20681 1122.523 1613.259
348.0 Budapest 47.49801 19.03991 1713.903 1810.73
356.0 Agartala 23.83639 91.275 550.249 954.556
356.0 Agra 27.18333 78.01667 1966.249 2793.02
356.0 Ahmadabad 23.03333 72.61667 7342.85 10526.6
356.0 Ahmadnagar 19.08333 74.73333 394.264 529.293
356.0 Aizawl 23.72444 92.7175 323.031 461.22
356.0 Ajmer 26.45 74.63333 579.258 782.94
356.0 Akola 20.73333 77.0 438.856 582.958
356.0 Aligarh 27.88333 78.08333 1037.402 1502.317
356.0 Allahabad 25.45 81.85 1294.851 1754.767
356.0 Alwar 27.56246 76.625 379.64 543.349
356.0 Amravati 20.93333 77.75 692.947 951.669
356.0 Amritsar 31.630953 74.875536 1264.932 1721.216
356.0 Anand 22.56667 72.93333 322.43 466.809
356.0 Anantapur 14.68333 77.6 395.171 585.773
356.0 Asansol 23.68333 86.98333 1313.452 1768.061
356.0 Aurangabad 19.876619 75.34331 1344.253 1924.698
356.0 Baharampur 24.1 88.25 312.333 414.491
356.0 Bangalore 12.97194 77.59369 10087.132 14762.088
356.0 Barddhaman 23.24056 87.86944 376.698 527.325
356.0 Bareilly 28.35 79.41667 1110.8 1598.249
356.0 Bathinda 30.2 74.95 321.079 464.734
356.0 Begusarai 25.41666667 86.13333333 361.544 656.714
356.0 Belgaum 15.85212 74.50447 660.357 915.889
356.0 Bellary 15.15 76.93333 456.788 654.007
356.0 Bhagalpur 25.25 87.0 438.792 604.919
356.0 Bhavnagar 21.76667 72.15 648.124 889.008
356.0 Bhilwara 25.35 74.63333 400.455 572.921
356.0 Bhiwandi 19.3 73.06667 792.708 1090.403
356.0 Bhopal 23.26667 77.4 2101.61 2958.671
356.0 Bhubaneswar 20.23333 85.83333 999.369 1439.127
356.0 Bihar Sharif 25.18333 85.51667 329.692 472.007
356.0 Bijapur 16.82442 75.71537 363.456 521.134
356.0 Bikaner 28.01667 73.3 705.838 984.356
356.0 Bilaspur 22.078278 82.14574 517.962 758.058
356.0 Bokaro Steel City 23.78732 85.95622 593.455 803.815
356.0 Brahmapur 19.31667 84.78333 388.2 545.753
356.0 Chandigarh 30.7343 76.7933 1134.471 1595.437
356.0 Chandrapur 19.95 79.3 331.266 443.223
356.0 Chennai (Madras) 13.053091 80.24875 9890.427 13920.944
356.0 Cherthala 9.683497 76.336654 592.578 975.124
356.0 Coimbatore 10.9925 76.96139 2548.564 3782.486
356.0 Cuttack 20.46497 85.87927 691.4 931.466
356.0 Darbhanga 26.16667 85.9 324.292 444.68
356.0 Davangere 14.460849 75.919871 469.362 651.571
356.0 Dehradun 30.31667 78.03333 812.28 1176.503
356.0 Delhi 28.66667 77.21667 25703.168 36060.1
356.0 Dewas 22.96667 76.06667 318.7 452.892
356.0 Dhanbad 23.8 86.45 1254.832 1679.921
356.0 Dhule 20.9 74.78333 391.559 527.207
356.0 Dindigul 10.36896 77.98036 345.873 524.984
356.0 Durgapur 23.520444 87.311923 623.344 857.695
356.0 Durg-Bhilainagar 21.188706 81.280592 1129.433 1529.287
356.0 English Bazar 25.0 88.15 379.319 568.835
356.0 Erode 11.3428 77.72741 589.792 852.577
356.0 Farrukhabad 27.39048 79.58006 313.589 437.591
356.0 Firozabad 27.15 78.41667 696.185 1022.992
356.0 Gaya 24.78333 85.0 507.575 703.593
356.0 Gorakhpur 26.759877 83.371379 723.061 969.271
356.0 Gulbarga 17.3333333 76.8333333 594.009 835.053
356.0 Guntur 16.3 80.45 755.76 1081.425
356.0 Guwahati (Gauhati) 26.173547 91.750291 1042.044 1429.977
356.0 Gwalior 26.22361 78.17917 1220.768 1717.826
356.0 Habra 22.83444 88.6275 337.511 482.116
356.0 Hardwar 29.96667 78.16667 359.395 533.923
356.0 Hisar 29.16667 75.71667 327.507 452.042
356.0 Hosur 12.716667 77.816667 352.261 678.939
356.0 Hubli-Dharwad 15.458722 75.010582 1019.789 1405.254
356.0 Hyderabad 17.37528 78.47444 8943.523 12773.548
356.0 Ichalakaranji 16.7 74.46667 344.112 470.32
356.0 Imphal 24.81667 93.95 517.635 821.824
356.0 Indore 22.71792 75.8333 2440.756 3459.176
356.0 Jabalpur 23.16697 79.95006 1336.565 1795.307
356.0 Jaipur 26.91667 75.81667 3460.701 4884.841
356.0 Jalandhar 31.3255556 75.5791667 954.435 1329.571
356.0 Jalgaon 21.009222 75.564353 506.058 714.083
356.0 Jalna 19.83333 75.88333 309.498 433.9
356.0 Jammu 32.727805 74.856879 670.973 888.519
356.0 Jamnagar 22.46667 70.06667 618.642 820.709
356.0 Jamshedpur 22.8 86.18333 1451.265 2000.075
356.0 Jhansi 25.43333 78.58333 590.416 814.673
356.0 Jodhpur 26.239232 73.015787 1284.142 1837.176
356.0 Junagadh 21.51667 70.46667 354.471 505.533
356.0 Kadapa 14.470955 78.824135 387.041 559.684
356.0 Kakinada 16.93333 82.21667 478.691 665.533
356.0 Kannur 11.872888 75.371554 2152.671 3512.758
356.0 Kanpur 26.46667 80.35 3020.795 3949.751
356.0 Karimnagar 18.43333 79.15 344.638 509.334
356.0 Kayamkulam 9.166577 76.504332 532.776 844.334
356.0 Kochi (Cochin) 9.930693 76.260069 2416.003 3465.39
356.0 Kolhapur 16.69563 74.23167 591.239 800.154
356.0 Kolkata (Calcutta) 22.533455 88.356045 14864.919 19092.461
356.0 Kollam 8.88056 76.59167 1409.717 2246.059
356.0 Korba 22.35 82.68333 388.13 532.821
356.0 Kota 25.16645 75.856095 1163.011 1710.339
356.0 Kottayam 9.58333 76.51667 420.768 633.707
356.0 Kozhikode (Calicut) 11.25669 75.778724 2476.192 3775.978
356.0 Kurnool 15.826681 78.035199 566.963 856.928
356.0 Latur 18.4 76.58333 424.573 605.464
356.0 Lucknow 26.85 80.91667 3221.817 4493.175
356.0 Ludhiana 30.9 75.85 1715.979 2316.065
356.0 Madurai 9.93333 78.11667 1593.148 2200.77
356.0 Malappuram 11.06667 76.06667 2215.874 3599.958
356.0 Malegaon 20.55 74.53333 667.009 983.841
356.0 Mangalore 12.91723 74.85603 657.355 895.161
356.0 Mathura 27.5 77.68333 529.052 786.02
356.0 Maunath Bhanjan 25.947485 83.558986 314.883 457.731
356.0 Meerut 28.97155 77.71934 1550.35 2139.862
356.0 Moradabad 28.83333 78.78333 1022.989 1492.586
356.0 Mumbai (Bombay) 19.073975 72.880838 21042.538 27796.555
356.0 Muzaffarnagar 29.46667 77.68333 587.023 887.303
356.0 Muzaffarpur 26.11667 85.4 438.546 627.538
356.0 Mysore 12.29791 76.63925 1082.304 1515.231
356.0 Nagpur 21.15 79.1 2675.072 3616.214
356.0 Nanded Waghala 19.161775 77.313728 611.119 868.384
356.0 Nashik 19.98333 73.8 1779.212 2556.422
356.0 Navsari 20.948507 72.930834 307.23 431.465
356.0 Nellore 14.44625 79.9842 649.717 954.45
356.0 Nizamabad 18.67154 78.0988 320.77 429.843
356.0 Palakkad 10.7725 76.65139 325.687 465.926
356.0 Panipat 29.38889 76.96806 486.087 686.248
356.0 Parbhani 19.26667 76.78333 330.069 458.408
356.0 Patiala 30.32667 76.40028 510.152 748.035
356.0 Patna 25.6 85.11667 2209.547 3015.626
356.0 Puducherry 11.93 79.83 730.11 1040.261
356.0 Pune (Poona) 18.516057 73.861578 5727.53 8091.387
356.0 Purnia 25.78333 87.46667 377.81 586.936
356.0 Raipur 21.23333 81.63333 1373.898 2116.316
356.0 Rajahmundry 17.003789 81.789447 511.15 702.972
356.0 Rajkot 22.3 70.78333 1599.232 2321.576
356.0 Rampur 28.806232 79.027699 382.367 539.653
356.0 Ranchi 23.35 85.33333 1262.011 1793.27
356.0 Ranipet 12.93148 79.332312 357.852 618.581
356.0 Raurkela 22.224891 84.86175 584.686 794.871
356.0 Rohtak 28.9 76.5666667 412.544 586.729
356.0 Roorkee 29.8666666667 77.88333333 396.581 724.367
356.0 Sagar 23.840472 78.738458 399.658 556.127
356.0 Saharanpur 29.96667 77.55 848.65 1297.351
356.0 Salem 11.65 78.16667 1002.68 1394.227
356.0 Sangali 16.85438 74.56417 544.585 742.529
356.0 Santipur 23.24722 88.43302 395.703 686.223
356.0 Satna 24.58333 80.83333 309.397 436.938
356.0 Shahjahanpur 27.88333 79.91667 356.028 474.605
356.0 Shillong 25.56892 91.88313 399.073 577.555
356.0 Shimoga 13.93157 75.56791 345.313 477.895
356.0 Siliguri 26.71611 88.42361 831.913 1251.975
356.0 Solapur 17.68333 75.91667 985.568 1307.324
356.0 Srinagar 34.083658 74.797363 1428.526 2030.072
356.0 Surat 21.16667 72.83333 5650.011 8616.41
356.0 Thanjavur 10.8 79.15 330.083 482.308
356.0 Thiruvananthapuram 8.50694 76.95694 1964.59 2878.291
356.0 Thoothukkudi (Tuticorin) 8.809046 78.136911 514.146 817.696
356.0 Thrissur 10.51667 76.21667 2329.122 3651.403
356.0 Tiruchirappalli 10.805 78.68556 1105.99 1525.26
356.0 Tirunelveli 8.73333 77.7 530.429 725.477
356.0 Tirupati 13.65 79.41667 549.902 837.673
356.0 Tiruppur 11.11541 77.35456 1230.309 1974.088
356.0 Tumkur 13.34222 77.10167 333.886 470.518
356.0 Udaipur 24.566108 73.691075 516.984 722.617
356.0 Ujjain 23.18333 75.76667 555.782 770.088
356.0 Vadodara 22.3 73.2 1975.092 2715.918
356.0 Varanasi (Benares) 25.316426 82.982198 1541.367 2102.385
356.0 Vellore 12.93333 79.13333 528.26 743.2
356.0 Vijayawada 16.51667 80.61667 1759.772 2613.799
356.0 Visakhapatnam 17.681874 83.209685 1935.252 2732.823
356.0 Warangal 18.0 79.58333 853.639 1222.206
356.0 Yamunanagar 30.1 77.28333 421.381 595.995
360.0 Ambon -3.69543 128.1814 425.228 679.174
360.0 Balikpapan -1.26753 116.82887 655.425 972.871
360.0 Bandar Lampung -5.4254 105.258 965.241 1349.615
360.0 Bandung -6.919393 107.608456 2543.742 3433.165
360.0 Banjarmasin -3.32442 114.591 682.12 955.166
360.0 Batam 1.119078 104.031275 1390.546 2485.897
360.0 Bengkulu -3.800278 102.265278 323.995 444.79
360.0 Bogor -6.606481 106.801891 1075.563 1540.953
360.0 Cirebon -6.7063 108.557 309.993 424.495
360.0 Denpasar -8.65 115.21667 1106.593 1870.432
360.0 Jakarta -6.211831 106.841646 10323.142 13811.975
360.0 Jambi -1.6 103.61667 604.088 874.154
360.0 Makassar (Ujung Pandang) -5.144396 119.423639 1488.63 2104.278
360.0 Malang -7.9797 112.6304 856.09 1155.595
360.0 Manado 1.487 124.8455 426.425 578.578
360.0 Mataram -8.58333 116.11667 456.8 662.498
360.0 Medan 3.58333 98.66667 2204.005 2955.229
360.0 Padang -0.94924 100.35427 903.224 1254.107
360.0 Palembang -2.91673 104.7458 1455.256 1888.054
360.0 Pekan Baru 0.53333 101.45 1120.893 1731.216
360.0 Pontianak -0.03333 109.33333 603.35 844.387
360.0 Samarinda -0.5 117.15 865.034 1290.906
360.0 Semarang -6.9932 110.4203 1629.599 2187.839
360.0 Sukabumi -6.91806 106.92667 326.294 461.769
360.0 Surabaya -7.288838 112.741078 2853.237 3760.157
360.0 Surakarta -7.55611 110.83167 504.211 667.908
360.0 Tasikmalaya -7.327905 108.216618 786.81 1304.627
360.0 Yogyakarta -7.78278 110.36083 384.59 503.306
364.0 Ahvaz 31.3203 48.6693 1215.782 1574.538
364.0 Arak 34.09174 49.68916 514.08 653.292
364.0 Ardabil 38.2498 48.2933 536.435 715.897
364.0 Bandar Abbas 27.1865 56.2808 482.769 643.045
364.0 Esfahan 32.65722 51.67761 1879.806 2364.039
364.0 Eslamshahr 35.562618 51.235883 414.472 530.298
364.0 Gorgan 36.84165 54.44361 377.106 522.122
364.0 Hamadan 34.79922 48.51456 562.889 720.81
364.0 Karaj 35.8355 51.0103 1807.058 2386.12
364.0 Kerman 30.28321 57.07879 549.565 673.994
364.0 Kermanshah 34.31417 47.065 896.144 1118.922
364.0 Khorramabad 33.48778 48.35583 359.391 445.329
364.0 Malard 35.665833 50.976667 347.041 503.401
364.0 Mashhad 36.297 59.6062 3014.424 3863.264
364.0 Orumiyeh 37.55274 45.07605 737.446 973.127
364.0 Qazvin 36.26877 50.0041 402.421 509.546
364.0 Qods 35.713011 51.105508 330.581 467.996
364.0 Qom 34.6401 50.8764 1204.115 1568.087
364.0 Rasht 37.28077 49.58319 708.7 938.166
364.0 Sanandaj 35.3144 46.9923 422.618 576.238
364.0 Sari 36.56332 53.06009 325.393 431.66
364.0 Shiraz 29.6036 52.5388 1660.545 2232.92
364.0 Tabriz 38.08 46.2919 1571.582 1943.276
364.0 Tehran 35.69439 51.42151 8432.196 9989.806
364.0 Yazd 31.89722 54.3675 530.362 693.775
364.0 Zahedan 29.4963 60.8629 556.385 656.406
364.0 Zanjan 36.6736 48.4787 416.901 540.121
368.0 Al-Basrah (Basra) 30.49721 47.81491 1019.109 1490.779
368.0 Al-Mawsil (Mosul) 36.335 43.1188889 1694.284 2585.541
368.0 Amara 31.834419 47.152446 442.856 667.092
368.0 Baaqoobah 33.75 44.6411111 424.776 665.542
368.0 Baghdad 33.34058 44.40088 6642.848 9710.309
368.0 Diwaniyah 31.99051 44.93063 404.85 615.204
368.0 Faloojah 33.35581 43.78612 322.781 511.661
368.0 Hillah 32.4825 44.4313889 506.935 787.6
368.0 Irbil (Erbil) 36.19257 44.01062 1165.714 1765.909
368.0 Karbala 32.5983333 44.0238889 687.834 1095.617
368.0 Kirkuk 35.4680556 44.3922222 649.965 944.706
368.0 Kut 32.5 45.8333333 364.488 561.494
368.0 Najaf 31.997314 44.331352 888.93 1372.694
368.0 Nasiriyah 31.0333333 46.2666667 577.123 886.558
368.0 Ramadi 33.4166667 43.3 369.514 584.982
368.0 Sulaimaniya 35.5616667 45.4408333 1003.782 1570.668
372.0 Dublin 53.33306 -6.24889 1169.371 1467.33
376.0 Be'er Sheva 31.25181 34.7913 594.462 733.159
376.0 Hefa (Haifa) 32.813261 34.991355 1096.669 1313.527
376.0 Jerusalem 31.76904 35.21633 839.077 1032.756
376.0 Tel Aviv-Yafo (Tel Aviv-Jaffa) 32.08088 34.78057 3608.265 4381.544
380.0 Bari 41.11773 16.85118 618.245 648.233
380.0 Barletta 41.31183 16.29077 338.784 359.475
380.0 Bergamo 45.69798 9.66895 839.584 913.757
380.0 Bologna 44.49381 11.33875 784.17 832.084
380.0 Brescia 45.52478 10.22727 463.072 503.218
380.0 Busto Arsizio 45.61128 8.84914 630.203 677.085
380.0 Cagliari 39.20738 9.13462 472.758 498.659
380.0 Caserta 41.08322 14.33493 419.814 448.06
380.0 Catania 37.50213 15.08719 582.168 610.991
380.0 Como 45.80998 9.08744 461.223 500.367
380.0 Florence 43.76667 11.25 700.76 735.339
380.0 Genova (Genoa) 44.40632 8.93386 691.698 709.617
380.0 Latina 41.46614 12.9043 417.682 465.201
380.0 Milano (Milan) 45.55307 9.18344 3098.974 3162.442
380.0 Modena 44.64783 10.92539 341.97 372.579
380.0 Napoli (Naples) 40.850178 14.259213 2201.789 2226.219
380.0 Nola 40.92201 14.53294 317.7 342.286
380.0 Padova 45.41519 11.88181 655.466 706.265
380.0 Palermo 38.11582 13.35976 853.369 882.388
380.0 Parma 44.80266 10.32898 314.188 343.976
380.0 Pescara 42.46024 14.21021 364.857 394.935
380.0 Reggio Emilia 44.69825 10.63125 343.803 382.109
380.0 Roma (Rome) 41.894743 12.481142 3717.956 3842.156
380.0 Salerno 40.67797 14.76599 413.837 439.841
380.0 Seregno 45.65238 9.20034 587.68 640.408
380.0 Taranto 40.4625 17.25972 458.862 482.589
380.0 Torino (Turin) 45.068672 7.677218 1764.868 1824.619
380.0 Treviso 45.66667 12.245 352.55 389.641
380.0 Venezia 45.43565 12.339589 628.04 662.486
380.0 Verona 45.43419 10.99779 605.55 651.947
380.0 Vicenza 45.55729 11.5409 313.447 342.33
388.0 Kingston 17.99702 -76.79358 587.652 664.307
392.0 Asahikawa 43.76778 142.37028 312.693 319.689
392.0 Chukyo M.M.A. (Nagoya) 35.18147 136.90641 9406.264 9304.101
392.0 Hiroshima 34.392823 132.460534 2173.249 2213.23
392.0 Kagoshima 31.570982 130.548469 490.109 505.796
392.0 Kanazawa 36.556368 136.642985 387.318 410.246
392.0 Kinki M.M.A. (Osaka) 34.675834 135.553823 20237.645 19975.677
392.0 Kitakyushu-Fukuoka M.M.A. 33.6064 130.4181 5510.478 5354.751
392.0 Kumamoto 32.78972 130.74167 600.958 636.142
392.0 Matsuyama 33.83239 132.75951 436.806 459.153
392.0 Nagasaki 32.750214 129.876176 316.029 319.192
392.0 Naha 26.21219 127.687286 321.102 339.65
392.0 Niigata 37.913894 139.032723 586.406 605.032
392.0 Oita 33.236487 131.609909 333.989 353.922
392.0 Okayama 34.650668 133.913478 501.995 538.043
392.0 Sapporo 43.06417 141.34694 2571.497 2541.854
392.0 Sendai 38.256047 140.897639 2090.856 2012.219
392.0 Shizuoka-Hamamatsu M.M.A. 34.9769 138.3831 3368.988 3933.539
392.0 Tokyo 35.6895 139.69171 38001.018 37190.489
392.0 Utsunomiya 36.56583 139.88361 391.166 411.168
400.0 Amman 31.95522 35.94503 1154.67 1355.224
400.0 Ar-Rusayfah 32.01555556 36.0427777778 394.553 557.03
400.0 Irbid 32.55556 35.85 305.925 380.961
400.0 Zarqa 32.068265 36.088935 449.007 541.579
398.0 Aktyubinsk 50.285462 57.162773 416.494 507.78
398.0 Almaty 43.247189 76.910127 1522.637 1730.429
398.0 Astana 51.1801 71.44598 758.961 931.715
398.0 Karaganda 49.801088 73.095428 495.625 562.04
398.0 Pavlodar 52.3 76.95 355.825 415.914
398.0 Semipalatinsk 50.42675 80.26669 337.54 396.308
398.0 Shimkent 42.3 69.6 746.303 915.755
398.0 Taraz 42.9 71.36667 308.855 329.089
398.0 Ust-Kamenogorsk 49.96466 82.60898 312.245 346.446
404.0 Eldoret 0.52036 35.26992 320.774 597.521
404.0 Mombasa -4.05466 39.66359 1103.703 1973.488
404.0 Nairobi -1.28333 36.81667 3914.791 7140.32
404.0 Nakuru -0.28333 36.06667 335.057 589.065
414.0 Al Kuwayt (Kuwait City) 29.353429 47.982244 2778.724 3914.503
417.0 Bishkek 42.87 74.59 865.193 1172.83
418.0 Vientiane 17.96667 102.6 996.566 1781.961
428.0 Riga 56.946 24.10589 620.847 506.023
422.0 Bayrut (Beirut) 33.9 35.48333 2226.478 2437.488
430.0 Monrovia 6.30054 -10.7969 1263.8 2032.297
434.0 Banghazi 32.11667 20.06667 745.625 937.013
434.0 Misratah 32.37535 15.09254 671.899 971.227
434.0 Tarabulus (Tripoli) 32.87519 13.18746 1126.145 1333.405
440.0 Vilnius 54.68916 25.2798 516.765 491.169
450.0 Antananarivo -18.91368 47.53613 2609.744 5072.578
450.0 Toamasina -18.16667 49.38333 326.792 653.959
454.0 Blantyre-Limbe -15.78499 35.00854 808.045 1472.575
454.0 Lilongwe -13.96692 33.78725 905.433 1748.403
458.0 Ipoh 4.583333 101.0833 736.704 998.24
458.0 Johor Bahru 1.4655 103.7578 911.562 1248.737
458.0 Kota Bharu 6.133333 102.25 322.144 433.195
458.0 Kota Kinabalu 5.978172 116.116577 477.647 672.919
458.0 Kuala Lumpur 3.1412 101.68653 6836.911 9422.889
458.0 Kuala Terengganu 5.3302 103.1408 348.708 476.487
458.0 Kuantan 3.8077 103.326 440.04 617.19
458.0 Kuching 1.55 110.33333 559.999 754.735
458.0 Sandakan 5.8402 118.1179 349.263 467.455
458.0 Seremban 2.7297 101.9381 422.037 584.706
466.0 Bamako 12.65 -8.0 2515.0 5231.087
478.0 Nouakchott 18.08581 -15.9785 967.54 1432.137
484.0 Acapulco de Juárez 16.86336 -99.8901 900.334 1074.991
484.0 Aguascalientes 21.88333 -102.3 1031.465 1287.006
484.0 Cancún 21.17429 -86.84656 844.705 1161.004
484.0 Celaya 20.51667 -100.81667 661.189 826.137
484.0 Chihuahua 28.63333 -106.08333 940.639 1172.964
484.0 Ciudad de México (Mexico City) 19.427318 -99.141869 20998.543 23864.706
484.0 Ciudad Juárez 31.73333 -106.48333 1390.387 1649.881
484.0 Ciudad Obregón 27.48333 -109.93333 331.801 422.983
484.0 Ciudad Victoria 23.73333 -99.13333 337.009 427.489
484.0 Coatzacoalcos 18.15 -94.41667 368.195 451.781
484.0 Colima 19.23333 -103.71667 367.081 462.983
484.0 Córdoba 18.88333 -96.93333 337.159 416.28
484.0 Cuautla Morelos 18.8 -98.95 467.806 579.067
484.0 Cuernavaca 18.91667 -99.25 993.161 1211.368
484.0 Culiacán 24.79944 -107.38972 761.574 968.769
484.0 Durango 24.03333 -104.66667 585.661 749.212
484.0 Guadalajara 20.66667 -103.33333 4843.241 5836.861
484.0 Hermosillo 29.084507 -110.967187 804.073 1020.185
484.0 Irapuato 20.6784 -101.3465 427.482 546.986
484.0 León de los Aldamas 21.123373 -101.680486 1806.862 2260.192
484.0 Matamoros 25.53333 -103.25 527.929 653.014
484.0 Mazatlán 23.240665 -106.414306 415.833 520.264
484.0 Mérida 20.96667 -89.61667 1067.71 1323.032
484.0 Mexicali 32.65194 -115.46833 1034.138 1288.094
484.0 Minatitlán 18.0013 -94.5581 373.122 453.474
484.0 Monclova 26.9 -101.41667 335.471 411.306
484.0 Monterrey 25.66667 -100.31667 4512.572 5471.43
484.0 Morelia 19.70078 -101.18443 914.484 1140.007
484.0 Nuevo Laredo 27.47629 -99.51639 425.622 539.374
484.0 Oaxaca de Juárez 17.05 -96.71667 667.784 834.339
484.0 Orizaba 18.85 -97.1 451.432 550.457
484.0 Pachuca de Soto 20.11697 -98.73329 596.328 781.14
484.0 Poza Rica de Hidalgo 20.53315 -97.45946 537.45 648.878
484.0 Puebla 19.041532 -98.204962 2984.048 3627.886
484.0 Puerto Vallarta 20.62041 -105.23066 471.121 650.773
484.0 Querétaro 20.6 -100.38333 1266.956 1629.5
484.0 Reynosa 26.08333 -98.28333 852.658 1116.778
484.0 Saltillo 25.41667 -101.0 932.446 1187.094
484.0 San Luis Potosí 22.15 -100.98333 1147.41 1425.741
484.0 Tampico 22.21667 -97.85 920.213 1121.312
484.0 Tehuacán 18.45 -97.38333 328.967 418.516
484.0 Tepic 21.5 -104.9 479.075 609.178
484.0 Tijuana 32.53333 -117.01667 1986.787 2501.785
484.0 Tlaxcala 19.31389 -98.24167 551.027 692.838
484.0 Toluca de Lerdo 19.283896 -99.657254 2164.006 2689.928
484.0 Torreón 25.539231 -103.461434 1332.257 1643.256
484.0 Tuxtla Gutierrez 16.75 -93.11667 779.512 999.736
484.0 Veracruz 19.2 -96.13333 879.634 1082.789
484.0 Villahermosa 17.98333 -92.91667 844.693 1066.184
484.0 Xalapa 19.537714 -96.913656 728.604 905.654
484.0 Zacatecas 22.77559 -102.57218 348.689 448.818
496.0 Ulaanbaatar 47.90771 106.88324 1377.308 1849.598
504.0 Agadir 30.424847 -9.593695 590.422 696.256
504.0 Dar-el-Beida (Casablanca) 33.59278 -7.61916 3514.958 4361.033
504.0 Fès 34.03715 -4.9998 1172.112 1558.832
504.0 Kénitra 34.26101 -6.5802 448.4 605.696
504.0 Marrakech 31.63148 -8.00828 1133.609 1571.539
504.0 Meknès 33.89352 -5.54727 716.339 985.392
504.0 Oujda 34.68052 -1.90764 495.099 665.29
504.0 Rabat 34.01325 -6.83255 1966.802 2574.491
504.0 Safi 32.29939 -9.23718 311.497 402.96
504.0 Tanger 35.784722 -5.812778 981.753 1391.041
504.0 Tétouan 35.57109 -5.37242 510.942 753.26
508.0 Beira -19.84361 34.83889 447.853 702.109
508.0 Maputo -25.96528 32.58917 1187.214 1893.44
508.0 Matola -25.96222 32.45889 937.176 1699.654
508.0 Nampula -15.11646 39.2666 649.633 1172.584
104.0 Bago 17.33667 96.47972 517.779 783.413
104.0 Mandalay 21.97473 96.08359 1166.906 1653.849
104.0 Mawlamyine 16.49051 97.62825 486.561 697.893
104.0 Monywa 22.11667 95.13333 478.083 747.804
104.0 Nay Pyi Taw 19.745 96.12972 1029.712 1398.12
104.0 Yangon 16.80528 96.15611 4801.93 6578.163
516.0 Windhoek -22.55941 17.08323 367.987 582.252
524.0 Kathmandu 27.70169 85.3206 1182.598 1854.781
524.0 Pokhara 28.233333 83.983333 329.424 549.238
528.0 Amsterdam 52.37403 4.88969 1090.772 1212.63
528.0 Eindhoven 51.44083 5.47778 334.79 377.425
528.0 Rotterdam 51.9225 4.47917 993.336 1076.647
528.0 s-Gravenhage (The Hague) 52.0767 4.2986 649.675 724.666
528.0 Utrecht 52.09083 5.12222 479.665 560.465
554.0 Auckland -36.86667 174.76667 1344.304 1573.705
554.0 Christchurch -43.53333 172.63333 351.214 397.598
554.0 Wellington -41.28664 174.77557 382.943 449.107
558.0 Managua 12.13282 -86.2504 956.233 1231.508
562.0 Niamey 13.51366 2.1098 1089.589 2363.23
562.0 Zinder 13.80716 8.9881 370.261 887.143
566.0 Aba 5.10658 7.36667 944.045 1675.276
566.0 Abakaliki 6.31625 8.11691 438.68 867.274
566.0 Abeokuta 7.15 3.35 494.705 836.846
566.0 Abuja 9.05735 7.48976 2440.242 4912.792
566.0 Ado-Ekiti 7.621 5.2215 402.044 739.62
566.0 Akure 7.25256 5.19312 556.29 1024.506
566.0 Bauchi 10.31344 9.84327 496.246 919.281
566.0 Benin City 6.33504 5.62749 1495.763 2667.293
566.0 Calabar 4.9517 8.322 466.815 886.213
566.0 Effon Alaiye 7.65 4.91667 328.576 594.253
566.0 Enugu 6.4402 7.4943 680.703 1200.584
566.0 Gboko 7.326835 9.003405 380.562 684.777
566.0 Gombe 10.28969 11.16729 417.107 780.92
566.0 Ibadan 7.38778 3.89639 3160.19 5498.728
566.0 Ife 7.477328 4.558853 331.012 583.303
566.0 Igbidu 6.068322 8.116942 402.336 705.546
566.0 Ikorodu 6.608716 3.510823 706.133 1414.429
566.0 Ilorin 8.5 4.55 856.914 1480.967
566.0 Jos 9.91667 8.9 810.09 1396.918
566.0 Kaduna 10.52224 7.43828 1047.815 1748.217
566.0 Kano 12.00012 8.51672 3587.049 6197.56
566.0 Katsina 12.98943 7.60063 394.812 724.498
566.0 Lagos 6.45306 3.39583 13122.829 24239.435
566.0 Lokoja 7.80236 6.743 472.75 1026.582
566.0 Maiduguri 11.84644 13.16027 727.525 1232.676
566.0 Makurdi 7.7411 8.5121 342.456 628.687
566.0 Minna 9.61389 6.55694 384.982 694.061
566.0 Nnewi 6.01986 6.91478 769.502 1576.494
566.0 Ogbomosho 8.132406 4.243307 439.483 842.111
566.0 Okene 7.550727 6.233654 407.106 722.282
566.0 Okpogho 6.440393 7.284425 342.791 669.453
566.0 Ondo 7.1 4.83333 376.974 671.568
566.0 Onitsha 6.14543 6.78845 1109.287 2146.972
566.0 Oshogbo 7.76667 4.56667 649.584 1115.63
566.0 Owerri 5.48333 7.03041 715.784 1337.422
566.0 Oyo 7.85 3.93333 370.948 663.731
566.0 Port Harcourt 4.77742 7.0134 2343.309 4562.459
566.0 Sokoto 13.06092 5.23902 552.352 992.718
566.0 Umuahia 5.52627 7.48959 579.844 1167.027
566.0 Uyo 5.05127 7.9335 847.483 1709.299
566.0 Warri 5.51667 5.75 663.005 1298.281
566.0 Zaria 11.11128 7.7227 702.79 1147.924
578.0 Oslo 59.91273 10.74609 986.093 1186.066
512.0 Masqat (Muscat) 23.61387 58.5922 838.019 1123.921
586.0 Bahawalpur 29.4 71.68333 913.008 1480.163
586.0 Dera Ghazikhan 30.05 70.6333333 349.832 547.193
586.0 Faisalabad 31.4166667 73.0833333 3566.952 5418.561
586.0 Gujranwala 32.15 74.1833333 2122.254 3273.549
586.0 Gujrat 32.5666667 74.0833333 405.788 614.324
586.0 Hyderabad 25.3666667 68.3666667 1772.143 2613.469
586.0 Islamabad 33.70351 73.059373 1364.531 2275.111
586.0 Jhang 31.267026 72.312594 438.572 651.734
586.0 Karachi 24.9056 67.0822 16617.644 24837.881
586.0 Kasur 31.115 74.4547222 377.382 566.749
586.0 Lahore 31.5497222 74.3436111 8741.365 13033.135
586.0 Larkana 27.55 68.2166667 596.086 964.603
586.0 Mardan 34.20195 72.05254 406.522 618.887
586.0 Multan 30.1833333 71.4833333 1920.776 2865.591
586.0 Nawabshah 26.25 68.4166667 330.759 514.221
586.0 Okara 30.8080556 73.4458333 318.346 480.47
586.0 Peshawar 34.00195 71.55944 1736.192 2639.81
586.0 Quetta 30.199 67.00971 1108.749 1739.793
586.0 Rahim Yar Khan 28.415126 70.299678 442.374 696.818
586.0 Rawalpindi 33.6 73.0666667 2505.889 3808.919
586.0 Sargodha 32.0833333 72.6666667 715.354 1069.18
586.0 Sheikhupura 31.7130556 73.9783333 528.174 831.195
586.0 Sialkot 32.5 74.5166667 579.222 843.079
586.0 Sukkur 27.7 68.8666667 572.576 877.862
586.0 Wah 33.764072 72.745029 323.742 491.813
591.0 Ciudad de Panamá (Panama City) 8.995816 -79.519572 1672.81 2221.467
598.0 Port Moresby -9.44314 147.17972 345.158 534.225
600.0 Asunción -25.30066 -57.63591 2356.174 3135.177
600.0 Ciudad del Este -25.51667 -54.61667 421.692 620.518
604.0 Arequipa -16.39889 -71.535 850.275 1067.376
604.0 Chiclayo -6.77361 -79.84167 596.273 757.745
604.0 Chimbote -9.08528 -78.57833 375.492 477.335
604.0 Cusco -13.51833 -71.97806 411.688 536.25
604.0 Huancayo -12.06667 -75.23333 363.714 463.337
604.0 Iquitos -3.737172 -73.25275 435.059 564.472
604.0 Lima -12.04318 -77.02824 9897.033 12221.301
604.0 Piura -5.2 -80.63333 444.129 577.002
604.0 Trujillo -8.11599 -79.02998 797.799 1023.641
608.0 Angeles City 15.15 120.58333 362.885 499.025
608.0 Bacolod 10.650723 122.945983 558.788 753.373
608.0 Baguio City 16.410801 120.590156 358.227 496.833
608.0 Basilan City (including City of Isabela) 6.70407 121.97117 423.858 570.188
608.0 Batangas City 13.75729 121.058643 339.561 467.068
608.0 Butuan 8.94917 125.54361 333.151 447.062
608.0 Cagayan de Oro City 8.48222 124.64722 687.949 958.018
608.0 Cebu City 10.31672 123.89071 950.559 1277.799
608.0 Cotabato 7.22361 124.24639 351.406 543.007
608.0 Davao City 7.073854 125.612487 1629.547 2216.228
608.0 General Santos City 6.11278 125.17167 615.559 859.249
608.0 Iligan 8.227401 124.242586 343.192 456.201
608.0 Iloilo City 10.696639 122.562855 457.15 611.336
608.0 Lapu-Lapu City 10.31028 123.94944 446.944 681.209
608.0 Lipa City 13.941883 121.162665 323.146 453.655
608.0 Mandaue City 10.32361 123.92222 374.402 521.073
608.0 Manila 14.6042 120.9822 12946.263 16755.63
608.0 Zamboanga City 6.910333 122.075045 935.769 1312.566
616.0 Bydgoszcz 53.1235 18.00762 359.17 375.809
616.0 Gdańsk 54.35205 18.64637 460.22 485.301
616.0 Katowice 50.25842 19.02754 303.024 314.182
616.0 Kraków (Cracow) 50.066777 19.942468 759.557 796.758
616.0 Łódź 51.759433 19.459957 702.965 707.303
616.0 Lublin 51.25 22.56667 345.504 362.634
616.0 Poznań 52.40692 16.92993 544.616 561.109
616.0 Szczecin 53.42894 14.55302 407.498 428.3
616.0 Warszawa (Warsaw) 52.22977 21.01178 1722.31 1791.269
616.0 Wrocław 51.1 17.03333 627.94 654.253
620.0 Lisboa (Lisbon) 38.71686 -9.139867 2884.297 3192.337
620.0 Porto 41.14961 -8.61099 1299.437 1442.997
630.0 Aguadilla-Isabela-San Sebastian 18.427701 -67.154397 303.03 313.895
630.0 San Juan 18.46633 -66.10572 2463.243 2468.182
634.0 Ad-Dawhah (Doha) 25.274724 51.524472 717.79 836.742
634.0 Ar-Rayyan 25.29194 51.42444 677.236 938.847
410.0 Ansan 37.32361 126.82194 775.81 876.791
410.0 Anyang 37.3925 126.92694 595.335 635.074
410.0 Bucheon 37.49889 126.78306 871.567 949.1
410.0 Busan 35.10278 129.04028 3216.298 3263.702
410.0 Changwon 35.22806 128.68111 1038.755 1089.769
410.0 Cheonan 36.813188 127.140955 488.003 589.01
410.0 Cheongju 36.63722 127.48972 692.599 768.105
410.0 Daegu 35.87028 128.59111 2244.086 2327.543
410.0 Daejon 36.32139 127.41972 1563.706 1711.075
410.0 Gimhae 35.23417 128.88111 305.985 342.677
410.0 Goyang 37.65639 126.835 942.437 1041.396
410.0 Gumi 36.119127 128.345482 363.098 417.071
410.0 Gwangju 35.146111 126.918611 1536.409 1681.672
410.0 Gwangmyeong 37.47722 126.86639 338.31 377.189
410.0 Incheon 37.45361 126.73167 2685.238 2918.919
410.0 Jeju 33.50972 126.52194 332.991 373.175
410.0 Jeonju 35.82194 127.14889 675.543 750.305
410.0 Pohang 36.017205 129.360216 346.282 389.827
410.0 Seongnam 37.43861 127.13778 968.337 1050.27
410.0 Seoul 37.56826 126.97783 9773.746 9959.675
410.0 Siheung 37.455619 126.902408 429.635 487.491
410.0 Suweon 37.26349 127.021385 1098.841 1194.662
410.0 Uijeongbu 37.7415 127.0474 436.786 491.866
410.0 Ulsan 35.53722 129.31667 904.239 975.453
410.0 Yongin 37.235245 127.203292 1047.815 1324.842
498.0 Chişinău 47.00556 28.8575 725.432 764.115
642.0 Bucuresti (Bucharest) 44.432787 26.104302 1867.724 1939.167
642.0 Cluj-Napoca 46.76667 23.6 327.26 358.8
642.0 Timisoara 45.74944 21.22722 320.015 348.793
643.0 Arkhangelsk 64.56 40.5333333 348.818 360.339
643.0 Astrakhan 46.34968 48.04076 526.782 544.759
643.0 Barnaul 53.36056 83.76361 615.475 630.405
643.0 Belgorod 50.61074 36.58015 366.562 387.245
643.0 Bryansk 53.25209 34.37167 405.12 360.99
643.0 Cheboksary 56.13222 47.25194 459.811 477.356
643.0 Chelyabinsk 55.15444 61.42972 1157.336 1187.421
643.0 Cherepovets 59.13333 37.9 311.275 321.458
643.0 Chita 52.03171 113.50087 327.239 340.945
643.0 Irkutsk 52.29778 104.29639 582.467 547.116
643.0 Ivanovo 56.99719 40.97139 393.42 338.107
643.0 Izhevsk 56.84976 53.20448 622.818 587.644
643.0 Kaliningrad, Kaliningrad Oblast 54.714258 20.510017 431.327 442.939
643.0 Kaluga 54.5293 36.27542 317.527 286.107
643.0 Kazan 55.78874 49.12214 1162.259 1184.834
643.0 Kemerovo 55.33333 86.08333 532.887 545.192
643.0 Khabarovsk 48.48272 135.08379 572.202 537.737
643.0 Kirov 58.603068 49.668173 481.765 501.123
643.0 Krasnodar 45.0488 38.9725 807.578 876.06
643.0 Krasnoyarsk 56.00972 92.79167 1008.374 1047.453
643.0 Kurgan 55.45 65.33333 325.459 291.031
643.0 Kursk 51.73733 36.18735 415.199 427.252
643.0 Lipetsk 52.60311 39.57076 508.782 521.054
643.0 Magnitogorsk 53.41861 59.04722 399.743 362.994
643.0 Makhachkala 42.97638 47.50236 641.821 720.297
643.0 Moskva (Moscow) 55.754996 37.621849 12165.704 12200.375
643.0 Naberezhnye Tchelny 55.72545 52.41122 513.255 525.676
643.0 Nizhniy Novgorod 56.32867 44.00205 1211.716 1060.074
643.0 Nizhny Tagil 57.91944 59.965 344.575 285.384
643.0 Novokuznetsk 53.7557 87.1099 544.549 516.616
643.0 Novosibirsk 55.0415 82.9346 1497.164 1517.051
643.0 Omsk 55.0 73.4 1161.893 1175.042
643.0 Orel 52.96508 36.0785 307.613 268.42
643.0 Orenburg 51.7727 55.0988 545.983 521.035
643.0 Penza 53.20066 45.00464 514.836 490.524
643.0 Perm 58.01741 56.28552 982.219 923.209
643.0 Rostov-na-Donu (Rostov-on-Don) 47.217791 39.703185 1096.597 1110.433
643.0 Ryazan 54.6269 39.6916 524.966 537.379
643.0 Samara 53.20006 50.15 1164.357 1170.585
643.0 Sankt Peterburg (Saint Petersburg) 59.929858 30.326228 4992.991 4955.347
643.0 Saratov 51.54056 46.00861 814.562 720.269
643.0 Smolensk 54.7818 32.0401 326.517 337.471
643.0 Sochi 43.59917 39.72569 350.817 368.973
643.0 Stavropol 45.0428 41.9734 425.138 461.568
643.0 Surgut 61.258749 73.424407 318.631 340.546
643.0 Tolyatti 53.5303 49.3461 727.591 746.21
643.0 Tomsk 56.49417 84.97417 545.577 576.561
643.0 Tula 54.20213 37.64429 516.984 543.337
643.0 Tver 56.86049 35.87603 398.724 371.08
643.0 Tyumen 57.15222 65.52722 625.705 678.011
643.0 Ufa 54.78517 56.04562 1070.272 1085.041
643.0 Ulan-Ude 51.82605 107.60979 431.719 468.827
643.0 Ulyanovsk 54.32824 48.38657 600.589 539.388
643.0 Vladikavkaz 43.03667 44.66778 308.596 289.207
643.0 Vladimir 56.13655 40.39658 362.272 389.181
643.0 Vladivostok 43.10562 131.87353 590.082 600.76
643.0 Volgograd 48.71939 44.50184 1022.487 1032.257
643.0 Vologda 59.2187 39.8886 306.034 320.806
643.0 Volzhsky 48.78583 44.77973 315.246 327.229
643.0 Voronezh 51.67204 39.1843 911.225 940.015
643.0 Yakutsk 62.03389 129.73306 311.229 363.562
643.0 Yaroslavl 57.62987 39.87368 576.888 515.427
643.0 Yekaterinburg 56.8575 60.6125 1379.038 1406.616
646.0 Kigali -1.947364 30.057897 1256.994 2267.541
682.0 Ad-Dammam 26.43442 50.10326 1064.418 1321.315
682.0 Al-Madinah (Medina) 24.463501 39.611106 1280.248 1569.683
682.0 Ar-Riyadh (Riyadh) 24.690466 46.709566 6369.71 7940.087
682.0 Buraydah 26.32599 43.97497 559.723 710.403
682.0 Hafar al-Batin 28.425078 45.96883 309.809 382.204
682.0 Ha'il 27.52188 41.69073 352.75 432.595
682.0 Hufuf-Mubarraz 25.41 49.58083 743.248 895.167
682.0 Jiddah 21.51694 39.21917 4075.803 4988.057
682.0 Jubayl 27.01122 49.65826 488.376 717.814
682.0 Khamis Mushayt 18.30639 42.72917 485.594 589.599
682.0 Makkah (Mecca) 21.417368 39.815855 1770.6 2145.795
682.0 Najran 17.4924 44.12766 350.083 440.663
682.0 Tabuk 28.38333 36.58333 580.31 705.032
682.0 Taif 21.27028 40.41583 631.216 743.117
686.0 Dakar 14.6937 -17.44406 3520.215 6045.685
688.0 Beograd (Belgrade) 44.817649 20.463309 1181.81 1196.109
694.0 Freetown 8.484 -13.22994 1007.14 1470.312
702.0 Singapore 1.28967 103.85007 5618.866 6577.884
703.0 Bratislava 48.14816 17.10674 400.67 404.066
706.0 Berbera 10.43959 45.01432 383.21 651.866
706.0 Hargeysa 9.56 44.065 759.587 1287.879
706.0 Kismaayo -0.366667 42.533333 366.178 616.535
706.0 Merca 1.71594 44.77166 511.228 868.946
706.0 Muqdisho (Mogadishu) 2.041636 45.343492 2137.839 4176.11
710.0 Bloemfontein -29.12106 26.214 503.013 622.744
710.0 Cape Town -33.92584 18.42322 3660.447 4321.625
710.0 Durban -29.8579 31.0292 2900.927 3349.433
710.0 East London -33.01529 27.91162 319.304 397.141
710.0 Johannesburg -26.20227 28.04363 9398.698 11573.129
710.0 Pietermaritzburg -29.61678 30.39278 494.828 587.714
710.0 Port Elizabeth -33.91799 25.57007 1178.729 1389.716
710.0 Pretoria -25.74486 28.18783 2058.789 2701.345
710.0 Rustenburg -25.66756 27.24208 382.716 544.001
710.0 Soshanguve -25.47288 28.09919 774.59 934.706
710.0 Vereeniging -26.67313 27.92615 1155.14 1370.144
710.0 Witbank -25.87133 29.23323 371.398 511.917
728.0 Juba 4.85165 31.58247 321.115 596.192
724.0 Alicante 38.34517 -0.48149 346.237 396.62
724.0 Barcelona 41.38879 2.15899 5258.319 5685.152
724.0 Bilbao 43.26271 -2.92528 350.835 379.938
724.0 Cordoba 37.88333 -4.76667 335.024 371.778
724.0 Las Palmas Gran Canaria 28.110696 -15.434283 390.19 433.084
724.0 Madrid 40.4165 -3.70256 6199.254 6707.421
724.0 Malaga 36.72016 -4.42034 573.808 631.201
724.0 Murcia 37.98704 -1.13004 463.468 532.034
724.0 Palma 39.56939 2.65024 428.859 496.963
724.0 Sevilla 37.38241 -5.97613 700.89 753.368
724.0 Valencia 39.46975 -0.37739 810.044 885.722
724.0 Valladolid 41.65518 -4.72372 309.022 332.918
724.0 Zaragoza 41.65606 -0.87734 700.544 776.608
144.0 Colombo 6.93194 79.84778 706.648 844.884
275.0 Gaza (incl. Ash Shati Camp) 31.510618 34.458756 623.913 941.223
729.0 Al Gadarif 14.03493 35.38344 317.669 510.305
729.0 Al Obeid (Al Ubayyid) 13.18416667 30.2166666667 419.835 684.813
729.0 Al-Khartum (Khartoum) 15.55177 32.53241 5129.358 8158.384
729.0 Kassala 15.45099 36.39998 335.293 524.047
729.0 Nyala 12.05 24.88333 714.149 1278.634
729.0 Port Sudan (Bur Sudan) 19.619521 37.21238 444.451 694.389
729.0 Wad Medani 14.40118 33.51989 336.753 536.676
752.0 Göteborg 57.703161 11.966273 585.859 694.79
752.0 Stockholm 59.33258 18.0649 1485.68 1757.468
756.0 Basel 47.5584 7.57327 507.764 603.522
756.0 Bern 46.94809 7.44744 358.481 424.896
756.0 Genève 46.20222 6.14569 557.806 682.203
756.0 Lausanne 46.516 6.63282 352.642 429.327
756.0 Zürich (Zurich) 47.35785 8.50296 1246.199 1493.733
760.0 Al-Hasakah 36.50237 40.74772 557.704 955.994
760.0 Al-Kamishli 37.05215 41.23142 378.264 583.512
760.0 Al-Raqqa 35.95 39.01667 736.313 1248.325
760.0 Deir El-Zor(Deir ez-Zor) 35.332233 40.150155 413.671 651.844
760.0 Dimashq (Damascus) 33.508586 36.308444 2565.67 3450.513
760.0 Halab (Aleppo) 36.213611 37.157141 3561.796 5086.929
760.0 Hamah 35.13179 36.75783 1236.537 2002.853
760.0 Hims (Homs) 34.731809 36.718125 1641.298 2471.05
760.0 Lattakia 35.51484 35.77684 780.933 1155.237
760.0 Tartus 34.893201 35.88844 595.445 1007.057
762.0 Dushanbe 38.53575 68.77905 822.331 1270.514
807.0 Skopje 42.0 21.43333 502.655 528.349
764.0 Chon Buri 13.361125 100.988319 518.103 796.26
764.0 Hat Yai 7.0083 100.4767 317.694 430.363
764.0 Krung Thep (Bangkok) 13.721964 100.525248 9269.823 11527.934
764.0 Lampang 18.29232 99.49277 382.281 576.281
764.0 Nakhon Ratchasima 14.97066 102.10196 367.929 505.365
764.0 Nonthaburi 13.860208 100.521782 409.173 526.232
764.0 Rayong 12.68095 101.25798 332.195 526.833
764.0 Samut Prakan 13.59934 100.59675 1814.046 3139.358
764.0 Udon Thani 17.41567 102.78589 526.401 772.441
768.0 Lomé 6.13748 1.21227 956.332 1601.626
788.0 Safaqis 34.748471 10.756162 714.4 912.234
788.0 Tunis 36.81897 10.16579 1993.487 2347.008
792.0 Adana 37.00167 35.32889 1829.555 2350.675
792.0 Ankara 39.91987 32.85427 4749.968 5874.551
792.0 Antalya 36.90812 30.69556 1072.386 1380.699
792.0 Batman 37.88738 41.13221 365.488 470.112
792.0 Bursa 40.19167 29.06111 1922.517 2464.6
792.0 Denizli 37.77417 29.0875 557.936 709.863
792.0 Diyarbakir 37.91583 40.21889 926.275 1130.681
792.0 Elazig 38.67431 39.22321 363.481 457.281
792.0 Erzurum 39.90861 41.27694 382.124 448.647
792.0 Eskisehir 39.77667 30.52056 704.798 893.867
792.0 Gaziantep 37.05944 37.3825 1528.366 1955.173
792.0 Gebze 40.80276 29.43068 609.088 795.67
792.0 Istanbul 41.0138 28.9497 14163.989 16694.313
792.0 Izmir 38.41273 27.13838 3040.416 3700.674
792.0 Izmit 40.774765 29.949082 307.441 362.489
792.0 Kahramanmaras 37.5847 36.9264 455.205 574.216
792.0 Kayseri 38.73222 35.48528 904.245 1118.506
792.0 Konya 37.87135 32.48464 1194.383 1542.142
792.0 Malatya 38.35 38.316667 431.342 514.767
792.0 Manisa 38.61202 27.42646 325.43 413.184
792.0 Mersin 36.8 34.633333 853.652 1104.007
792.0 Sakarya 40.773758 30.402377 473.2 614.34
792.0 Samsun 41.2833333 36.3333333 565.158 731.662
792.0 Sanliurfa 37.16708 38.79392 555.302 704.279
792.0 Sivas 39.75 37.0333333 351.817 445.72
792.0 Van 38.5 43.3833333 409.583 521.877
795.0 Ashgabat 37.95 58.38333 745.961 942.418
795.0 Tashauz 41.83625 59.96662 310.022 419.845
800.0 Kampala 0.31628 32.58219 1935.654 3939.07
804.0 Dnipropetrovsk 48.45 34.98333 956.654 821.44
804.0 Donetsk 48.023 37.80224 934.147 838.636
804.0 Kharkiv 49.98081 36.25272 1440.839 1392.551
804.0 Krivoi Rog 47.91083 33.392491 681.248 704.414
804.0 Kyiv (Kiev) 50.445368 30.518634 2941.884 3037.714
804.0 Lugansk 48.56705 39.31706 419.328 371.821
804.0 Lvov 49.837969 24.032508 735.397 755.757
804.0 Makeyevka 48.04782 37.92576 331.644 274.295
804.0 Mariupol 47.06667 37.5 450.884 405.046
804.0 Nikolaev 46.96591 31.9974 492.005 463.756
804.0 Odesa 46.47747 30.73262 1010.475 1031.231
804.0 Sevastopol 44.58883 33.5224 334.556 323.005
804.0 Simferopol 44.95719 34.11079 333.302 318.41
804.0 Vinnitsa 49.23278 28.48097 371.299 391.755
804.0 Zaporizhzhya 47.82289 35.19031 753.237 684.667
784.0 Abu Zaby (Abu Dhabi) 24.464778 54.361781 1144.933 1607.821
784.0 Ajman 25.41111 55.43504 323.043 452.871
784.0 Al-Ain 24.19167 55.76056 447.299 567.812
784.0 Dubayy (Dubai) 25.272061 55.311265 2414.591 3470.592
784.0 Sharjah 25.35731 55.4033 1279.36 1890.154
826.0 Belfast 54.594668 -5.929812 605.163 682.97
826.0 Birkenhead 53.39337 -3.01479 327.833 372.188
826.0 Birmingham (West Midlands) 52.4814 -1.8998 2514.596 2808.296
826.0 Bournemouth/Poole 50.72048 -1.8795 482.9 558.379
826.0 Brighton-Worthing-Littlehampton 50.82838 -0.13947 496.686 567.342
826.0 Bristol 51.4552 -2.5966 648.143 755.079
826.0 Cardiff 51.48 -3.18 468.264 547.223
826.0 Coventry-Bedworth 52.4066 -1.5122 369.534 425.854
826.0 Edinburgh 55.9521 -3.1965 494.71 566.993
826.0 Glasgow 55.86515 -4.25763 1222.955 1360.23
826.0 Kingston upon Hull 53.748257 -0.334021 319.702 366.544
826.0 Leicester 52.6386 -1.1317 535.803 627.926
826.0 Liverpool 53.41058 -2.97794 870.26 970.032
826.0 London 51.50853 -0.12574 10313.307 11467.322
826.0 Manchester 53.48095 -2.23743 2645.598 2967.799
826.0 Newcastle upon Tyne 54.97328 -1.61396 790.653 893.632
826.0 Newport 51.58471 -2.997939 313.904 361.632
826.0 Nottingham 52.9536 -1.15047 755.012 864.934
826.0 Preston 53.761025 -2.702435 324.596 378.126
826.0 Reading-Wokingham 51.4112 -0.8356 325.353 374.603
826.0 Sheffield 53.38297 -1.4659 705.781 806.229
826.0 Southampton/Portsmouth (South Hampshire) 50.911698 -1.40357 882.065 1004.633
826.0 Southend-On-Sea 51.53782 0.71433 304.344 353.236
826.0 Stoke-on-Trent (The Potteries) 53.0042 -2.1854 377.458 429.28
826.0 Sunderland 54.9119 -1.3833 334.785 376.504
826.0 Swansea 51.6208 -3.9432 309.328 358.687
826.0 Teeside (Middlesbrough) 54.57623 -1.23483 381.78 434.515
826.0 West Yorkshire 53.798431 -1.764855 1912.493 2234.68
834.0 Arusha -3.36667 36.68333 443.871 816.326
834.0 Dar es Salaam -6.82349 39.26951 5115.67 10759.575
834.0 Mbeya -8.9 33.45 444.365 914.23
834.0 Morogoro -6.81667 37.66667 340.755 667.499
834.0 Mwanza -2.51667 32.9 837.86 1793.192
834.0 Zanzibar -6.16394 39.19793 569.158 1144.477
840.0 Akron 41.08144 -81.51901 567.661 636.569
840.0 Albany 42.66 -73.78 613.043 703.97
840.0 Albuquerque 35.110703 -106.609991 826.787 1002.767
840.0 Allentown-Bethlehem 40.60908 -75.475962 713.978 843.867
840.0 Ann Arbor 42.27756 -83.74088 317.407 370.455
840.0 Antioch 38.0 -121.81 314.4 392.171
840.0 Asheville 35.579862 -82.55581 316.604 393.739
840.0 Atlanta 33.76 -84.4 5142.14 6140.49
840.0 Augusta-Richmond County 33.467086 -81.990199 415.382 495.424
840.0 Austin 30.27 -97.74 1684.433 2181.545
840.0 Bakersfield 35.357276 -119.031661 604.614 756.415
840.0 Baltimore 39.29038 -76.61219 2266.981 2542.507
840.0 Baton Rouge 30.45075 -91.15455 663.232 807.813
840.0 Birmingham 33.515744 -86.801056 796.463 931.963
840.0 Boise City 43.619505 -116.212301 397.07 494.331
840.0 Bonita Springs-Naples 26.33981 -81.7787 369.123 476.56
840.0 Boston 42.347919 -71.06453 4249.036 4671.29
840.0 Bridgeport-Stamford 41.16704 -73.20483 939.307 1060.508
840.0 Buffalo 42.887934 -78.871593 912.955 999.061
840.0 Cape Coral 26.6396 -81.982471 677.385 913.323
840.0 Charleston-North Charleston 32.789295 -79.986255 625.867 776.074
840.0 Charlotte 35.22709 -80.84313 1615.57 2165.939
840.0 Chattanooga 35.045473 -85.267255 401.271 471.777
840.0 Chicago 41.85003 -87.65005 8744.835 9493.032
840.0 Cincinnati 39.104722 -84.518783 1687.514 1915.934
840.0 Cleveland 41.498587 -81.687402 1772.872 1948.003
840.0 Colorado Springs 38.863443 -104.791914 613.579 738.622
840.0 Columbia, South Carolina 33.999477 -81.036538 630.484 784.57
840.0 Columbus, Ohio 39.962205 -83.000186 1505.041 1788.21
840.0 Concord 37.97798 -122.03107 650.099 759.408
840.0 Corpus Christi 27.742857 -97.401927 333.743 390.749
840.0 Dallas-Fort Worth 32.72541 -97.32085 5702.641 6682.913
840.0 Dayton 39.758406 -84.192906 733.18 828.355
840.0 Daytona Beach-Port Orange 29.1383165 -80.9956105 409.729 522.74
840.0 Denton-Lewisville 33.04669 -96.994063 405.314 494.785
840.0 Denver-Aurora 39.734283 -104.983138 2599.351 3048.482
840.0 Des Moines 41.60054 -93.60911 496.779 603.049
840.0 Detroit 42.387137 -83.102641 3639.05 3886.329
840.0 Durham 35.988644 -78.907167 382.537 465.404
840.0 El Paso 31.7775757 -106.4424559 876.991 1045.804
840.0 Fayetteville 35.066663 -78.917579 328.726 389.628
840.0 Fayetteville-Springdale 36.186711 -94.129539 389.175 542.667
840.0 Flint 43.027577 -83.693996 350.786 393.005
840.0 Fort Wayne 41.078348 -85.126546 326.96 383.008
840.0 Fresno 36.754529 -119.771119 711.61 848.692
840.0 Grand Rapids 42.956393 -85.664883 585.185 670.724
840.0 Greensboro 36.073233 -79.791751 336.61 404.509
840.0 Greenville 34.849805 -82.397334 462.567 581.793
840.0 Harrisburg 40.271709 -76.884956 492.794 600.314
840.0 Hartford 41.7637111 -72.6850932 962.996 1106.024
840.0 Honolulu 21.30895 -157.826182 847.986 987.005
840.0 Houston 29.7601927 -95.3693896 5638.045 6728.797
840.0 Huntsville 34.729703 -86.589848 333.614 424.35
840.0 Indianapolis 39.790942 -86.147685 1645.658 1960.581
840.0 Indio-Cathedral City-Palm Springs 33.719871 -116.231889 403.936 513.84
840.0 Jackson, Mississippi 32.295719 -90.184034 385.679 468.13
840.0 Jacksonville, Florida 30.33218 -81.65565 1171.962 1398.493
840.0 Kansas City 39.11417 -94.62746 1604.389 1846.073
840.0 Kissimmee 28.30468 -81.41667 410.764 568.634
840.0 Knoxville 35.960749 -83.927657 646.67 810.003
840.0 Lancaster 40.0378755 -76.3055144 448.969 550.822
840.0 Lancaster-Palmdale 34.686854 -118.150931 411.908 536.715
840.0 Lansing 42.728422 -84.551367 319.987 368.888
840.0 Las Vegas 36.169941 -115.13983 2270.187 2866.652
840.0 Lexington-Fayette 38.029632 -84.494642 312.294 374.812
840.0 Little Rock 34.742048 -92.275359 472.565 570.873
840.0 Los Angeles-Long Beach-Santa Ana 34.031656 -118.241716 12309.53 13256.838
840.0 Louisville 38.24194 -85.763064 1031.932 1200.78
840.0 Madison 43.069698 -89.400114 444.133 540.9
840.0 McAllen 26.216263 -98.236385 863.945 1096.366
840.0 Memphis 35.140814 -90.047458 1106.083 1269.357
840.0 Miami 25.789097 -80.204044 5817.221 6553.633
840.0 Milwaukee 43.0389 -87.90647 1409.316 1587.809
840.0 Minneapolis-St. Paul 44.97307 -93.269895 2791.224 3174.602
840.0 Mission Viejo 33.60002 -117.672 610.369 708.815
840.0 Mobile 30.69436 -88.04305 329.9 377.527
840.0 Modesto 37.661479 -120.994543 384.558 459.182
840.0 Nashville-Davidson 36.160996 -86.783045 1105.476 1356.517
840.0 New Haven 41.3019 -72.929857 578.497 663.707
840.0 New Orleans 29.95465 -90.07507 921.27 1045.619
840.0 New York-Newark 40.717042 -74.003663 18593.22 19885.263
840.0 Ogden-Layton 41.223 -111.97383 625.976 778.862
840.0 Oklahoma City 35.4675 -97.516389 925.506 1089.088
840.0 Omaha 41.25861111 -95.93777778 780.19 921.958
840.0 Orlando 28.53834 -81.37924 1730.587 2115.084
840.0 Oxnard 34.1975 -119.17705 382.75 446.9
840.0 Palm Bay-Melbourne 28.05902778 -80.59833333 486.011 577.877
840.0 Pensacola 30.42131 -87.21691 347.984 401.386
840.0 Philadelphia 39.95234 -75.16379 5585.211 6157.522
840.0 Phoenix-Mesa 33.449454 -112.074743 4062.605 4808.348
840.0 Pittsburgh 40.441823 -79.98823 1719.343 1884.46
840.0 Port St. Lucie 27.29393 -80.35033 445.052 570.542
840.0 Portland 45.521525 -122.679933 2000.852 2335.566
840.0 Poughkeepsie-Newburgh 41.60180556 -73.96555556 465.242 563.318
840.0 Providence 41.824037 -71.417702 1196.451 1332.539
840.0 Provo-Orem 40.23384 -111.65853 613.098 824.354
840.0 Raleigh 35.778897 -78.637471 1139.77 1532.708
840.0 Reno 39.52963 -119.8138 446.831 556.618
840.0 Richmond 37.543207 -77.438159 1029.581 1213.971
840.0 Riverside-San Bernardino 33.95335 -117.39616 2194.298 2652.762
840.0 Rochester 43.156924 -77.604633 732.692 830.448
840.0 Rockford 42.271254 -89.095727 310.856 365.559
840.0 Round Lake Beach-McHenry-Grayslake 42.354045 -88.100529 329.375 411.041
840.0 Sacramento 38.58157 -121.4944 1920.353 2293.936
840.0 Salt Lake City 40.7547 -111.892622 1095.726 1284.451
840.0 San Antonio 29.424113 -98.493536 2029.842 2488.403
840.0 San Diego 32.71533 -117.15726 3107.034 3521.974
840.0 San Francisco-Oakland 37.759881 -122.437392 3300.075 3615.239
840.0 San Jose 37.33939 -121.89496 1729.674 1963.794
840.0 Santa Clarita 34.39166 -118.54259 320.55 427.879
840.0 Santa Rosa 38.44047 -122.71443 320.018 373.734
840.0 Sarasota-Bradenton 27.33643 -82.53065 690.12 815.361
840.0 Scranton 41.410629 -75.667411 378.605 426.103
840.0 Seattle 47.626353 -122.333144 3248.724 3708.977
840.0 Shreveport 32.468003 -93.771115 310.319 363.12
840.0 Spokane 47.673341 -117.410271 417.612 499.022
840.0 Springfield, Massachusett, Connecticut 42.10148 -72.5898 646.013 746.258
840.0 Springfield, Missouri 37.208264 -93.291368 309.615 385.966
840.0 St. Louis 38.628612 -90.197197 2183.942 2427.014
840.0 Stockton 37.9577016 -121.2907796 403.353 486.218
840.0 Syracuse 43.046788 -76.147496 416.583 474.454
840.0 Tampa-St. Petersburg 27.94752 -82.45843 2659.134 3104.875
840.0 Temecula-Murrieta 33.53635 -117.16305 618.801 896.208
840.0 The Woodlands 30.16299 -95.45577 400.096 665.681
840.0 Toledo 41.656529 -83.549856 508.767 573.954
840.0 Trenton 40.2170534 -74.7429384 312.928 369.989
840.0 Tucson 32.214476 -110.918192 912.778 1080.604
840.0 Tulsa 36.131294 -95.937332 710.746 846.071
840.0 Victorville-Hesperia-Apple Valley 34.533991 -117.295848 423.71 580.192
840.0 Virginia Beach 36.834498 -76.087179 1459.945 1631.995
840.0 Washington, D.C. 38.89511 -77.03637 4955.139 5689.846
840.0 Wichita 37.688848 -97.336226 500.273 588.082
840.0 Winston-Salem 36.102764 -80.260491 448.289 560.983
840.0 Worcester 42.262599 -71.802347 517.572 610.619
840.0 Youngstown 41.096258 -80.649299 371.892 408.181
858.0 Montevideo -34.83346 -56.16735 1706.831 1860.296
860.0 Andizhan 40.7830556 72.3438889 402.299 537.378
860.0 Namangan 40.9983 71.67257 521.42 716.815
860.0 Samarkand 39.6541667 66.9597222 363.907 464.42
860.0 Tashkent 41.26465 69.21627 2251.156 2838.539
862.0 Acarigua-Aruare 9.55451 -69.19564 309.047 395.323
862.0 Barcelona-Puerto La Cruz 10.21667 -64.61667 710.084 893.344
862.0 Barinas 8.62261 -70.20749 333.198 439.82
862.0 Barquisimeto 10.07389 -69.32278 1038.556 1228.225
862.0 Cabimas 10.38828 -71.43992 357.214 465.674
862.0 Caracas 10.48801 -66.87919 2916.183 3346.811
862.0 Ciudad Bolivar 8.12923 -63.54086 385.473 486.401
862.0 Ciudad Guayana 8.35122 -62.64102 695.724 841.319
862.0 Cumana 10.46354 -64.1775 336.46 423.423
862.0 El Tigre-San José de Guanipa 8.88724 -64.16512 367.702 509.584
862.0 Guarenas-Guatire 10.46736 -66.60663 379.472 476.167
862.0 Lagunillas 10.13008 -71.25946 349.567 487.344
862.0 Maracaibo 10.63167 -71.64056 2196.435 2676.708
862.0 Maracay 10.24694 -67.59583 1165.922 1449.657
862.0 Maturin 9.75 -63.17667 558.23 751.545
862.0 Merida 8.59524 -71.1434 324.429 403.306
862.0 Punto Fijo 11.6956 -70.19957 321.191 424.587
862.0 San Cristóbal 7.76694 -72.225 370.572 454.577
862.0 Valencia 10.16202 -68.00765 1733.641 2106.92
704.0 Bien Hoa 10.95 106.81667 834.29 1224.784
704.0 Can Tho 10.03333 105.78333 1174.693 1901.886
704.0 Da Nang 16.051264 108.212426 952.141 1365.43
704.0 Hà Noi 21.0245 105.84117 3629.493 5497.921
704.0 Hai Phòng 20.86481 106.68345 1075.499 1568.535
704.0 Hue 16.46667 107.6 353.916 495.441
704.0 Nha Trang 12.25 109.18333 312.515 413.748
704.0 Thành Pho Ho Chí Minh (Ho Chi Minh City) 10.75 106.66667 7297.78 10200.392
704.0 Vungtau 10.34599 107.08426 351.451 512.271
887.0 Adan (Aden) 12.798803 45.035902 881.54 1438.126
887.0 Al-Hudaydah 14.79781 42.95452 568.265 902.928
887.0 Al-Mukalla 14.54248 49.12424 363.26 663.727
887.0 Ibb 13.96667 44.18333 451.881 844.632
887.0 Sana'a' 15.353115 44.20782 2961.934 5070.944
887.0 Ta'izz 13.57952 44.02091 694.672 1132.298
894.0 Kitwe -12.8166667 28.2 589.79 1117.245
894.0 Lusaka -15.413374 28.277148 2179.47 4364.817
894.0 Ndola -12.95867 28.63659 499.429 897.23
716.0 Bulawayo -20.15 28.58333 647.704 868.091
716.0 Chitungwiza -18.01274 31.07555 367.424 522.502
716.0 Harare -17.82935 31.05389 1501.363 2048.423
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
// https://d3js.org/d3-dispatch/ Version 1.0.2. Copyright 2016 Mike Bostock.
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.d3 = global.d3 || {})));
}(this, (function (exports) { 'use strict';
var noop = {value: function() {}};
function dispatch() {
for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
_[t] = [];
}
return new Dispatch(_);
}
function Dispatch(_) {
this._ = _;
}
function parseTypenames(typenames, types) {
return typenames.trim().split(/^|\s+/).map(function(t) {
var name = "", i = t.indexOf(".");
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
return {type: t, name: name};
});
}
Dispatch.prototype = dispatch.prototype = {
constructor: Dispatch,
on: function(typename, callback) {
var _ = this._,
T = parseTypenames(typename + "", _),
t,
i = -1,
n = T.length;
// If no callback was specified, return the callback of the given type and name.
if (arguments.length < 2) {
while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
return;
}
// If a type was specified, set the callback for the given type and name.
// Otherwise, if a null callback was specified, remove callbacks of the given name.
if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
while (++i < n) {
if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
}
return this;
},
copy: function() {
var copy = {}, _ = this._;
for (var t in _) copy[t] = _[t].slice();
return new Dispatch(copy);
},
call: function(type, that) {
if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
},
apply: function(type, that, args) {
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
}
};
function get(type, name) {
for (var i = 0, n = type.length, c; i < n; ++i) {
if ((c = type[i]).name === name) {
return c.value;
}
}
}
function set(type, name, callback) {
for (var i = 0, n = type.length; i < n; ++i) {
if (type[i].name === name) {
type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
break;
}
}
if (callback != null) type.push({name: name, value: callback});
return type;
}
exports.dispatch = dispatch;
Object.defineProperty(exports, '__esModule', { value: true });
})));
},{}],2:[function(require,module,exports){
// https://d3js.org/d3-drag/ Version 1.0.2. Copyright 2016 Mike Bostock.
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-selection')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-dispatch', 'd3-selection'], factory) :
(factory((global.d3 = global.d3 || {}),global.d3,global.d3));
}(this, (function (exports,d3Dispatch,d3Selection) { 'use strict';
function nopropagation() {
d3Selection.event.stopImmediatePropagation();
}
var noevent = function() {
d3Selection.event.preventDefault();
d3Selection.event.stopImmediatePropagation();
};
var nodrag = function(view) {
var root = view.document.documentElement,
selection = d3Selection.select(view).on("dragstart.drag", noevent, true);
if ("onselectstart" in root) {
selection.on("selectstart.drag", noevent, true);
} else {
root.__noselect = root.style.MozUserSelect;
root.style.MozUserSelect = "none";
}
};
function yesdrag(view, noclick) {
var root = view.document.documentElement,
selection = d3Selection.select(view).on("dragstart.drag", null);
if (noclick) {
selection.on("click.drag", noevent, true);
setTimeout(function() { selection.on("click.drag", null); }, 0);
}
if ("onselectstart" in root) {
selection.on("selectstart.drag", null);
} else {
root.style.MozUserSelect = root.__noselect;
delete root.__noselect;
}
}
var constant = function(x) {
return function() {
return x;
};
};
function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch$$1) {
this.target = target;
this.type = type;
this.subject = subject;
this.identifier = id;
this.active = active;
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
this._ = dispatch$$1;
}
DragEvent.prototype.on = function() {
var value = this._.on.apply(this._, arguments);
return value === this._ ? this : value;
};
// Ignore right-click, since that should open the context menu.
function defaultFilter() {
return !d3Selection.event.button;
}
function defaultContainer() {
return this.parentNode;
}
function defaultSubject(d) {
return d == null ? {x: d3Selection.event.x, y: d3Selection.event.y} : d;
}
var drag = function() {
var filter = defaultFilter,
container = defaultContainer,
subject = defaultSubject,
gestures = {},
listeners = d3Dispatch.dispatch("start", "drag", "end"),
active = 0,
mousemoving,
touchending;
function drag(selection) {
selection
.on("mousedown.drag", mousedowned)
.on("touchstart.drag", touchstarted)
.on("touchmove.drag", touchmoved)
.on("touchend.drag touchcancel.drag", touchended)
.style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
}
function mousedowned() {
if (touchending || !filter.apply(this, arguments)) return;
var gesture = beforestart("mouse", container.apply(this, arguments), d3Selection.mouse, this, arguments);
if (!gesture) return;
d3Selection.select(d3Selection.event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
nodrag(d3Selection.event.view);
nopropagation();
mousemoving = false;
gesture("start");
}
function mousemoved() {
noevent();
mousemoving = true;
gestures.mouse("drag");
}
function mouseupped() {
d3Selection.select(d3Selection.event.view).on("mousemove.drag mouseup.drag", null);
yesdrag(d3Selection.event.view, mousemoving);
noevent();
gestures.mouse("end");
}
function touchstarted() {
if (!filter.apply(this, arguments)) return;
var touches = d3Selection.event.changedTouches,
c = container.apply(this, arguments),
n = touches.length, i, gesture;
for (i = 0; i < n; ++i) {
if (gesture = beforestart(touches[i].identifier, c, d3Selection.touch, this, arguments)) {
nopropagation();
gesture("start");
}
}
}
function touchmoved() {
var touches = d3Selection.event.changedTouches,
n = touches.length, i, gesture;
for (i = 0; i < n; ++i) {
if (gesture = gestures[touches[i].identifier]) {
noevent();
gesture("drag");
}
}
}
function touchended() {
var touches = d3Selection.event.changedTouches,
n = touches.length, i, gesture;
if (touchending) clearTimeout(touchending);
touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
for (i = 0; i < n; ++i) {
if (gesture = gestures[touches[i].identifier]) {
nopropagation();
gesture("end");
}
}
}
function beforestart(id, container, point, that, args) {
var p = point(container, id), s, dx, dy,
sublisteners = listeners.copy();
if (!d3Selection.customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
if ((d3Selection.event.subject = s = subject.apply(that, args)) == null) return false;
dx = s.x - p[0] || 0;
dy = s.y - p[1] || 0;
return true;
})) return;
return function gesture(type) {
var p0 = p, n;
switch (type) {
case "start": gestures[id] = gesture, n = active++; break;
case "end": delete gestures[id], --active; // nobreak
case "drag": p = point(container, id), n = active; break;
}
d3Selection.customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]);
};
}
drag.filter = function(_) {
return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), drag) : filter;
};
drag.container = function(_) {
return arguments.length ? (container = typeof _ === "function" ? _ : constant(_), drag) : container;
};
drag.subject = function(_) {
return arguments.length ? (subject = typeof _ === "function" ? _ : constant(_), drag) : subject;
};
drag.on = function() {
var value = listeners.on.apply(listeners, arguments);
return value === listeners ? drag : value;
};
return drag;
};
exports.drag = drag;
exports.dragDisable = nodrag;
exports.dragEnable = yesdrag;
Object.defineProperty(exports, '__esModule', { value: true });
})));
},{"d3-dispatch":1,"d3-selection":4}],3:[function(require,module,exports){
// https://d3js.org/d3-path/ Version 1.0.3. Copyright 2016 Mike Bostock.
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.d3 = global.d3 || {})));
}(this, (function (exports) { 'use strict';
var pi = Math.PI;
var tau = 2 * pi;
var epsilon = 1e-6;
var tauEpsilon = tau - epsilon;
function Path() {
this._x0 = this._y0 = // start of current subpath
this._x1 = this._y1 = null; // end of current subpath
this._ = "";
}
function path() {
return new Path;
}
Path.prototype = path.prototype = {
constructor: Path,
moveTo: function(x, y) {
this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
},
closePath: function() {
if (this._x1 !== null) {
this._x1 = this._x0, this._y1 = this._y0;
this._ += "Z";
}
},
lineTo: function(x, y) {
this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
},
quadraticCurveTo: function(x1, y1, x, y) {
this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
},
bezierCurveTo: function(x1, y1, x2, y2, x, y) {
this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
},
arcTo: function(x1, y1, x2, y2, r) {
x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
var x0 = this._x1,
y0 = this._y1,
x21 = x2 - x1,
y21 = y2 - y1,
x01 = x0 - x1,
y01 = y0 - y1,
l01_2 = x01 * x01 + y01 * y01;
// Is the radius negative? Error.
if (r < 0) throw new Error("negative radius: " + r);
// Is this path empty? Move to (x1,y1).
if (this._x1 === null) {
this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1);
}
// Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
else if (!(l01_2 > epsilon)) {}
// Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
// Equivalently, is (x1,y1) coincident with (x2,y2)?
// Or, is the radius zero? Line to (x1,y1).
else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {
this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1);
}
// Otherwise, draw an arc!
else {
var x20 = x2 - x0,
y20 = y2 - y0,
l21_2 = x21 * x21 + y21 * y21,
l20_2 = x20 * x20 + y20 * y20,
l21 = Math.sqrt(l21_2),
l01 = Math.sqrt(l01_2),
l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
t01 = l / l01,
t21 = l / l21;
// If the start tangent is not coincident with (x0,y0), line to.
if (Math.abs(t01 - 1) > epsilon) {
this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
}
this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21);
}
},
arc: function(x, y, r, a0, a1, ccw) {
x = +x, y = +y, r = +r;
var dx = r * Math.cos(a0),
dy = r * Math.sin(a0),
x0 = x + dx,
y0 = y + dy,
cw = 1 ^ ccw,
da = ccw ? a0 - a1 : a1 - a0;
// Is the radius negative? Error.
if (r < 0) throw new Error("negative radius: " + r);
// Is this path empty? Move to (x0,y0).
if (this._x1 === null) {
this._ += "M" + x0 + "," + y0;
}
// Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {
this._ += "L" + x0 + "," + y0;
}
// Is this arc empty? We’re done.
if (!r) return;
// Is this a complete circle? Draw two arcs to complete the circle.
if (da > tauEpsilon) {
this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0);
}
// Otherwise, draw an arc!
else {
if (da < 0) da = da % tau + tau;
this._ += "A" + r + "," + r + ",0," + (+(da >= pi)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1));
}
},
rect: function(x, y, w, h) {
this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
},
toString: function() {
return this._;
}
};
exports.path = path;
Object.defineProperty(exports, '__esModule', { value: true });
})));
},{}],4:[function(require,module,exports){
// https://d3js.org/d3-selection/ Version 1.0.2. Copyright 2016 Mike Bostock.
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.d3 = global.d3 || {})));
}(this, function (exports) { 'use strict';
var xhtml = "http://www.w3.org/1999/xhtml";
var namespaces = {
svg: "http://www.w3.org/2000/svg",
xhtml: xhtml,
xlink: "http://www.w3.org/1999/xlink",
xml: "http://www.w3.org/XML/1998/namespace",
xmlns: "http://www.w3.org/2000/xmlns/"
};
function namespace(name) {
var prefix = name += "", i = prefix.indexOf(":");
if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;
}
function creatorInherit(name) {
return function() {
var document = this.ownerDocument,
uri = this.namespaceURI;
return uri === xhtml && document.documentElement.namespaceURI === xhtml
? document.createElement(name)
: document.createElementNS(uri, name);
};
}
function creatorFixed(fullname) {
return function() {
return this.ownerDocument.createElementNS(fullname.space, fullname.local);
};
}
function creator(name) {
var fullname = namespace(name);
return (fullname.local
? creatorFixed
: creatorInherit)(fullname);
}
var nextId = 0;
function local() {
return new Local;
}
function Local() {
this._ = "@" + (++nextId).toString(36);
}
Local.prototype = local.prototype = {
constructor: Local,
get: function(node) {
var id = this._;
while (!(id in node)) if (!(node = node.parentNode)) return;
return node[id];
},
set: function(node, value) {
return node[this._] = value;
},
remove: function(node) {
return this._ in node && delete node[this._];
},
toString: function() {
return this._;
}
};
var matcher = function(selector) {
return function() {
return this.matches(selector);
};
};
if (typeof document !== "undefined") {
var element = document.documentElement;
if (!element.matches) {
var vendorMatches = element.webkitMatchesSelector
|| element.msMatchesSelector
|| element.mozMatchesSelector
|| element.oMatchesSelector;
matcher = function(selector) {
return function() {
return vendorMatches.call(this, selector);
};
};
}
}
var matcher$1 = matcher;
var filterEvents = {};
exports.event = null;
if (typeof document !== "undefined") {
var element$1 = document.documentElement;
if (!("onmouseenter" in element$1)) {
filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
}
}
function filterContextListener(listener, index, group) {
listener = contextListener(listener, index, group);
return function(event) {
var related = event.relatedTarget;
if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
listener.call(this, event);
}
};
}
function contextListener(listener, index, group) {
return function(event1) {
var event0 = exports.event; // Events can be reentrant (e.g., focus).
exports.event = event1;
try {
listener.call(this, this.__data__, index, group);
} finally {
exports.event = event0;
}
};
}
function parseTypenames(typenames) {
return typenames.trim().split(/^|\s+/).map(function(t) {
var name = "", i = t.indexOf(".");
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
return {type: t, name: name};
});
}
function onRemove(typename) {
return function() {
var on = this.__on;
if (!on) return;
for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
this.removeEventListener(o.type, o.listener, o.capture);
} else {
on[++i] = o;
}
}
if (++i) on.length = i;
else delete this.__on;
};
}
function onAdd(typename, value, capture) {
var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
return function(d, i, group) {
var on = this.__on, o, listener = wrap(value, i, group);
if (on) for (var j = 0, m = on.length; j < m; ++j) {
if ((o = on[j]).type === typename.type && o.name === typename.name) {
this.removeEventListener(o.type, o.listener, o.capture);
this.addEventListener(o.type, o.listener = listener, o.capture = capture);
o.value = value;
return;
}
}
this.addEventListener(typename.type, listener, capture);
o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
if (!on) this.__on = [o];
else on.push(o);
};
}
function selection_on(typename, value, capture) {
var typenames = parseTypenames(typename + ""), i, n = typenames.length, t;
if (arguments.length < 2) {
var on = this.node().__on;
if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
for (i = 0, o = on[j]; i < n; ++i) {
if ((t = typenames[i]).type === o.type && t.name === o.name) {
return o.value;
}
}
}
return;
}
on = value ? onAdd : onRemove;
if (capture == null) capture = false;
for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
return this;
}
function customEvent(event1, listener, that, args) {
var event0 = exports.event;
event1.sourceEvent = exports.event;
exports.event = event1;
try {
return listener.apply(that, args);
} finally {
exports.event = event0;
}
}
function sourceEvent() {
var current = exports.event, source;
while (source = current.sourceEvent) current = source;
return current;
}
function point(node, event) {
var svg = node.ownerSVGElement || node;
if (svg.createSVGPoint) {
var point = svg.createSVGPoint();
point.x = event.clientX, point.y = event.clientY;
point = point.matrixTransform(node.getScreenCTM().inverse());
return [point.x, point.y];
}
var rect = node.getBoundingClientRect();
return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
}
function mouse(node) {
var event = sourceEvent();
if (event.changedTouches) event = event.changedTouches[0];
return point(node, event);
}
function none() {}
function selector(selector) {
return selector == null ? none : function() {
return this.querySelector(selector);
};
}
function selection_select(select) {
if (typeof select !== "function") select = selector(select);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
if ("__data__" in node) subnode.__data__ = node.__data__;
subgroup[i] = subnode;
}
}
}
return new Selection(subgroups, this._parents);
}
function empty() {
return [];
}
function selectorAll(selector) {
return selector == null ? empty : function() {
return this.querySelectorAll(selector);
};
}
function selection_selectAll(select) {
if (typeof select !== "function") select = selectorAll(select);
for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
subgroups.push(select.call(node, node.__data__, i, group));
parents.push(node);
}
}
}
return new Selection(subgroups, parents);
}
function selection_filter(match) {
if (typeof match !== "function") match = matcher$1(match);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
subgroup.push(node);
}
}
}
return new Selection(subgroups, this._parents);
}
function sparse(update) {
return new Array(update.length);
}
function selection_enter() {
return new Selection(this._enter || this._groups.map(sparse), this._parents);
}
function EnterNode(parent, datum) {
this.ownerDocument = parent.ownerDocument;
this.namespaceURI = parent.namespaceURI;
this._next = null;
this._parent = parent;
this.__data__ = datum;
}
EnterNode.prototype = {
constructor: EnterNode,
appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
querySelector: function(selector) { return this._parent.querySelector(selector); },
querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
};
function constant(x) {
return function() {
return x;
};
}
var keyPrefix = "$"; // Protect against keys like “__proto__”.
function bindIndex(parent, group, enter, update, exit, data) {
var i = 0,
node,
groupLength = group.length,
dataLength = data.length;
// Put any non-null nodes that fit into update.
// Put any null nodes into enter.
// Put any remaining data into enter.
for (; i < dataLength; ++i) {
if (node = group[i]) {
node.__data__ = data[i];
update[i] = node;
} else {
enter[i] = new EnterNode(parent, data[i]);
}
}
// Put any non-null nodes that don’t fit into exit.
for (; i < groupLength; ++i) {
if (node = group[i]) {
exit[i] = node;
}
}
}
function bindKey(parent, group, enter, update, exit, data, key) {
var i,
node,
nodeByKeyValue = {},
groupLength = group.length,
dataLength = data.length,
keyValues = new Array(groupLength),
keyValue;
// Compute the key for each node.
// If multiple nodes have the same key, the duplicates are added to exit.
for (i = 0; i < groupLength; ++i) {
if (node = group[i]) {
keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
if (keyValue in nodeByKeyValue) {
exit[i] = node;
} else {
nodeByKeyValue[keyValue] = node;
}
}
}
// Compute the key for each datum.
// If there a node associated with this key, join and add it to update.
// If there is not (or the key is a duplicate), add it to enter.
for (i = 0; i < dataLength; ++i) {
keyValue = keyPrefix + key.call(parent, data[i], i, data);
if (node = nodeByKeyValue[keyValue]) {
update[i] = node;
node.__data__ = data[i];
nodeByKeyValue[keyValue] = null;
} else {
enter[i] = new EnterNode(parent, data[i]);
}
}
// Add any remaining nodes that were not bound to data to exit.
for (i = 0; i < groupLength; ++i) {
if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
exit[i] = node;
}
}
}
function selection_data(value, key) {
if (!value) {
data = new Array(this.size()), j = -1;
this.each(function(d) { data[++j] = d; });
return data;
}
var bind = key ? bindKey : bindIndex,
parents = this._parents,
groups = this._groups;
if (typeof value !== "function") value = constant(value);
for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
var parent = parents[j],
group = groups[j],
groupLength = group.length,
data = value.call(parent, parent && parent.__data__, j, parents),
dataLength = data.length,
enterGroup = enter[j] = new Array(dataLength),
updateGroup = update[j] = new Array(dataLength),
exitGroup = exit[j] = new Array(groupLength);
bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
// Now connect the enter nodes to their following update node, such that
// appendChild can insert the materialized enter node before this node,
// rather than at the end of the parent node.
for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
if (previous = enterGroup[i0]) {
if (i0 >= i1) i1 = i0 + 1;
while (!(next = updateGroup[i1]) && ++i1 < dataLength);
previous._next = next || null;
}
}
}
update = new Selection(update, parents);
update._enter = enter;
update._exit = exit;
return update;
}
function selection_exit() {
return new Selection(this._exit || this._groups.map(sparse), this._parents);
}
function selection_merge(selection) {
for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
if (node = group0[i] || group1[i]) {
merge[i] = node;
}
}
}
for (; j < m0; ++j) {
merges[j] = groups0[j];
}
return new Selection(merges, this._parents);
}
function selection_order() {
for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
if (node = group[i]) {
if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
next = node;
}
}
}
return this;
}
function selection_sort(compare) {
if (!compare) compare = ascending;
function compareNode(a, b) {
return a && b ? compare(a.__data__, b.__data__) : !a - !b;
}
for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
if (node = group[i]) {
sortgroup[i] = node;
}
}
sortgroup.sort(compareNode);
}
return new Selection(sortgroups, this._parents).order();
}
function ascending(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
function selection_call() {
var callback = arguments[0];
arguments[0] = this;
callback.apply(null, arguments);
return this;
}
function selection_nodes() {
var nodes = new Array(this.size()), i = -1;
this.each(function() { nodes[++i] = this; });
return nodes;
}
function selection_node() {
for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
var node = group[i];
if (node) return node;
}
}
return null;
}
function selection_size() {
var size = 0;
this.each(function() { ++size; });
return size;
}
function selection_empty() {
return !this.node();
}
function selection_each(callback) {
for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
if (node = group[i]) callback.call(node, node.__data__, i, group);
}
}
return this;
}
function attrRemove(name) {
return function() {
this.removeAttribute(name);
};
}
function attrRemoveNS(fullname) {
return function() {
this.removeAttributeNS(fullname.space, fullname.local);
};
}
function attrConstant(name, value) {
return function() {
this.setAttribute(name, value);
};
}
function attrConstantNS(fullname, value) {
return function() {
this.setAttributeNS(fullname.space, fullname.local, value);
};
}
function attrFunction(name, value) {
return function() {
var v = value.apply(this, arguments);
if (v == null) this.removeAttribute(name);
else this.setAttribute(name, v);
};
}
function attrFunctionNS(fullname, value) {
return function() {
var v = value.apply(this, arguments);
if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
else this.setAttributeNS(fullname.space, fullname.local, v);
};
}
function selection_attr(name, value) {
var fullname = namespace(name);
if (arguments.length < 2) {
var node = this.node();
return fullname.local
? node.getAttributeNS(fullname.space, fullname.local)
: node.getAttribute(fullname);
}
return this.each((value == null
? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
? (fullname.local ? attrFunctionNS : attrFunction)
: (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
}
function defaultView(node) {
return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
|| (node.document && node) // node is a Window
|| node.defaultView; // node is a Document
}
function styleRemove(name) {
return function() {
this.style.removeProperty(name);
};
}
function styleConstant(name, value, priority) {
return function() {
this.style.setProperty(name, value, priority);
};
}
function styleFunction(name, value, priority) {
return function() {
var v = value.apply(this, arguments);
if (v == null) this.style.removeProperty(name);
else this.style.setProperty(name, v, priority);
};
}
function selection_style(name, value, priority) {
var node;
return arguments.length > 1
? this.each((value == null
? styleRemove : typeof value === "function"
? styleFunction
: styleConstant)(name, value, priority == null ? "" : priority))
: defaultView(node = this.node())
.getComputedStyle(node, null)
.getPropertyValue(name);
}
function propertyRemove(name) {
return function() {
delete this[name];
};
}
function propertyConstant(name, value) {
return function() {
this[name] = value;
};
}
function propertyFunction(name, value) {
return function() {
var v = value.apply(this, arguments);
if (v == null) delete this[name];
else this[name] = v;
};
}
function selection_property(name, value) {
return arguments.length > 1
? this.each((value == null
? propertyRemove : typeof value === "function"
? propertyFunction
: propertyConstant)(name, value))
: this.node()[name];
}
function classArray(string) {
return string.trim().split(/^|\s+/);
}
function classList(node) {
return node.classList || new ClassList(node);
}
function ClassList(node) {
this._node = node;
this._names = classArray(node.getAttribute("class") || "");
}
ClassList.prototype = {
add: function(name) {
var i = this._names.indexOf(name);
if (i < 0) {
this._names.push(name);
this._node.setAttribute("class", this._names.join(" "));
}
},
remove: function(name) {
var i = this._names.indexOf(name);
if (i >= 0) {
this._names.splice(i, 1);
this._node.setAttribute("class", this._names.join(" "));
}
},
contains: function(name) {
return this._names.indexOf(name) >= 0;
}
};
function classedAdd(node, names) {
var list = classList(node), i = -1, n = names.length;
while (++i < n) list.add(names[i]);
}
function classedRemove(node, names) {
var list = classList(node), i = -1, n = names.length;
while (++i < n) list.remove(names[i]);
}
function classedTrue(names) {
return function() {
classedAdd(this, names);
};
}
function classedFalse(names) {
return function() {
classedRemove(this, names);
};
}
function classedFunction(names, value) {
return function() {
(value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
};
}
function selection_classed(name, value) {
var names = classArray(name + "");
if (arguments.length < 2) {
var list = classList(this.node()), i = -1, n = names.length;
while (++i < n) if (!list.contains(names[i])) return false;
return true;
}
return this.each((typeof value === "function"
? classedFunction : value
? classedTrue
: classedFalse)(names, value));
}
function textRemove() {
this.textContent = "";
}
function textConstant(value) {
return function() {
this.textContent = value;
};
}
function textFunction(value) {
return function() {
var v = value.apply(this, arguments);
this.textContent = v == null ? "" : v;
};
}
function selection_text(value) {
return arguments.length
? this.each(value == null
? textRemove : (typeof value === "function"
? textFunction
: textConstant)(value))
: this.node().textContent;
}
function htmlRemove() {
this.innerHTML = "";
}
function htmlConstant(value) {
return function() {
this.innerHTML = value;
};
}
function htmlFunction(value) {
return function() {
var v = value.apply(this, arguments);
this.innerHTML = v == null ? "" : v;
};
}
function selection_html(value) {
return arguments.length
? this.each(value == null
? htmlRemove : (typeof value === "function"
? htmlFunction
: htmlConstant)(value))
: this.node().innerHTML;
}
function raise() {
if (this.nextSibling) this.parentNode.appendChild(this);
}
function selection_raise() {
return this.each(raise);
}
function lower() {
if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
}
function selection_lower() {
return this.each(lower);
}
function selection_append(name) {
var create = typeof name === "function" ? name : creator(name);
return this.select(function() {
return this.appendChild(create.apply(this, arguments));
});
}
function constantNull() {
return null;
}
function selection_insert(name, before) {
var create = typeof name === "function" ? name : creator(name),
select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
return this.select(function() {
return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
});
}
function remove() {
var parent = this.parentNode;
if (parent) parent.removeChild(this);
}
function selection_remove() {
return this.each(remove);
}
function selection_datum(value) {
return arguments.length
? this.property("__data__", value)
: this.node().__data__;
}
function dispatchEvent(node, type, params) {
var window = defaultView(node),
event = window.CustomEvent;
if (event) {
event = new event(type, params);
} else {
event = window.document.createEvent("Event");
if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
else event.initEvent(type, false, false);
}
node.dispatchEvent(event);
}
function dispatchConstant(type, params) {
return function() {
return dispatchEvent(this, type, params);
};
}
function dispatchFunction(type, params) {
return function() {
return dispatchEvent(this, type, params.apply(this, arguments));
};
}
function selection_dispatch(type, params) {
return this.each((typeof params === "function"
? dispatchFunction
: dispatchConstant)(type, params));
}
var root = [null];
function Selection(groups, parents) {
this._groups = groups;
this._parents = parents;
}
function selection() {
return new Selection([[document.documentElement]], root);
}
Selection.prototype = selection.prototype = {
constructor: Selection,
select: selection_select,
selectAll: selection_selectAll,
filter: selection_filter,
data: selection_data,
enter: selection_enter,
exit: selection_exit,
merge: selection_merge,
order: selection_order,
sort: selection_sort,
call: selection_call,
nodes: selection_nodes,
node: selection_node,
size: selection_size,
empty: selection_empty,
each: selection_each,
attr: selection_attr,
style: selection_style,
property: selection_property,
classed: selection_classed,
text: selection_text,
html: selection_html,
raise: selection_raise,
lower: selection_lower,
append: selection_append,
insert: selection_insert,
remove: selection_remove,
datum: selection_datum,
on: selection_on,
dispatch: selection_dispatch
};
function select(selector) {
return typeof selector === "string"
? new Selection([[document.querySelector(selector)]], [document.documentElement])
: new Selection([[selector]], root);
}
function selectAll(selector) {
return typeof selector === "string"
? new Selection([document.querySelectorAll(selector)], [document.documentElement])
: new Selection([selector == null ? [] : selector], root);
}
function touch(node, touches, identifier) {
if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
if ((touch = touches[i]).identifier === identifier) {
return point(node, touch);
}
}
return null;
}
function touches(node, touches) {
if (touches == null) touches = sourceEvent().touches;
for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {
points[i] = point(node, touches[i]);
}
return points;
}
exports.creator = creator;
exports.local = local;
exports.matcher = matcher$1;
exports.mouse = mouse;
exports.namespace = namespace;
exports.namespaces = namespaces;
exports.select = select;
exports.selectAll = selectAll;
exports.selection = selection;
exports.selector = selector;
exports.selectorAll = selectorAll;
exports.touch = touch;
exports.touches = touches;
exports.window = defaultView;
exports.customEvent = customEvent;
Object.defineProperty(exports, '__esModule', { value: true });
}));
},{}],5:[function(require,module,exports){
// https://d3js.org/d3-shape/ Version 1.0.4. Copyright 2016 Mike Bostock.
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-path')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-path'], factory) :
(factory((global.d3 = global.d3 || {}),global.d3));
}(this, (function (exports,d3Path) { 'use strict';
var constant$1 = function(x) {
return function constant() {
return x;
};
};
var epsilon = 1e-12;
var pi = Math.PI;
var halfPi = pi / 2;
var tau = 2 * pi;
function arcInnerRadius(d) {
return d.innerRadius;
}
function arcOuterRadius(d) {
return d.outerRadius;
}
function arcStartAngle(d) {
return d.startAngle;
}
function arcEndAngle(d) {
return d.endAngle;
}
function arcPadAngle(d) {
return d && d.padAngle; // Note: optional!
}
function asin(x) {
return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);
}
function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
var x10 = x1 - x0, y10 = y1 - y0,
x32 = x3 - x2, y32 = y3 - y2,
t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);
return [x0 + t * x10, y0 + t * y10];
}
// Compute perpendicular offset line of length rc.
// http://mathworld.wolfram.com/Circle-LineIntersection.html
function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
var x01 = x0 - x1,
y01 = y0 - y1,
lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01),
ox = lo * y01,
oy = -lo * x01,
x11 = x0 + ox,
y11 = y0 + oy,
x10 = x1 + ox,
y10 = y1 + oy,
x00 = (x11 + x10) / 2,
y00 = (y11 + y10) / 2,
dx = x10 - x11,
dy = y10 - y11,
d2 = dx * dx + dy * dy,
r = r1 - rc,
D = x11 * y10 - x10 * y11,
d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)),
cx0 = (D * dy - dx * d) / d2,
cy0 = (-D * dx - dy * d) / d2,
cx1 = (D * dy + dx * d) / d2,
cy1 = (-D * dx + dy * d) / d2,
dx0 = cx0 - x00,
dy0 = cy0 - y00,
dx1 = cx1 - x00,
dy1 = cy1 - y00;
// Pick the closer of the two intersection points.
// TODO Is there a faster way to determine which intersection to use?
if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
return {
cx: cx0,
cy: cy0,
x01: -ox,
y01: -oy,
x11: cx0 * (r1 / r - 1),
y11: cy0 * (r1 / r - 1)
};
}
var arc = function() {
var innerRadius = arcInnerRadius,
outerRadius = arcOuterRadius,
cornerRadius = constant$1(0),
padRadius = null,
startAngle = arcStartAngle,
endAngle = arcEndAngle,
padAngle = arcPadAngle,
context = null;
function arc() {
var buffer,
r,
r0 = +innerRadius.apply(this, arguments),
r1 = +outerRadius.apply(this, arguments),
a0 = startAngle.apply(this, arguments) - halfPi,
a1 = endAngle.apply(this, arguments) - halfPi,
da = Math.abs(a1 - a0),
cw = a1 > a0;
if (!context) context = buffer = d3Path.path();
// Ensure that the outer radius is always larger than the inner radius.
if (r1 < r0) r = r1, r1 = r0, r0 = r;
// Is it a point?
if (!(r1 > epsilon)) context.moveTo(0, 0);
// Or is it a circle or annulus?
else if (da > tau - epsilon) {
context.moveTo(r1 * Math.cos(a0), r1 * Math.sin(a0));
context.arc(0, 0, r1, a0, a1, !cw);
if (r0 > epsilon) {
context.moveTo(r0 * Math.cos(a1), r0 * Math.sin(a1));
context.arc(0, 0, r0, a1, a0, cw);
}
}
// Or is it a circular or annular sector?
else {
var a01 = a0,
a11 = a1,
a00 = a0,
a10 = a1,
da0 = da,
da1 = da,
ap = padAngle.apply(this, arguments) / 2,
rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : Math.sqrt(r0 * r0 + r1 * r1)),
rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
rc0 = rc,
rc1 = rc,
t0,
t1;
// Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
if (rp > epsilon) {
var p0 = asin(rp / r0 * Math.sin(ap)),
p1 = asin(rp / r1 * Math.sin(ap));
if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
else da0 = 0, a00 = a10 = (a0 + a1) / 2;
if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
else da1 = 0, a01 = a11 = (a0 + a1) / 2;
}
var x01 = r1 * Math.cos(a01),
y01 = r1 * Math.sin(a01),
x10 = r0 * Math.cos(a10),
y10 = r0 * Math.sin(a10);
// Apply rounded corners?
if (rc > epsilon) {
var x11 = r1 * Math.cos(a11),
y11 = r1 * Math.sin(a11),
x00 = r0 * Math.cos(a00),
y00 = r0 * Math.sin(a00);
// Restrict the corner radius according to the sector angle.
if (da < pi) {
var oc = da0 > epsilon ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],
ax = x01 - oc[0],
ay = y01 - oc[1],
bx = x11 - oc[0],
by = y11 - oc[1],
kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2),
lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
rc0 = Math.min(rc, (r0 - lc) / (kc - 1));
rc1 = Math.min(rc, (r1 - lc) / (kc + 1));
}
}
// Is the sector collapsed to a line?
if (!(da1 > epsilon)) context.moveTo(x01, y01);
// Does the sector’s outer ring have rounded corners?
else if (rc1 > epsilon) {
t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
// Have the corners merged?
if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw);
// Otherwise, draw the two corners and the ring.
else {
context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
context.arc(0, 0, r1, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
context.arc(t1.cx, t1.cy, rc1, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
}
}
// Or is the outer ring just a circular arc?
else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
// Is there no inner ring, and it’s a circular sector?
// Or perhaps it’s an annular sector collapsed due to padding?
if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);
// Does the sector’s inner ring (or point) have rounded corners?
else if (rc0 > epsilon) {
t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
// Have the corners merged?
if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw);
// Otherwise, draw the two corners and the ring.
else {
context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
context.arc(0, 0, r0, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);
context.arc(t1.cx, t1.cy, rc0, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
}
}
// Or is the inner ring just a circular arc?
else context.arc(0, 0, r0, a10, a00, cw);
}
context.closePath();
if (buffer) return context = null, buffer + "" || null;
}
arc.centroid = function() {
var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;
return [Math.cos(a) * r, Math.sin(a) * r];
};
arc.innerRadius = function(_) {
return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$1(+_), arc) : innerRadius;
};
arc.outerRadius = function(_) {
return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$1(+_), arc) : outerRadius;
};
arc.cornerRadius = function(_) {
return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$1(+_), arc) : cornerRadius;
};
arc.padRadius = function(_) {
return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$1(+_), arc) : padRadius;
};
arc.startAngle = function(_) {
return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$1(+_), arc) : startAngle;
};
arc.endAngle = function(_) {
return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$1(+_), arc) : endAngle;
};
arc.padAngle = function(_) {
return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$1(+_), arc) : padAngle;
};
arc.context = function(_) {
return arguments.length ? ((context = _ == null ? null : _), arc) : context;
};
return arc;
};
function Linear(context) {
this._context = context;
}
Linear.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; // proceed
default: this._context.lineTo(x, y); break;
}
}
};
var curveLinear = function(context) {
return new Linear(context);
};
function x(p) {
return p[0];
}
function y(p) {
return p[1];
}
var line = function() {
var x$$1 = x,
y$$1 = y,
defined = constant$1(true),
context = null,
curve = curveLinear,
output = null;
function line(data) {
var i,
n = data.length,
d,
defined0 = false,
buffer;
if (context == null) output = curve(buffer = d3Path.path());
for (i = 0; i <= n; ++i) {
if (!(i < n && defined(d = data[i], i, data)) === defined0) {
if (defined0 = !defined0) output.lineStart();
else output.lineEnd();
}
if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));
}
if (buffer) return output = null, buffer + "" || null;
}
line.x = function(_) {
return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$1(+_), line) : x$$1;
};
line.y = function(_) {
return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$1(+_), line) : y$$1;
};
line.defined = function(_) {
return arguments.length ? (defined = typeof _ === "function" ? _ : constant$1(!!_), line) : defined;
};
line.curve = function(_) {
return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
};
line.context = function(_) {
return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
};
return line;
};
var area = function() {
var x0 = x,
x1 = null,
y0 = constant$1(0),
y1 = y,
defined = constant$1(true),
context = null,
curve = curveLinear,
output = null;
function area(data) {
var i,
j,
k,
n = data.length,
d,
defined0 = false,
buffer,
x0z = new Array(n),
y0z = new Array(n);
if (context == null) output = curve(buffer = d3Path.path());
for (i = 0; i <= n; ++i) {
if (!(i < n && defined(d = data[i], i, data)) === defined0) {
if (defined0 = !defined0) {
j = i;
output.areaStart();
output.lineStart();
} else {
output.lineEnd();
output.lineStart();
for (k = i - 1; k >= j; --k) {
output.point(x0z[k], y0z[k]);
}
output.lineEnd();
output.areaEnd();
}
}
if (defined0) {
x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
}
}
if (buffer) return output = null, buffer + "" || null;
}
function arealine() {
return line().defined(defined).curve(curve).context(context);
}
area.x = function(_) {
return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$1(+_), x1 = null, area) : x0;
};
area.x0 = function(_) {
return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$1(+_), area) : x0;
};
area.x1 = function(_) {
return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$1(+_), area) : x1;
};
area.y = function(_) {
return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$1(+_), y1 = null, area) : y0;
};
area.y0 = function(_) {
return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$1(+_), area) : y0;
};
area.y1 = function(_) {
return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$1(+_), area) : y1;
};
area.lineX0 =
area.lineY0 = function() {
return arealine().x(x0).y(y0);
};
area.lineY1 = function() {
return arealine().x(x0).y(y1);
};
area.lineX1 = function() {
return arealine().x(x1).y(y0);
};
area.defined = function(_) {
return arguments.length ? (defined = typeof _ === "function" ? _ : constant$1(!!_), area) : defined;
};
area.curve = function(_) {
return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
};
area.context = function(_) {
return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
};
return area;
};
var descending = function(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
};
var identity = function(d) {
return d;
};
var pie = function() {
var value = identity,
sortValues = descending,
sort = null,
startAngle = constant$1(0),
endAngle = constant$1(tau),
padAngle = constant$1(0);
function pie(data) {
var i,
n = data.length,
j,
k,
sum = 0,
index = new Array(n),
arcs = new Array(n),
a0 = +startAngle.apply(this, arguments),
da = Math.min(tau, Math.max(-tau, endAngle.apply(this, arguments) - a0)),
a1,
p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
pa = p * (da < 0 ? -1 : 1),
v;
for (i = 0; i < n; ++i) {
if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
sum += v;
}
}
// Optionally sort the arcs by previously-computed values or by data.
if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
// Compute the arcs! They are stored in the original data's order.
for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
data: data[j],
index: i,
value: v,
startAngle: a0,
endAngle: a1,
padAngle: p
};
}
return arcs;
}
pie.value = function(_) {
return arguments.length ? (value = typeof _ === "function" ? _ : constant$1(+_), pie) : value;
};
pie.sortValues = function(_) {
return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
};
pie.sort = function(_) {
return arguments.length ? (sort = _, sortValues = null, pie) : sort;
};
pie.startAngle = function(_) {
return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$1(+_), pie) : startAngle;
};
pie.endAngle = function(_) {
return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$1(+_), pie) : endAngle;
};
pie.padAngle = function(_) {
return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$1(+_), pie) : padAngle;
};
return pie;
};
var curveRadialLinear = curveRadial(curveLinear);
function Radial(curve) {
this._curve = curve;
}
Radial.prototype = {
areaStart: function() {
this._curve.areaStart();
},
areaEnd: function() {
this._curve.areaEnd();
},
lineStart: function() {
this._curve.lineStart();
},
lineEnd: function() {
this._curve.lineEnd();
},
point: function(a, r) {
this._curve.point(r * Math.sin(a), r * -Math.cos(a));
}
};
function curveRadial(curve) {
function radial(context) {
return new Radial(curve(context));
}
radial._curve = curve;
return radial;
}
function radialLine(l) {
var c = l.curve;
l.angle = l.x, delete l.x;
l.radius = l.y, delete l.y;
l.curve = function(_) {
return arguments.length ? c(curveRadial(_)) : c()._curve;
};
return l;
}
var radialLine$1 = function() {
return radialLine(line().curve(curveRadialLinear));
};
var radialArea = function() {
var a = area().curve(curveRadialLinear),
c = a.curve,
x0 = a.lineX0,
x1 = a.lineX1,
y0 = a.lineY0,
y1 = a.lineY1;
a.angle = a.x, delete a.x;
a.startAngle = a.x0, delete a.x0;
a.endAngle = a.x1, delete a.x1;
a.radius = a.y, delete a.y;
a.innerRadius = a.y0, delete a.y0;
a.outerRadius = a.y1, delete a.y1;
a.lineStartAngle = function() { return radialLine(x0()); }, delete a.lineX0;
a.lineEndAngle = function() { return radialLine(x1()); }, delete a.lineX1;
a.lineInnerRadius = function() { return radialLine(y0()); }, delete a.lineY0;
a.lineOuterRadius = function() { return radialLine(y1()); }, delete a.lineY1;
a.curve = function(_) {
return arguments.length ? c(curveRadial(_)) : c()._curve;
};
return a;
};
var circle = {
draw: function(context, size) {
var r = Math.sqrt(size / pi);
context.moveTo(r, 0);
context.arc(0, 0, r, 0, tau);
}
};
var cross = {
draw: function(context, size) {
var r = Math.sqrt(size / 5) / 2;
context.moveTo(-3 * r, -r);
context.lineTo(-r, -r);
context.lineTo(-r, -3 * r);
context.lineTo(r, -3 * r);
context.lineTo(r, -r);
context.lineTo(3 * r, -r);
context.lineTo(3 * r, r);
context.lineTo(r, r);
context.lineTo(r, 3 * r);
context.lineTo(-r, 3 * r);
context.lineTo(-r, r);
context.lineTo(-3 * r, r);
context.closePath();
}
};
var tan30 = Math.sqrt(1 / 3);
var tan30_2 = tan30 * 2;
var diamond = {
draw: function(context, size) {
var y = Math.sqrt(size / tan30_2),
x = y * tan30;
context.moveTo(0, -y);
context.lineTo(x, 0);
context.lineTo(0, y);
context.lineTo(-x, 0);
context.closePath();
}
};
var ka = 0.89081309152928522810;
var kr = Math.sin(pi / 10) / Math.sin(7 * pi / 10);
var kx = Math.sin(tau / 10) * kr;
var ky = -Math.cos(tau / 10) * kr;
var star = {
draw: function(context, size) {
var r = Math.sqrt(size * ka),
x = kx * r,
y = ky * r;
context.moveTo(0, -r);
context.lineTo(x, y);
for (var i = 1; i < 5; ++i) {
var a = tau * i / 5,
c = Math.cos(a),
s = Math.sin(a);
context.lineTo(s * r, -c * r);
context.lineTo(c * x - s * y, s * x + c * y);
}
context.closePath();
}
};
var square = {
draw: function(context, size) {
var w = Math.sqrt(size),
x = -w / 2;
context.rect(x, x, w, w);
}
};
var sqrt3 = Math.sqrt(3);
var triangle = {
draw: function(context, size) {
var y = -Math.sqrt(size / (sqrt3 * 3));
context.moveTo(0, y * 2);
context.lineTo(-sqrt3 * y, -y);
context.lineTo(sqrt3 * y, -y);
context.closePath();
}
};
var c = -0.5;
var s = Math.sqrt(3) / 2;
var k = 1 / Math.sqrt(12);
var a = (k / 2 + 1) * 3;
var wye = {
draw: function(context, size) {
var r = Math.sqrt(size / a),
x0 = r / 2,
y0 = r * k,
x1 = x0,
y1 = r * k + r,
x2 = -x1,
y2 = y1;
context.moveTo(x0, y0);
context.lineTo(x1, y1);
context.lineTo(x2, y2);
context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
context.closePath();
}
};
var symbols = [
circle,
cross,
diamond,
square,
star,
triangle,
wye
];
var symbol = function() {
var type = constant$1(circle),
size = constant$1(64),
context = null;
function symbol() {
var buffer;
if (!context) context = buffer = d3Path.path();
type.apply(this, arguments).draw(context, +size.apply(this, arguments));
if (buffer) return context = null, buffer + "" || null;
}
symbol.type = function(_) {
return arguments.length ? (type = typeof _ === "function" ? _ : constant$1(_), symbol) : type;
};
symbol.size = function(_) {
return arguments.length ? (size = typeof _ === "function" ? _ : constant$1(+_), symbol) : size;
};
symbol.context = function(_) {
return arguments.length ? (context = _ == null ? null : _, symbol) : context;
};
return symbol;
};
var noop = function() {};
function point(that, x, y) {
that._context.bezierCurveTo(
(2 * that._x0 + that._x1) / 3,
(2 * that._y0 + that._y1) / 3,
(that._x0 + 2 * that._x1) / 3,
(that._y0 + 2 * that._y1) / 3,
(that._x0 + 4 * that._x1 + x) / 6,
(that._y0 + 4 * that._y1 + y) / 6
);
}
function Basis(context) {
this._context = context;
}
Basis.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 =
this._y0 = this._y1 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 3: point(this, this._x1, this._y1); // proceed
case 2: this._context.lineTo(this._x1, this._y1); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; break;
case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
default: point(this, x, y); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
var basis = function(context) {
return new Basis(context);
};
function BasisClosed(context) {
this._context = context;
}
BasisClosed.prototype = {
areaStart: noop,
areaEnd: noop,
lineStart: function() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 1: {
this._context.moveTo(this._x2, this._y2);
this._context.closePath();
break;
}
case 2: {
this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
this._context.closePath();
break;
}
case 3: {
this.point(this._x2, this._y2);
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
break;
}
}
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;
default: point(this, x, y); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
var basisClosed = function(context) {
return new BasisClosed(context);
};
function BasisOpen(context) {
this._context = context;
}
BasisOpen.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 =
this._y0 = this._y1 = NaN;
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; break;
case 1: this._point = 2; break;
case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;
case 3: this._point = 4; // proceed
default: point(this, x, y); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
var basisOpen = function(context) {
return new BasisOpen(context);
};
function Bundle(context, beta) {
this._basis = new Basis(context);
this._beta = beta;
}
Bundle.prototype = {
lineStart: function() {
this._x = [];
this._y = [];
this._basis.lineStart();
},
lineEnd: function() {
var x = this._x,
y = this._y,
j = x.length - 1;
if (j > 0) {
var x0 = x[0],
y0 = y[0],
dx = x[j] - x0,
dy = y[j] - y0,
i = -1,
t;
while (++i <= j) {
t = i / j;
this._basis.point(
this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
);
}
}
this._x = this._y = null;
this._basis.lineEnd();
},
point: function(x, y) {
this._x.push(+x);
this._y.push(+y);
}
};
var bundle = (function custom(beta) {
function bundle(context) {
return beta === 1 ? new Basis(context) : new Bundle(context, beta);
}
bundle.beta = function(beta) {
return custom(+beta);
};
return bundle;
})(0.85);
function point$1(that, x, y) {
that._context.bezierCurveTo(
that._x1 + that._k * (that._x2 - that._x0),
that._y1 + that._k * (that._y2 - that._y0),
that._x2 + that._k * (that._x1 - x),
that._y2 + that._k * (that._y1 - y),
that._x2,
that._y2
);
}
function Cardinal(context, tension) {
this._context = context;
this._k = (1 - tension) / 6;
}
Cardinal.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 2: this._context.lineTo(this._x2, this._y2); break;
case 3: point$1(this, this._x1, this._y1); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
case 2: this._point = 3; // proceed
default: point$1(this, x, y); break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var cardinal = (function custom(tension) {
function cardinal(context) {
return new Cardinal(context, tension);
}
cardinal.tension = function(tension) {
return custom(+tension);
};
return cardinal;
})(0);
function CardinalClosed(context, tension) {
this._context = context;
this._k = (1 - tension) / 6;
}
CardinalClosed.prototype = {
areaStart: noop,
areaEnd: noop,
lineStart: function() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 1: {
this._context.moveTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 2: {
this._context.lineTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 3: {
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
this.point(this._x5, this._y5);
break;
}
}
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
default: point$1(this, x, y); break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var cardinalClosed = (function custom(tension) {
function cardinal(context) {
return new CardinalClosed(context, tension);
}
cardinal.tension = function(tension) {
return custom(+tension);
};
return cardinal;
})(0);
function CardinalOpen(context, tension) {
this._context = context;
this._k = (1 - tension) / 6;
}
CardinalOpen.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; break;
case 1: this._point = 2; break;
case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
case 3: this._point = 4; // proceed
default: point$1(this, x, y); break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var cardinalOpen = (function custom(tension) {
function cardinal(context) {
return new CardinalOpen(context, tension);
}
cardinal.tension = function(tension) {
return custom(+tension);
};
return cardinal;
})(0);
function point$2(that, x, y) {
var x1 = that._x1,
y1 = that._y1,
x2 = that._x2,
y2 = that._y2;
if (that._l01_a > epsilon) {
var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
n = 3 * that._l01_a * (that._l01_a + that._l12_a);
x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
}
if (that._l23_a > epsilon) {
var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
m = 3 * that._l23_a * (that._l23_a + that._l12_a);
x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
}
that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
}
function CatmullRom(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRom.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._l01_a = this._l12_a = this._l23_a =
this._l01_2a = this._l12_2a = this._l23_2a =
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 2: this._context.lineTo(this._x2, this._y2); break;
case 3: this.point(this._x2, this._y2); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; break;
case 2: this._point = 3; // proceed
default: point$2(this, x, y); break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var catmullRom = (function custom(alpha) {
function catmullRom(context) {
return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
}
catmullRom.alpha = function(alpha) {
return custom(+alpha);
};
return catmullRom;
})(0.5);
function CatmullRomClosed(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRomClosed.prototype = {
areaStart: noop,
areaEnd: noop,
lineStart: function() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
this._l01_a = this._l12_a = this._l23_a =
this._l01_2a = this._l12_2a = this._l23_2a =
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 1: {
this._context.moveTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 2: {
this._context.lineTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 3: {
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
this.point(this._x5, this._y5);
break;
}
}
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
default: point$2(this, x, y); break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var catmullRomClosed = (function custom(alpha) {
function catmullRom(context) {
return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
}
catmullRom.alpha = function(alpha) {
return custom(+alpha);
};
return catmullRom;
})(0.5);
function CatmullRomOpen(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRomOpen.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._l01_a = this._l12_a = this._l23_a =
this._l01_2a = this._l12_2a = this._l23_2a =
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0: this._point = 1; break;
case 1: this._point = 2; break;
case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
case 3: this._point = 4; // proceed
default: point$2(this, x, y); break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var catmullRomOpen = (function custom(alpha) {
function catmullRom(context) {
return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
}
catmullRom.alpha = function(alpha) {
return custom(+alpha);
};
return catmullRom;
})(0.5);
function LinearClosed(context) {
this._context = context;
}
LinearClosed.prototype = {
areaStart: noop,
areaEnd: noop,
lineStart: function() {
this._point = 0;
},
lineEnd: function() {
if (this._point) this._context.closePath();
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) this._context.lineTo(x, y);
else this._point = 1, this._context.moveTo(x, y);
}
};
var linearClosed = function(context) {
return new LinearClosed(context);
};
function sign(x) {
return x < 0 ? -1 : 1;
}
// Calculate the slopes of the tangents (Hermite-type interpolation) based on
// the following paper: Steffen, M. 1990. A Simple Method for Monotonic
// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
// NOV(II), P. 443, 1990.
function slope3(that, x2, y2) {
var h0 = that._x1 - that._x0,
h1 = x2 - that._x1,
s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
p = (s0 * h1 + s1 * h0) / (h0 + h1);
return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
}
// Calculate a one-sided slope.
function slope2(that, t) {
var h = that._x1 - that._x0;
return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
}
// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
// "you can express cubic Hermite interpolation in terms of cubic Bézier curves
// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
function point$3(that, t0, t1) {
var x0 = that._x0,
y0 = that._y0,
x1 = that._x1,
y1 = that._y1,
dx = (x1 - x0) / 3;
that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
}
function MonotoneX(context) {
this._context = context;
}
MonotoneX.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 =
this._y0 = this._y1 =
this._t0 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 2: this._context.lineTo(this._x1, this._y1); break;
case 3: point$3(this, this._t0, slope2(this, this._t0)); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
var t1 = NaN;
x = +x, y = +y;
if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; break;
case 2: this._point = 3; point$3(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
default: point$3(this, this._t0, t1 = slope3(this, x, y)); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
this._t0 = t1;
}
};
function MonotoneY(context) {
this._context = new ReflectContext(context);
}
(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
MonotoneX.prototype.point.call(this, y, x);
};
function ReflectContext(context) {
this._context = context;
}
ReflectContext.prototype = {
moveTo: function(x, y) { this._context.moveTo(y, x); },
closePath: function() { this._context.closePath(); },
lineTo: function(x, y) { this._context.lineTo(y, x); },
bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
};
function monotoneX(context) {
return new MonotoneX(context);
}
function monotoneY(context) {
return new MonotoneY(context);
}
function Natural(context) {
this._context = context;
}
Natural.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x = [];
this._y = [];
},
lineEnd: function() {
var x = this._x,
y = this._y,
n = x.length;
if (n) {
this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
if (n === 2) {
this._context.lineTo(x[1], y[1]);
} else {
var px = controlPoints(x),
py = controlPoints(y);
for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
}
}
}
if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
this._line = 1 - this._line;
this._x = this._y = null;
},
point: function(x, y) {
this._x.push(+x);
this._y.push(+y);
}
};
// See https://www.particleincell.com/2012/bezier-splines/ for derivation.
function controlPoints(x) {
var i,
n = x.length - 1,
m,
a = new Array(n),
b = new Array(n),
r = new Array(n);
a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
a[n - 1] = r[n - 1] / b[n - 1];
for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
b[n - 1] = (x[n] + a[n - 1]) / 2;
for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
return [a, b];
}
var natural = function(context) {
return new Natural(context);
};
function Step(context, t) {
this._context = context;
this._t = t;
}
Step.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x = this._y = NaN;
this._point = 0;
},
lineEnd: function() {
if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; // proceed
default: {
if (this._t <= 0) {
this._context.lineTo(this._x, y);
this._context.lineTo(x, y);
} else {
var x1 = this._x * (1 - this._t) + x * this._t;
this._context.lineTo(x1, this._y);
this._context.lineTo(x1, y);
}
break;
}
}
this._x = x, this._y = y;
}
};
var step = function(context) {
return new Step(context, 0.5);
};
function stepBefore(context) {
return new Step(context, 0);
}
function stepAfter(context) {
return new Step(context, 1);
}
var slice = Array.prototype.slice;
var none = function(series, order) {
if (!((n = series.length) > 1)) return;
for (var i = 1, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
s0 = s1, s1 = series[order[i]];
for (var j = 0; j < m; ++j) {
s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
}
}
};
var none$1 = function(series) {
var n = series.length, o = new Array(n);
while (--n >= 0) o[n] = n;
return o;
};
function stackValue(d, key) {
return d[key];
}
var stack = function() {
var keys = constant$1([]),
order = none$1,
offset = none,
value = stackValue;
function stack(data) {
var kz = keys.apply(this, arguments),
i,
m = data.length,
n = kz.length,
sz = new Array(n),
oz;
for (i = 0; i < n; ++i) {
for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {
si[j] = sij = [0, +value(data[j], ki, j, data)];
sij.data = data[j];
}
si.key = ki;
}
for (i = 0, oz = order(sz); i < n; ++i) {
sz[oz[i]].index = i;
}
offset(sz, oz);
return sz;
}
stack.keys = function(_) {
return arguments.length ? (keys = typeof _ === "function" ? _ : constant$1(slice.call(_)), stack) : keys;
};
stack.value = function(_) {
return arguments.length ? (value = typeof _ === "function" ? _ : constant$1(+_), stack) : value;
};
stack.order = function(_) {
return arguments.length ? (order = _ == null ? none$1 : typeof _ === "function" ? _ : constant$1(slice.call(_)), stack) : order;
};
stack.offset = function(_) {
return arguments.length ? (offset = _ == null ? none : _, stack) : offset;
};
return stack;
};
var expand = function(series, order) {
if (!((n = series.length) > 0)) return;
for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
}
none(series, order);
};
var silhouette = function(series, order) {
if (!((n = series.length) > 0)) return;
for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
s0[j][1] += s0[j][0] = -y / 2;
}
none(series, order);
};
var wiggle = function(series, order) {
if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
var si = series[order[i]],
sij0 = si[j][1] || 0,
sij1 = si[j - 1][1] || 0,
s3 = (sij0 - sij1) / 2;
for (var k = 0; k < i; ++k) {
var sk = series[order[k]],
skj0 = sk[j][1] || 0,
skj1 = sk[j - 1][1] || 0;
s3 += skj0 - skj1;
}
s1 += sij0, s2 += s3 * sij0;
}
s0[j - 1][1] += s0[j - 1][0] = y;
if (s1) y -= s2 / s1;
}
s0[j - 1][1] += s0[j - 1][0] = y;
none(series, order);
};
var ascending = function(series) {
var sums = series.map(sum);
return none$1(series).sort(function(a, b) { return sums[a] - sums[b]; });
};
function sum(series) {
var s = 0, i = -1, n = series.length, v;
while (++i < n) if (v = +series[i][1]) s += v;
return s;
}
var descending$1 = function(series) {
return ascending(series).reverse();
};
var insideOut = function(series) {
var n = series.length,
i,
j,
sums = series.map(sum),
order = none$1(series).sort(function(a, b) { return sums[b] - sums[a]; }),
top = 0,
bottom = 0,
tops = [],
bottoms = [];
for (i = 0; i < n; ++i) {
j = order[i];
if (top < bottom) {
top += sums[j];
tops.push(j);
} else {
bottom += sums[j];
bottoms.push(j);
}
}
return bottoms.reverse().concat(tops);
};
var reverse = function(series) {
return none$1(series).reverse();
};
exports.arc = arc;
exports.area = area;
exports.line = line;
exports.pie = pie;
exports.radialArea = radialArea;
exports.radialLine = radialLine$1;
exports.symbol = symbol;
exports.symbols = symbols;
exports.symbolCircle = circle;
exports.symbolCross = cross;
exports.symbolDiamond = diamond;
exports.symbolSquare = square;
exports.symbolStar = star;
exports.symbolTriangle = triangle;
exports.symbolWye = wye;
exports.curveBasisClosed = basisClosed;
exports.curveBasisOpen = basisOpen;
exports.curveBasis = basis;
exports.curveBundle = bundle;
exports.curveCardinalClosed = cardinalClosed;
exports.curveCardinalOpen = cardinalOpen;
exports.curveCardinal = cardinal;
exports.curveCatmullRomClosed = catmullRomClosed;
exports.curveCatmullRomOpen = catmullRomOpen;
exports.curveCatmullRom = catmullRom;
exports.curveLinearClosed = linearClosed;
exports.curveLinear = curveLinear;
exports.curveMonotoneX = monotoneX;
exports.curveMonotoneY = monotoneY;
exports.curveNatural = natural;
exports.curveStep = step;
exports.curveStepAfter = stepAfter;
exports.curveStepBefore = stepBefore;
exports.stack = stack;
exports.stackOffsetExpand = expand;
exports.stackOffsetNone = none;
exports.stackOffsetSilhouette = silhouette;
exports.stackOffsetWiggle = wiggle;
exports.stackOrderAscending = ascending;
exports.stackOrderDescending = descending$1;
exports.stackOrderInsideOut = insideOut;
exports.stackOrderNone = none$1;
exports.stackOrderReverse = reverse;
Object.defineProperty(exports, '__esModule', { value: true });
})));
},{"d3-path":3}],6:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = annotation;
var _Annotation = require('./Annotation');
var _Annotation2 = _interopRequireDefault(_Annotation);
var _AnnotationCollection = require('./AnnotationCollection');
var _AnnotationCollection2 = _interopRequireDefault(_AnnotationCollection);
var _TypesD = require('./Types-d3');
var _d3Selection = require('d3-selection');
var _d3Dispatch = require('d3-dispatch');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function annotation() {
var annotations = [],
collection = void 0,
context = void 0,
//TODO: add canvas functionality
disable = [],
accessors = {},
accessorsInverse = {},
editMode = false,
ids = void 0,
type = _TypesD.d3Callout,
textWrap = void 0,
notePadding = void 0,
annotationDispatcher = (0, _d3Dispatch.dispatch)("subjectover", "subjectout", "subjectclick", "connectorover", "connectorout", "connectorclick", "noteover", "noteout", "noteclick");
var annotation = function annotation(selection) {
//TODO: check to see if this is still needed
if (!editMode) {
selection.selectAll("circle.handle").remove();
}
var translatedAnnotations = annotations.map(function (a) {
if (!a.type) {
a.type = type;
}
if (!a.disable) {
a.disable = disable;
}
return new _Annotation2.default(a);
});
collection = new _AnnotationCollection2.default({
annotations: translatedAnnotations,
accessors: accessors,
accessorsInverse: accessorsInverse,
ids: ids
});
var annotationG = selection.selectAll('g').data([collection]);
annotationG.enter().append('g').attr('class', 'annotations ' + (editMode ? "editable" : ""));
var group = selection.select('g.annotations');
(0, _TypesD.newWithClass)(group, collection.annotations, 'g', 'annotation');
var annotation = group.selectAll('g.annotation');
annotation.each(function (d) {
var a = (0, _d3Selection.select)(this);
var position = d.position;
var className = d.type.className && d.type.className();
if (className) {
a.attr('class', 'annotation ' + className);
}
(0, _TypesD.newWithClass)(a, [d], 'g', 'annotation-connector');
(0, _TypesD.newWithClass)(a, [d], 'g', 'annotation-subject');
(0, _TypesD.newWithClass)(a, [d], 'g', 'annotation-note');
(0, _TypesD.newWithClass)(a.select('g.annotation-note'), [d], 'g', 'annotation-note-content');
d.type = new d.type({ a: a, annotation: d, textWrap: textWrap, notePadding: notePadding, editMode: editMode,
dispatcher: annotationDispatcher, accessors: accessors });
d.type.draw();
});
};
annotation.json = function () {
console.log('Annotations JSON was copied to your clipboard. Please note the annotation type is not JSON compatible. It appears in the objects array in the console, but not in the copied JSON.', collection.json);
window.copy(JSON.stringify(collection.json.map(function (a) {
delete a.type;return a;
})));
return annotation;
};
annotation.update = function () {
if (annotations && collection) {
annotations = collection.annotations.map(function (a, i) {
a.type.draw();return a;
});
}
return annotation;
};
annotation.updatedAccessors = function () {
collection.setPositionWithAccessors();
annotations = collection.annotations;
return annotation;
};
annotation.disable = function (_) {
if (!arguments.length) return disable;
disable = _;
if (collection) {
collection.updateDisable(disable);
annotations = collection.annotations;
}
return annotation;
};
annotation.textWrap = function (_) {
if (!arguments.length) return textWrap;
textWrap = _;
if (collection) {
collection.updateTextWrap(textWrap);
annotations = collection.annotations;
}
return annotation;
};
annotation.notePadding = function (_) {
if (!arguments.length) return notePadding;
notePadding = _;
if (collection) {
collection.updateNotePadding(notePadding);
annotations = collection.annotations;
}
return annotation;
};
annotation.type = function (_, settings) {
if (!arguments.length) return type;
type = _;
if (collection) {
collection.annotations.map(function (a) {
var previousType = a.type;
var className = type.className && type.className();
if (className) {
previousType.a.attr('class', 'annotation ' + className);
}
a.type.note && a.type.note.selectAll("*:not(.annotation-note-content)").remove();
a.type.noteContent && a.type.noteContent.selectAll("*").remove();
a.type.subject && a.type.subject.selectAll("*").remove();
a.type.connector && a.type.connector.selectAll("*").remove();
a.type = type;
a.subject = settings && settings.subject || a.subject;
a.connector = settings && settings.connector || a.connector;
a.note = settings && settings.note || a.note;
});
annotations = collection.annotations;
}
return annotation;
};
annotation.annotations = function (_) {
if (!arguments.length) return collection && collection.annotations || annotations;
annotations = _;
return annotation;
};
annotation.context = function (_) {
if (!arguments.length) return context;
context = _;
return annotation;
};
annotation.accessors = function (_) {
if (!arguments.length) return accessors;
accessors = _;
return annotation;
};
annotation.accessorsInverse = function (_) {
if (!arguments.length) return accessorsInverse;
accessorsInverse = _;
return annotation;
};
annotation.ids = function (_) {
if (!arguments.length) return ids;
ids = _;
return annotation;
};
annotation.editMode = function (_) {
if (!arguments.length) return editMode;
editMode = _;
if (collection) {
collection.editMode(editMode);
annotations = collection.annotations;
}
return annotation;
};
annotation.collection = function (_) {
if (!arguments.length) return collection;
collection = _;
return annotation;
};
annotation.on = function () {
var value = annotationDispatcher.on.apply(annotationDispatcher, arguments);
return value === annotationDispatcher ? annotation : value;
};
return annotation;
};
},{"./Annotation":7,"./AnnotationCollection":8,"./Types-d3":22,"d3-dispatch":1,"d3-selection":4}],7:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Annotation = function () {
function Annotation(_ref) {
var _ref$x = _ref.x,
x = _ref$x === undefined ? 0 : _ref$x,
_ref$y = _ref.y,
y = _ref$y === undefined ? 0 : _ref$y,
_ref$dy = _ref.dy,
dy = _ref$dy === undefined ? 0 : _ref$dy,
_ref$dx = _ref.dx,
dx = _ref$dx === undefined ? 0 : _ref$dx,
data = _ref.data,
type = _ref.type,
subject = _ref.subject,
connector = _ref.connector,
note = _ref.note,
disable = _ref.disable,
id = _ref.id;
_classCallCheck(this, Annotation);
this._dx = dx;
this._dy = dy;
this._x = x;
this._y = y;
this.id = id;
this.type = type || '';
this.data = data;
this.note = note || {};
this.connector = connector || {};
this.subject = subject || {};
this.disable = disable || [];
}
_createClass(Annotation, [{
key: 'updatePosition',
value: function updatePosition() {
if (this.type.setPosition) {
this.type.setPosition();
if (this.type.subject.selectAll(':not(.handle)').nodes().length !== 0) {
this.type.redrawSubject();
}
}
}
}, {
key: 'updateOffset',
value: function updateOffset() {
if (this.type.setOffset) {
this.type.setOffset();
if (this.type.connector.selectAll(':not(.handle)').nodes().length !== 0) {
this.type.redrawConnector();
}
this.type.redrawNote();
}
}
}, {
key: 'x',
get: function get() {
return this._x;
},
set: function set(x) {
this._x = x;
this.updatePosition();
}
}, {
key: 'y',
get: function get() {
return this._y;
},
set: function set(y) {
this._y = y;
this.updatePosition();
}
}, {
key: 'dx',
get: function get() {
return this._dx;
},
set: function set(dx) {
this._dx = dx;
this.updateOffset();
}
}, {
key: 'dy',
get: function get() {
return this._dy;
},
set: function set(dy) {
this._dy = dy;
this.updateOffset();
}
}, {
key: 'offset',
get: function get() {
return { x: this._dx, y: this._dy };
},
set: function set(_ref2) {
var x = _ref2.x,
y = _ref2.y;
this._dx = x;
this._dy = y;
this.updateOffset();
}
}, {
key: 'position',
get: function get() {
return { x: this._x, y: this._y };
},
set: function set(_ref3) {
var x = _ref3.x,
y = _ref3.y;
this._x = x;
this._y = y;
this.updatePosition();
}
}, {
key: 'translation',
get: function get() {
return {
x: this._x + this._dx,
y: this._y + this._dy
};
}
}, {
key: 'json',
get: function get() {
var json = {
x: this._x,
y: this._y,
dx: this._dx,
dy: this._dy
};
if (this.data && Object.keys(this.data).length > 0) json.data = this.data;
if (this.type) json.type = this.type;
if (Object.keys(this.connector).length > 0) json.connector = this.connector;
if (Object.keys(this.subject).length > 0) json.subject = this.subject;
if (Object.keys(this.note).length > 0) json.note = this.note;
return json;
}
}]);
return Annotation;
}();
exports.default = Annotation;
},{}],8:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var AnnotationCollection = function () {
function AnnotationCollection(_ref) {
var annotations = _ref.annotations,
accessors = _ref.accessors,
accessorsInverse = _ref.accessorsInverse;
_classCallCheck(this, AnnotationCollection);
this.accessors = accessors;
this.accessorsInverse = accessorsInverse;
this.annotations = annotations;
}
_createClass(AnnotationCollection, [{
key: "clearTypes",
value: function clearTypes(newSettings) {
this.annotations.forEach(function (d) {
d.type = undefined;
d.subject = newSettings && newSettings.subject || d.subject;
d.connector = newSettings && newSettings.connector || d.connector;
d.note = newSettings && newSettings.note || d.note;
});
}
}, {
key: "setPositionWithAccessors",
value: function setPositionWithAccessors() {
var _this = this;
this.annotations.forEach(function (d) {
d.type.setPositionWithAccessors(_this.accessors);
});
}
}, {
key: "editMode",
value: function editMode(_editMode) {
this.annotations.forEach(function (a) {
if (a.type) {
a.type.editMode = _editMode;
a.type.updateEditMode();
}
});
}
}, {
key: "updateDisable",
value: function updateDisable(disable) {
this.annotations.forEach(function (a) {
a.disable = disable;
if (a.type) {
disable.forEach(function (d) {
if (a.type[d]) {
a.type[d].remove && a.type[d].remove();
a.type[d] = undefined;
}
});
}
});
}
}, {
key: "updateTextWrap",
value: function updateTextWrap(textWrap) {
this.annotations.forEach(function (a) {
if (a.type && a.type.updateTextWrap) {
a.type.updateTextWrap(textWrap);
}
});
}
}, {
key: "updateNotePadding",
value: function updateNotePadding(notePadding) {
this.annotations.forEach(function (a) {
if (a.type) {
a.type.notePadding = notePadding;
}
});
}
}, {
key: "json",
get: function get() {
var _this2 = this;
return this.annotations.map(function (a) {
var json = a.json;
if (_this2.accessorsInverse) {
json.data = {};
Object.keys(_this2.accessorsInverse).forEach(function (k) {
json.data[k] = _this2.accessorsInverse[k]({ x: a.x, y: a.y });
});
}
return json;
});
}
//TODO: should all annotations have a key?
//If so what would that help? could that map to priority?
//
}, {
key: "noteNodes",
get: function get() {
return this.annotations.map(function (a) {
return _extends({}, a.type.getNoteBBox(), { startX: a.x, startY: a.y });
});
}
//TODO: come back and rethink if a.x and a.y are applicable in all situations
}, {
key: "connectorNodes",
get: function get() {
return this.annotations.map(function (a) {
return _extends({}, a.type.getConnectorBBox(), { startX: a.x, startY: a.y });
});
}
}, {
key: "subjectNodes",
get: function get() {
return this.annotations.map(function (a) {
return _extends({}, a.type.getSubjectBBox(), { startX: a.x, startY: a.y });
});
}
}, {
key: "annotationNodes",
get: function get() {
return this.annotations.map(function (a) {
return _extends({}, a.type.getAnnotationBBox(), { startX: a.x, startY: a.y });
});
}
}]);
return AnnotationCollection;
}();
exports.default = AnnotationCollection;
},{}],9:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.arcBuilder = exports.lineBuilder = undefined;
var _d3Shape = require('d3-shape');
var lineBuilder = exports.lineBuilder = function lineBuilder(_ref) {
var data = _ref.data,
_ref$curve = _ref.curve,
curve = _ref$curve === undefined ? _d3Shape.curveLinear : _ref$curve,
canvasContext = _ref.canvasContext,
className = _ref.className;
var lineGen = (0, _d3Shape.line)().curve(curve);
var builder = {
type: 'path',
className: className,
data: data
};
if (canvasContext) {
lineGen.context(canvasContext);
builder.pathMethods = lineGen;
} else {
builder.attrs = {
d: lineGen(data)
};
}
return builder;
};
var arcBuilder = exports.arcBuilder = function arcBuilder(_ref2) {
var data = _ref2.data,
canvasContext = _ref2.canvasContext,
className = _ref2.className;
var builder = {
type: 'path',
className: className,
data: data
};
var arcShape = (0, _d3Shape.arc)().innerRadius(data.innerRadius || 0).outerRadius(data.outerRadius || data.radius || 2).startAngle(data.startAngle || 0).endAngle(data.endAngle || 2 * Math.PI);
if (canvasContext) {
arcShape.context(canvasContext);
builder.pathMethods = lineGen;
} else {
builder.attrs = {
d: arcShape()
};
}
return builder;
};
},{"d3-shape":5}],10:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _Builder = require('../Builder');
exports.default = function (_ref) {
var annotation = _ref.annotation,
start = _ref.start,
end = _ref.end;
var offset = annotation.position;
if (!start) {
start = [annotation.dx, annotation.dy];
} else {
start = [-end[0] + start[0], -end[1] + start[1]];
}
if (!end) {
end = [annotation.x - offset.x, annotation.y - offset.y];
}
var x1 = end[0],
y1 = end[1];
var dx = start[0];
var dy = start[1];
var size = 10;
var angleOffset = 16 / 180 * Math.PI;
var angle = Math.atan(dy / dx);
if (dx < 0) {
angle += Math.PI;
}
var data = [[x1, y1], [Math.cos(angle + angleOffset) * size + x1, Math.sin(angle + angleOffset) * size + y1], [Math.cos(angle - angleOffset) * size + x1, Math.sin(angle - angleOffset) * size + y1], [x1, y1]];
//TODO add in reverse
// if (canvasContext.arrowReverse){
// data = [[x1, y1],
// [Math.cos(angle + angleOffset)*size, Math.sin(angle + angleOffset)*size],
// [Math.cos(angle - angleOffset)*size, Math.sin(angle - angleOffset)*size],
// [x1, y1]
// ]
// } else {
// data = [[x1, y1],
// [Math.cos(angle + angleOffset)*size, Math.sin(angle + angleOffset)*size],
// [Math.cos(angle - angleOffset)*size, Math.sin(angle - angleOffset)*size],
// [x1, y1]
// ]
// }
return { components: [(0, _Builder.lineBuilder)({ data: data, className: 'connector-arrow' })] };
};
},{"../Builder":9}],11:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _Builder = require('../Builder');
exports.default = function (_ref) {
var line = _ref.line;
var dot = (0, _Builder.arcBuilder)({ className: 'connector-dot', data: { radius: 3 } });
dot.attrs.transform = 'translate(' + line.data[0][0] + ', ' + line.data[0][1] + ')';
return { components: [dot] };
};
},{"../Builder":9}],12:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _Builder = require('../Builder');
var _d3Selection = require('d3-selection');
var _typeLine = require('./type-line');
var _d3Shape = require('d3-shape');
var _Handles = require('../Handles');
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
exports.default = function (_ref) {
var type = _ref.type,
connectorData = _ref.connectorData;
if (!connectorData) {
connectorData = {};
}
if (!connectorData.points || typeof connectorData.points === "number") {
connectorData.points = createPoints(type.annotation.offset, connectorData.points);
}
if (!connectorData.curve) {
connectorData.curve = _d3Shape.curveCatmullRom;
}
// context.points = connectorData.points
// context.curve = connectorData.curve
var handles = [];
if (type.editMode) {
(function () {
var cHandles = connectorData.points.map(function (c, i) {
return _extends({}, (0, _Handles.pointHandle)({ cx: c[0], cy: c[1] }), { index: i });
});
var updatePoint = function updatePoint(index) {
connectorData.points[index][0] += _d3Selection.event.dx;
connectorData.points[index][1] += _d3Selection.event.dy;
type.redrawConnector();
};
handles = type.mapHandles(cHandles.map(function (h) {
return _extends({}, h.move, { drag: updatePoint.bind(type, h.index) });
}));
})();
}
var data = (0, _typeLine.lineSetup)(type);
data = [data[0]].concat(_toConsumableArray(connectorData.points), [data[1]]);
var components = [(0, _Builder.lineBuilder)({ data: data, curve: connectorData.curve, className: "connector" })];
return { components: components, handles: handles };
};
var createPoints = function createPoints(offset) {
var anchors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
var diff = { x: offset.x / (anchors + 1), y: offset.y / (anchors + 1) };
var p = [];
var i = 1;
for (; i <= anchors; i++) {
p.push([diff.x * i + i % 2 * 20, diff.y * i - i % 2 * 20]);
}
return p;
};
},{"../Builder":9,"../Handles":15,"./type-line":14,"d3-selection":4,"d3-shape":5}],13:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _Builder = require("../Builder");
exports.default = function (_ref) {
var type = _ref.type;
var annotation = type.annotation;
var offset = annotation.position;
var x1 = annotation.x - offset.x,
x2 = x1 + annotation.dx,
y1 = annotation.y - offset.y,
y2 = y1 + annotation.dy;
var subjectData = annotation.subject;
var data = [[x1, y1], [x2, y2]];
var diffY = y2 - y1;
var diffX = x2 - x1;
var xe = x2;
var ye = y2;
var opposite = y2 < 0 && x2 > 0 || x2 < 0 && y2 > 0 ? -1 : 1;
if (Math.abs(diffX) < Math.abs(diffY)) {
xe = x2;
ye = y1 + diffX * opposite;
} else {
ye = y2;
xe = x1 + diffY * opposite;
}
var circleCheck = type.typeSettings && type.typeSettings.subject && type.typeSettings.subject.type == "circle";
if (circleCheck && (subjectData.outerRadius || subjectData.radius)) {
var r = (subjectData.outerRadius || subjectData.radius) + (subjectData.radiusPadding || 0);
var length = r / Math.sqrt(2);
if (Math.abs(diffX) > length && Math.abs(diffY) > length) {
x1 = length * (x2 < 0 ? -1 : 1);
y1 = length * (y2 < 0 ? -1 : 1);
data = [[x1, y1], [xe, ye], [x2, y2]];
} else if (Math.abs(diffX) > Math.abs(diffY)) {
var angle = Math.asin(-y2 / r);
x1 = Math.abs(Math.cos(angle) * r) * (x2 < 0 ? -1 : 1);
data = [[x1, y2], [x2, y2]];
} else {
var _angle = Math.acos(x2 / r);
y1 = Math.abs(Math.sin(_angle) * r) * (y2 < 0 ? -1 : 1);
data = [[x2, y1], [x2, y2]];
}
} else {
data = [[x1, y1], [xe, ye], [x2, y2]];
}
return { components: [(0, _Builder.lineBuilder)({ data: data, className: "connector" })] };
};
},{"../Builder":9}],14:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.lineSetup = undefined;
var _Builder = require("../Builder");
var lineSetup = exports.lineSetup = function lineSetup(type) {
var annotation = type.annotation;
var offset = annotation.position;
var x1 = annotation.x - offset.x,
x2 = x1 + annotation.dx,
y1 = annotation.y - offset.y,
y2 = y1 + annotation.dy;
var subjectData = annotation.subject;
var circleCheck = type.typeSettings && type.typeSettings.subject && type.typeSettings.subject.type == "circle";
if (circleCheck && (subjectData.outerRadius || subjectData.radius)) {
var h = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
var angle = Math.asin(-y2 / h);
var r = subjectData.outerRadius || subjectData.radius + (subjectData.radiusPadding || 0);
x1 = Math.abs(Math.cos(angle) * r) * (x2 < 0 ? -1 : 1);
y1 = Math.abs(Math.sin(angle) * r) * (y2 < 0 ? -1 : 1);
}
return [[x1, y1], [x2, y2]];
};
exports.default = function (_ref) {
var type = _ref.type;
var data = lineSetup(type);
return { components: [(0, _Builder.lineBuilder)({ data: data, className: "connector" })] };
};
},{"../Builder":9}],15:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addHandles = exports.lineHandles = exports.rectHandles = exports.circleHandles = exports.pointHandle = undefined;
var _d3Selection = require('d3-selection');
var _d3Drag = require('d3-drag');
var pointHandle = exports.pointHandle = function pointHandle(_ref) {
var _ref$cx = _ref.cx,
cx = _ref$cx === undefined ? 0 : _ref$cx,
_ref$cy = _ref.cy,
cy = _ref$cy === undefined ? 0 : _ref$cy;
return { move: { x: cx, y: cy } };
};
var circleHandles = exports.circleHandles = function circleHandles(_ref2) {
var _ref2$cx = _ref2.cx,
cx = _ref2$cx === undefined ? 0 : _ref2$cx,
_ref2$cy = _ref2.cy,
cy = _ref2$cy === undefined ? 0 : _ref2$cy,
r1 = _ref2.r1,
r2 = _ref2.r2,
padding = _ref2.padding;
var h = { move: { x: cx, y: cy } };
if (r1 !== undefined) {
h.r1 = { x: cx + r1 / Math.sqrt(2), y: cy + r1 / Math.sqrt(2) };
}
if (r2 !== undefined) {
h.r2 = { x: cx + r2 / Math.sqrt(2), y: cy + r2 / Math.sqrt(2) };
}
if (padding !== undefined) {
h.padding = { x: cx + r1 + padding, y: cy };
}
return h;
};
var rectHandles = exports.rectHandles = function rectHandles(_ref3) {
var _ref3$x = _ref3.x1,
x1 = _ref3$x === undefined ? 0 : _ref3$x,
_ref3$y = _ref3.y1,
y1 = _ref3$y === undefined ? 0 : _ref3$y,
_ref3$x2 = _ref3.x2,
x2 = _ref3$x2 === undefined ? x1 : _ref3$x2,
_ref3$y2 = _ref3.y2,
y2 = _ref3$y2 === undefined ? y1 : _ref3$y2,
width = _ref3.width,
height = _ref3.height;
var w = width || Math.abs(x2 - x1);
var h = height || Math.abs(y2 - y1);
return {
move: {
x: Math.min(x1, x2) + w / 2,
y: Math.min(y1, y2) - 10
},
width: {
x: Math.max(x1, x2),
y: Math.min(y1, y2) + h / 2
},
height: {
x: Math.min(x1, x2) + w / 2,
y: Math.max(y1, y2)
}
};
};
var lineHandles = exports.lineHandles = function lineHandles(_ref4) {
var x1 = _ref4.x1,
y1 = _ref4.y1,
x2 = _ref4.x2,
y2 = _ref4.y2,
x = _ref4.x,
y = _ref4.y;
var minY = Math.min(y1, y2);
var minX = Math.min(x1, x2);
var height = Math.abs(y2 - y1);
var width = Math.abs(x2 - x1);
return {
move: {
x: x || minX + width / 2,
y: y || minY + height / 2
}
};
};
//arc handles
var addHandles = exports.addHandles = function addHandles(_ref5) {
var group = _ref5.group,
handles = _ref5.handles,
_ref5$r = _ref5.r,
r = _ref5$r === undefined ? 10 : _ref5$r;
//give it a group and x,y to draw handles
//then give it instructions on what the handles change
var h = group.selectAll('circle.handle').data(handles);
h.enter().append('circle').attr('class', 'handle').call((0, _d3Drag.drag)().container((0, _d3Selection.select)('g.annotations').node()).on('start', function (d) {
return d.start && d.start(d);
}).on('drag', function (d) {
return d.drag && d.drag(d);
}).on('end', function (d) {
return d.end && d.end(d);
}));
group.selectAll('circle.handle').attr('cx', function (d) {
return d.x;
}).attr('cy', function (d) {
return d.y;
}).attr('r', function (d) {
return d.r || r;
});
h.exit().remove();
};
},{"d3-drag":2,"d3-selection":4}],16:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var leftRightDynamic = exports.leftRightDynamic = function leftRightDynamic(align, y) {
if (align == "dynamic" || align == "left" || align == "right") {
if (y < 0) {
align = "top";
} else {
align = "bottom";
}
}
return align;
};
var topBottomDynamic = exports.topBottomDynamic = function topBottomDynamic(align, x) {
if (align == "dynamic" || align == "top" || align == "bottom") {
if (x < 0) {
align = "right";
} else {
align = "left";
}
}
return align;
};
exports.default = function (_ref) {
var padding = _ref.padding,
bbox = _ref.bbox,
align = _ref.align,
orientation = _ref.orientation,
offset = _ref.offset;
var x = -bbox.x;
var y = -bbox.y;
if (orientation === "topBottom") {
align = topBottomDynamic(align, offset.x);
if (offset.y < 0) {
y -= bbox.height + padding;
} else {
y += padding;
}
if (align === "middle") {
x -= bbox.width / 2;
} else if (align === "right") {
x -= bbox.width;
}
} else if (orientation === "leftRight") {
align = leftRightDynamic(align, offset.y);
if (offset.x < 0) {
x -= bbox.width + padding;
} else {
x += padding;
}
if (align === "middle") {
y -= bbox.height / 2;
} else if (align === "top") {
y -= bbox.height;
}
}
return "translate(" + x + ", " + y + ")";
};
},{}],17:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _Builder = require('../Builder');
var _alignment = require('./alignment');
exports.default = function (_ref) {
var align = _ref.align,
_ref$x = _ref.x,
x = _ref$x === undefined ? 0 : _ref$x,
_ref$y = _ref.y,
y = _ref$y === undefined ? 0 : _ref$y,
offset = _ref.offset,
bbox = _ref.bbox,
padding = _ref.padding;
align = (0, _alignment.topBottomDynamic)(align, offset.x);
if (align == "right") {
x -= bbox.width;
} else if (align == "middle") {
x -= bbox.width / 2;
}
var data = [[x, y], [x + bbox.width, y]];
return { components: [(0, _Builder.lineBuilder)({ data: data, className: "note-line" })] };
};
},{"../Builder":9,"./alignment":16}],18:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _Builder = require('../Builder');
var _alignment = require('./alignment');
exports.default = function (_ref) {
var align = _ref.align,
_ref$x = _ref.x,
x = _ref$x === undefined ? 0 : _ref$x,
_ref$y = _ref.y,
y = _ref$y === undefined ? 0 : _ref$y,
bbox = _ref.bbox,
offset = _ref.offset,
padding = _ref.padding;
align = (0, _alignment.leftRightDynamic)(align, offset.y);
if (align == "top") {
y -= bbox.height;
} else if (align == "middle") {
y -= bbox.height / 2;
}
var data = [[x, y], [x, y + bbox.height]];
return { components: [(0, _Builder.lineBuilder)({ data: data, className: "note-line" })] };
};
},{"../Builder":9,"./alignment":16}],19:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _Handles = require('../Handles');
var _Builder = require('../Builder');
var _d3Selection = require('d3-selection');
exports.default = function (_ref) {
var subjectData = _ref.subjectData,
type = _ref.type;
if (!subjectData.radius) subjectData.radius = 14;
if (!subjectData.x) subjectData.x = "left";
if (!subjectData.y) subjectData.y = "top";
var handles = [];
var radius = subjectData.radius;
var innerRadius = radius * .7;
var x = subjectData.x == "left" ? -radius : radius;
var y = subjectData.y == "top" ? -radius : radius;
var transform = 'translate(' + x + ', ' + y + ')';
var circlebg = (0, _Builder.arcBuilder)({ className: 'subject', data: { radius: radius } });
circlebg.attrs.transform = transform;
var circle = (0, _Builder.arcBuilder)({ className: 'subject-ring', data: { outerRadius: radius, innerRadius: innerRadius } });
circle.attrs.transform = transform;
var pointer = (0, _Builder.lineBuilder)({ className: 'subject-pointer',
data: [[0, 0], [x, 0], [0, y], [0, 0]]
});
if (type.editMode) {
var dragBadge = function dragBadge() {
subjectData.x = _d3Selection.event.x < 0 ? "left" : "right";
subjectData.y = _d3Selection.event.y < 0 ? "top" : "bottom";
type.redrawSubject();
};
var bHandles = [{ x: x * 2, y: y * 2, drag: dragBadge.bind(type) }];
handles = type.mapHandles(bHandles);
}
var text = void 0;
if (subjectData.text) {
text = {
type: "text",
className: "badge-text",
attrs: {
text: subjectData.text,
"text-anchor": "middle",
dy: ".25em",
x: x,
y: y
}
};
}
return { components: [pointer, circlebg, circle, text], handles: handles };
};
},{"../Builder":9,"../Handles":15,"d3-selection":4}],20:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _Handles = require('../Handles');
var _Builder = require('../Builder');
var _d3Selection = require('d3-selection');
exports.default = function (_ref) {
var subjectData = _ref.subjectData,
type = _ref.type;
if (!subjectData.radius && !subjectData.outerRadius) {
subjectData.radius = 20;
}
var handles = [];
var c = (0, _Builder.arcBuilder)({ data: subjectData, className: "subject" });
if (type.editMode) {
var h = (0, _Handles.circleHandles)({
r1: c.data.outerRadius || c.data.radius,
r2: c.data.innerRadius,
padding: subjectData.radiusPadding
});
var updateRadius = function updateRadius(attr) {
var r = subjectData[attr] + _d3Selection.event.dx * Math.sqrt(2);
subjectData[attr] = r;
type.redrawSubject();
type.redrawConnector();
};
var updateRadiusPadding = function updateRadiusPadding() {
var rpad = subjectData.radiusPadding + _d3Selection.event.dx;
subjectData.radiusPadding = rpad;
type.redrawSubject();
type.redrawConnector();
};
var cHandles = [_extends({}, h.padding, { drag: updateRadiusPadding.bind(type) }), _extends({}, h.r1, { drag: updateRadius.bind(type, subjectData.outerRadius !== undefined ? 'outerRadius' : 'radius') })];
if (subjectData.innerRadius) {
cHandles.push(_extends({}, h.r2, { drag: updateRadius.bind(type, 'innerRadius') }));
}
handles = type.mapHandles(cHandles);
}
return { components: [c], handles: handles };
};
},{"../Builder":9,"../Handles":15,"d3-selection":4}],21:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _Handles = require('../Handles');
var _Builder = require('../Builder');
exports.default = function (_ref) {
var subjectData = _ref.subjectData,
type = _ref.type;
var offset = type.annotation.position;
var x1 = (subjectData.x1 !== undefined ? subjectData.x1 : offset.x) - offset.x,
x2 = (subjectData.x2 !== undefined ? subjectData.x2 : offset.x) - offset.x,
y1 = (subjectData.y1 !== undefined ? subjectData.y1 : offset.y) - offset.y,
y2 = (subjectData.y2 !== undefined ? subjectData.y2 : offset.y) - offset.y;
var data = [[x1, y1], [x2, y2]];
return { components: [(0, _Builder.lineBuilder)({ data: data, className: 'subject' })] };
};
},{"../Builder":9,"../Handles":15}],22:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.newWithClass = exports.d3XYThreshold = exports.d3Badge = exports.d3CalloutCurve = exports.d3CalloutCircle = exports.d3CalloutElbow = exports.d3Callout = exports.d3Label = exports.d3NoteText = exports.customType = undefined;
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
//Note options
//Connector options
//Subject options
var _d3Selection = require('d3-selection');
var _d3Drag = require('d3-drag');
var _Annotation = require('./Annotation');
var _Handles = require('./Handles');
var _alignment = require('./Note/alignment');
var _alignment2 = _interopRequireDefault(_alignment);
var _lineTypeVertical = require('./Note/lineType-vertical');
var _lineTypeVertical2 = _interopRequireDefault(_lineTypeVertical);
var _lineTypeHorizontal = require('./Note/lineType-horizontal');
var _lineTypeHorizontal2 = _interopRequireDefault(_lineTypeHorizontal);
var _typeLine = require('./Connector/type-line');
var _typeLine2 = _interopRequireDefault(_typeLine);
var _typeElbow = require('./Connector/type-elbow');
var _typeElbow2 = _interopRequireDefault(_typeElbow);
var _typeCurve = require('./Connector/type-curve');
var _typeCurve2 = _interopRequireDefault(_typeCurve);
var _endArrow = require('./Connector/end-arrow');
var _endArrow2 = _interopRequireDefault(_endArrow);
var _endDot = require('./Connector/end-dot');
var _endDot2 = _interopRequireDefault(_endDot);
var _circle = require('./Subject/circle');
var _circle2 = _interopRequireDefault(_circle);
var _threshold = require('./Subject/threshold');
var _threshold2 = _interopRequireDefault(_threshold);
var _badge = require('./Subject/badge');
var _badge2 = _interopRequireDefault(_badge);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Type = function () {
function Type(_ref) {
var a = _ref.a,
annotation = _ref.annotation,
editMode = _ref.editMode,
dispatcher = _ref.dispatcher,
notePadding = _ref.notePadding,
accessors = _ref.accessors;
_classCallCheck(this, Type);
this.a = a;
this.note = annotation.disable.indexOf("note") === -1 && a.select('g.annotation-note');
this.noteContent = this.note && a.select('g.annotation-note-content');
this.connector = annotation.disable.indexOf("connector") === -1 && a.select('g.annotation-connector');
this.subject = annotation.disable.indexOf("subject") === -1 && a.select('g.annotation-subject');
if (dispatcher) {
var handler = addHandlers.bind(null, dispatcher, annotation);
handler({ component: this.note, name: 'note' });
handler({ component: this.connector, name: 'connector' });
handler({ component: this.subject, name: 'subject' });
}
this.annotation = annotation;
this.editMode = annotation.editMode || editMode;
this.notePadding = notePadding || 3;
if (accessors && annotation.data) {
this.init(accessors);
}
}
_createClass(Type, [{
key: 'init',
value: function init(accessors) {
if (!this.annotation.x) {
this.mapX(accessors);
}
if (!this.annotation.y) {
this.mapY(accessors);
}
}
}, {
key: 'mapY',
value: function mapY(accessors) {
if (accessors.y) {
this.annotation.y = accessors.y(this.annotation.data);
}
}
}, {
key: 'mapX',
value: function mapX(accessors) {
if (accessors.x) {
this.annotation.x = accessors.x(this.annotation.data);
}
}
}, {
key: 'updateEditMode',
value: function updateEditMode() {
this.a.selectAll('circle.handle').remove();
}
}, {
key: 'drawOnSVG',
value: function drawOnSVG(component, builders) {
var _this = this;
if (!Array.isArray(builders)) {
builders = [builders];
}
builders.filter(function (b) {
return b;
}).forEach(function (_ref2) {
var type = _ref2.type,
className = _ref2.className,
attrs = _ref2.attrs,
handles = _ref2.handles;
if (type === "handle") {
(0, _Handles.addHandles)({ group: component, r: attrs && attrs.r, handles: handles });
} else {
(function () {
newWithClass(component, [_this.annotation], type, className);
var el = component.select(type + '.' + className);
var attrKeys = Object.keys(attrs);
attrKeys.forEach(function (attr) {
if (attr === "text") {
el.text(attrs[attr]);
} else {
el.attr(attr, attrs[attr]);
}
});
})();
}
});
}
}, {
key: 'getNoteBBox',
value: function getNoteBBox() {
return bboxWithoutHandles(this.note, '.annotation-note-content');
}
}, {
key: 'getConnectorBBox',
value: function getConnectorBBox() {
return bboxWithoutHandles(this.connector);
}
}, {
key: 'getSubjectBBox',
value: function getSubjectBBox() {
return bboxWithoutHandles(this.subject);
}
}, {
key: 'getAnnotationBBox',
value: function getAnnotationBBox() {
return bboxWithoutHandles(this.a);
}
}, {
key: 'drawSubject',
value: function drawSubject() {
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var subjectData = this.annotation.subject;
var type = context.type;
var subjectParams = { type: this, subjectData: subjectData };
var subject = {};
if (type === "circle") subject = (0, _circle2.default)(subjectParams);else if (type === "threshold") subject = (0, _threshold2.default)(subjectParams);else if (type === "badge") subject = (0, _badge2.default)(subjectParams);
var _subject = subject,
_subject$components = _subject.components,
components = _subject$components === undefined ? [] : _subject$components,
_subject$handles = _subject.handles,
handles = _subject$handles === undefined ? [] : _subject$handles;
if (this.editMode) {
handles = handles.concat(this.mapHandles([{ drag: this.dragSubject.bind(this) }]));
components.push({ type: "handle", handles: handles });
}
return components;
}
}, {
key: 'drawConnector',
value: function drawConnector() {
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var connectorData = this.annotation.connector;
var type = connectorData.type || context.type;
var connectorParams = { type: this, connectorData: connectorData };
var connector = {};
if (type === "curve") connector = (0, _typeCurve2.default)(connectorParams);else if (type === "elbow") connector = (0, _typeElbow2.default)(connectorParams);else connector = (0, _typeLine2.default)(connectorParams);
var _connector = connector,
_connector$components = _connector.components,
components = _connector$components === undefined ? [] : _connector$components,
_connector$handles = _connector.handles,
handles = _connector$handles === undefined ? [] : _connector$handles;
var line = components[0];
var endType = connectorData.end || context.end;
var end = {};
if (endType === "arrow") end = (0, _endArrow2.default)({ annotation: this.annotation, start: line.data[1], end: line.data[0] });else if (endType === "dot") end = (0, _endDot2.default)({ line: line });
if (end.components) {
components = components.concat(end.components);
}
if (this.editMode && handles.length !== 0) {
components.push({ type: "handle", handles: handles });
}
return components;
}
}, {
key: 'drawNote',
value: function drawNote() {
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var noteData = this.annotation.note;
var align = noteData.align || context.align || 'dynamic';
var noteParams = { bbox: context.bbox, align: align, offset: this.annotation.offset };
var lineType = noteData.lineType || context.lineType;
var note = {};
if (lineType == "vertical") note = (0, _lineTypeVertical2.default)(noteParams);else if (lineType == "horizontal") note = (0, _lineTypeHorizontal2.default)(noteParams);
var _note = note,
_note$components = _note.components,
components = _note$components === undefined ? [] : _note$components,
_note$handles = _note.handles,
handles = _note$handles === undefined ? [] : _note$handles;
if (this.editMode) {
handles = this.mapHandles([{ x: 0, y: 0, drag: this.dragNote.bind(this) }]);
components.push({ type: "handle", handles: handles });
}
return components;
}
}, {
key: 'drawNoteContent',
value: function drawNoteContent(context) {
var noteData = this.annotation.note;
var padding = noteData.padding || this.notePadding;
var orientation = noteData.orientation || context.orientation || 'topBottom';
var lineType = noteData.lineType || context.lineType;
var align = noteData.align || context.align || 'dynamic';
if (lineType == "vertical") orientation = "leftRight";else if (lineType == "horizontal") orientation = "topBottom";
var noteParams = { padding: padding, bbox: context.bbox, offset: this.annotation.offset, orientation: orientation, align: align };
this.note && this.noteContent.attr('transform', (0, _alignment2.default)(noteParams));
return [];
}
}, {
key: 'redrawSubject',
value: function redrawSubject() {
this.subject && this.drawOnSVG(this.subject, this.drawSubject());
}
}, {
key: 'redrawConnector',
value: function redrawConnector() {
var bbox = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getNoteBBox();
this.connector && this.drawOnSVG(this.connector, this.drawConnector());
}
}, {
key: 'redrawNote',
value: function redrawNote() {
var bbox = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getNoteBBox();
this.noteContent && this.drawOnSVG(this.noteContent, this.drawNoteContent({ bbox: bbox }));
this.note && this.drawOnSVG(this.note, this.drawNote({ bbox: bbox }));
}
}, {
key: 'setPosition',
value: function setPosition() {
var position = this.annotation.position;
this.a.attr('transform', 'translate(' + position.x + ', ' + position.y + ')');
}
}, {
key: 'setOffset',
value: function setOffset() {
if (this.note) {
var offset = this.annotation.offset;
this.note.attr('transform', 'translate(' + offset.x + ', ' + offset.y + ')');
}
}
}, {
key: 'setPositionWithAccessors',
value: function setPositionWithAccessors(accessors) {
if (accessors && this.annotation.data) {
this.mapX(accessors);
this.mapY(accessors);
}
this.setPosition();
}
}, {
key: 'draw',
value: function draw() {
this.setPosition();
this.setOffset();
this.redrawSubject();
this.redrawConnector();
this.redrawNote();
}
}, {
key: 'dragstarted',
value: function dragstarted() {
_d3Selection.event.sourceEvent.stopPropagation();this.a.classed("dragging", true);
}
}, {
key: 'dragended',
value: function dragended() {
this.a.classed("dragging", false);
}
}, {
key: 'dragSubject',
value: function dragSubject() {
var position = this.annotation.position;
position.x += _d3Selection.event.dx;
position.y += _d3Selection.event.dy;
this.annotation.position = position;
}
}, {
key: 'dragNote',
value: function dragNote() {
var offset = this.annotation.offset;
offset.x += _d3Selection.event.dx;
offset.y += _d3Selection.event.dy;
this.annotation.offset = offset;
}
}, {
key: 'mapHandles',
value: function mapHandles(handles) {
var _this2 = this;
return handles.map(function (h) {
return _extends({}, h, {
start: _this2.dragstarted.bind(_this2), end: _this2.dragended.bind(_this2) });
});
}
}]);
return Type;
}();
var customType = exports.customType = function customType(initialType, typeSettings, _init) {
return function (_initialType) {
_inherits(customType, _initialType);
function customType(settings) {
_classCallCheck(this, customType);
var _this3 = _possibleConstructorReturn(this, (customType.__proto__ || Object.getPrototypeOf(customType)).call(this, settings));
_this3.typeSettings = typeSettings;
if (typeSettings.disable) {
typeSettings.disable.forEach(function (d) {
_this3[d] = undefined;
if (d == "note") {
_this3.noteContent = undefined;
}
});
}
return _this3;
}
_createClass(customType, [{
key: 'drawSubject',
value: function drawSubject(context) {
this.typeSettings.subject = Object.assign({}, typeSettings.subject, this.typeSettings.subject);
return _get(customType.prototype.__proto__ || Object.getPrototypeOf(customType.prototype), 'drawSubject', this).call(this, _extends({}, context, this.typeSettings.subject));
}
}, {
key: 'drawConnector',
value: function drawConnector(context, subjectContext) {
this.typeSettings.connector = Object.assign({}, typeSettings.connector, this.typeSettings.connector);
return _get(customType.prototype.__proto__ || Object.getPrototypeOf(customType.prototype), 'drawConnector', this).call(this, _extends({}, context, typeSettings.connector, this.typeSettings.connector));
}
}, {
key: 'drawNote',
value: function drawNote(context) {
this.typeSettings.note = Object.assign({}, typeSettings.note, this.typeSettings.note);
return _get(customType.prototype.__proto__ || Object.getPrototypeOf(customType.prototype), 'drawNote', this).call(this, _extends({}, context, typeSettings.note, this.typeSettings.note));
}
}, {
key: 'drawNoteContent',
value: function drawNoteContent(context) {
return _get(customType.prototype.__proto__ || Object.getPrototypeOf(customType.prototype), 'drawNoteContent', this).call(this, _extends({}, context, typeSettings.note, this.typeSettings.note));
}
}], [{
key: 'init',
value: function init(annotation, accessors) {
_get(customType.__proto__ || Object.getPrototypeOf(customType), 'init', this).call(this, annotation, accessors);
if (_init) {
annotation = _init(annotation, accessors);
}
return annotation;
}
}, {
key: 'className',
value: function className() {
return typeSettings.className || initialType.className();
}
}]);
return customType;
}(initialType);
};
var d3NoteText = exports.d3NoteText = function (_Type) {
_inherits(d3NoteText, _Type);
function d3NoteText(params) {
_classCallCheck(this, d3NoteText);
var _this4 = _possibleConstructorReturn(this, (d3NoteText.__proto__ || Object.getPrototypeOf(d3NoteText)).call(this, params));
_this4.textWrap = params.textWrap || 120;
_this4.drawText();
return _this4;
}
_createClass(d3NoteText, [{
key: 'updateTextWrap',
value: function updateTextWrap(textWrap) {
this.textWrap = textWrap;
this.drawText();
}
}, {
key: 'drawText',
value: function drawText() {
if (this.note) {
newWithClass(this.note, [this.annotation], 'g', 'annotation-note-content');
var noteContent = this.note.select('g.annotation-note-content');
newWithClass(noteContent, [this.annotation], 'text', 'annotation-note-label');
newWithClass(noteContent, [this.annotation], 'text', 'annotation-note-title');
var titleBBox = { height: 0 };
var label = this.a.select('text.annotation-note-label');
var wrapLength = this.annotation.note && this.annotation.note.wrap || this.textWrap;
if (this.annotation.note.title) {
var title = this.a.select('text.annotation-note-title');
title.text(this.annotation.note.title).attr('dy', '1.1em');
title.call(wrap, wrapLength);
titleBBox = title.node().getBBox();
}
label.text(this.annotation.note.label).attr('dy', '1em');
label.call(wrap, wrapLength);
label.attr('y', titleBBox.height * 1.1 || 0);
}
}
}]);
return d3NoteText;
}(Type);
var d3Label = exports.d3Label = customType(d3NoteText, {
className: "label",
note: { align: "middle" }
});
var d3Callout = exports.d3Callout = customType(d3NoteText, {
className: "callout",
note: { lineType: "horizontal" }
});
var d3CalloutElbow = exports.d3CalloutElbow = customType(d3Callout, {
className: "callout elbow",
connector: { type: "elbow" }
});
var d3CalloutCircle = exports.d3CalloutCircle = customType(d3CalloutElbow, {
className: "callout circle",
subject: { type: "circle" }
});
var d3CalloutCurve = exports.d3CalloutCurve = customType(d3Callout, {
className: "callout curve",
connector: { type: "curve" }
});
var d3Badge = exports.d3Badge = customType(Type, {
className: "badge",
subject: { type: "badge" },
disable: ['connector', 'note']
});
var d3XYThreshold = exports.d3XYThreshold = function (_d3Callout) {
_inherits(d3XYThreshold, _d3Callout);
function d3XYThreshold() {
_classCallCheck(this, d3XYThreshold);
return _possibleConstructorReturn(this, (d3XYThreshold.__proto__ || Object.getPrototypeOf(d3XYThreshold)).apply(this, arguments));
}
_createClass(d3XYThreshold, [{
key: 'drawSubject',
value: function drawSubject(context) {
return _get(d3XYThreshold.prototype.__proto__ || Object.getPrototypeOf(d3XYThreshold.prototype), 'drawSubject', this).call(this, _extends({}, context, { type: "threshold" }));
}
}, {
key: 'mapY',
value: function mapY(accessors) {
_get(d3XYThreshold.prototype.__proto__ || Object.getPrototypeOf(d3XYThreshold.prototype), 'mapY', this).call(this, accessors);
var a = this.annotation;
if ((a.subject.x1 || a.subject.x2) && a.data && accessors.y) {
a.y = accessors.y(a.data);
}
}
}, {
key: 'mapX',
value: function mapX(accessors) {
_get(d3XYThreshold.prototype.__proto__ || Object.getPrototypeOf(d3XYThreshold.prototype), 'mapX', this).call(this, accessors);
var a = this.annotation;
if ((a.subject.y1 || a.subject.y2) && a.data && accessors.x) {
a.x = accessors.x(a.data);
}
}
}], [{
key: 'className',
value: function className() {
return "xythreshold";
}
}]);
return d3XYThreshold;
}(d3Callout);
var newWithClass = exports.newWithClass = function newWithClass(a, d, type, className) {
var group = a.selectAll(type + '.' + className).data(d);
group.enter().append(type).merge(group).attr('class', className);
group.exit().remove();
return a;
};
var addHandlers = function addHandlers(dispatcher, annotation, _ref3) {
var component = _ref3.component,
name = _ref3.name;
if (component) {
component.on("mouseover.annotations", function () {
dispatcher.call(name + 'over', component, annotation);
}).on("mouseout.annotations", function () {
return dispatcher.call(name + 'out', component, annotation);
}).on("click.annotations", function () {
return dispatcher.call(name + 'click', component, annotation);
});
}
};
//Text wrapping code adapted from Mike Bostock
var wrap = function wrap(text, width) {
text.each(function () {
var text = d3.select(this),
words = text.text().split(/ \t\r\n+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = .2,
//ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")) || 0,
tspan = text.text(null).append("tspan").attr("x", 0).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width && line.length > 1) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("dy", lineHeight + dy + "em").text(word);
}
}
});
};
var bboxWithoutHandles = function bboxWithoutHandles(selection) {
var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ':not(.handle)';
if (!selection) {
return { x: 0, y: 0, width: 0, height: 0 };
}
return selection.selectAll(selector).nodes().reduce(function (p, c) {
var bbox = c.getBBox();
p.x = Math.min(p.x, bbox.x);
p.y = Math.min(p.y, bbox.y);
p.width = Math.max(p.width, bbox.width);
p.height += bbox.height;
return p;
}, { x: 0, y: 0, width: 0, height: 0 });
};
exports.default = {
Type: Type,
d3Label: d3Label,
d3Callout: d3Callout,
d3CalloutElbow: d3CalloutElbow,
d3CalloutCurve: d3CalloutCurve,
d3CalloutCircle: d3CalloutCircle,
d3XYThreshold: d3XYThreshold,
d3Badge: d3Badge,
customType: customType
};
},{"./Annotation":7,"./Connector/end-arrow":10,"./Connector/end-dot":11,"./Connector/type-curve":12,"./Connector/type-elbow":13,"./Connector/type-line":14,"./Handles":15,"./Note/alignment":16,"./Note/lineType-horizontal":17,"./Note/lineType-vertical":18,"./Subject/badge":19,"./Subject/circle":20,"./Subject/threshold":21,"d3-drag":2,"d3-selection":4}],23:[function(require,module,exports){
'use strict';
var _AdapterD = require('./src/Adapter-d3');
var _AdapterD2 = _interopRequireDefault(_AdapterD);
var _TypesD = require('./src/Types-d3');
var _TypesD2 = _interopRequireDefault(_TypesD);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
d3.annotation = _AdapterD2.default;
d3.annotationTypeBase = _TypesD2.default.Type;
d3.annotationLabel = _TypesD2.default.d3Label;
d3.annotationCallout = _TypesD2.default.d3Callout;
d3.annotationCalloutCurve = _TypesD2.default.d3CalloutCurve;
d3.annotationCalloutElbow = _TypesD2.default.d3CalloutElbow;
d3.annotationCalloutCircle = _TypesD2.default.d3CalloutCircle;
d3.annotationXYThreshold = _TypesD2.default.d3XYThreshold;
d3.annotationBadge = _TypesD2.default.d3Badge;
d3.annotationCustomType = _TypesD2.default.customType;
},{"./src/Adapter-d3":6,"./src/Types-d3":22}]},{},[23]);
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="d3-annotation.js"></script>
<style>
body {
margin: 0;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.editable .annotation-subject, .editable .annotation-textbox {
cursor: move;
}
.annotation path {
stroke: #e91e56;
fill: rgba(0,0,0,0);
}
.annotation text {
fill: #e91e56;
}
.annotation-note-title {
font-weight: bold;
}
circle.handle {
stroke-dasharray: 5;
stroke: #e91e56;
fill: rgba(255, 255, 255, .5);
cursor: move;
stroke-opacity: .4;
}
circle.handle.highlight {
stroke-opacity: 1;
}
.annotation-tip .annotation path {
stroke: black;
}
.annotation-tip .annotation text {
fill: black;
}
</style></head>
<body>
<script>
function weightedCentroid(data){
let X0 = Y0 = Z0 = W0 = 0;
const radians = Math.PI / 180;
function centroidPoint(lambda, phi, w) {
lambda *= radians, phi *= radians;
var cosPhi = Math.cos(phi);
centroidPointCartesian(cosPhi * Math.cos(lambda), cosPhi * Math.sin(lambda), Math.sin(phi), w);
}
function centroidPointCartesian(x, y, z, w) {
W0 += +w;
if (!w || !W0) return;
w /= W0;
X0 += (x - X0) * w;
Y0 += (y - Y0) * w;
Z0 += (z - Z0) * w;
}
data.map(d => centroidPoint(...d));
var x = X0,
y = Y0,
z = Z0,
m = x * x + y * y + z * z;
return [Math.atan2(y, x) / radians, Math.asin(z / Math.sqrt(m)) / radians];
}
const width = 960,
height = 500,
margin = 40,
scalepop = d3.scaleSqrt().domain([0, 100000]).range([0.2, 24]),
scalecountry = d3.scaleOrdinal(d3.schemeCategory20b),
projection = d3.geoEquirectangular().rotate([-10.5,0]);
d3.csv('cities.csv', function (cities) {
const data = cities
.sort((a, b) => d3.descending(+a[2015], +b[2015]))
.map((d, i) => [+d.Longitude, +d.Latitude, +d[2015], +d['Country Code'], d['Urban Agglomeration']]);
const svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// this almost invisible rect allows our svg to receive mousemove events
svg.append('rect')
.attr("width", width)
.attr("height", height)
.attr("fill", 'rgba(0,0,0,0.01)');
const nodes = data.map(d => {
let p = projection(d);
d.x = p[0];
d.y = p[1];
d.r = scalepop(d[2]);
d.color = 'rgba(127,127,127,0.5)';
d.name = d[4];
return d;
});
var gcities = svg.append('g');
draw(gcities, nodes);
// draw the unweighted geoCentroid
const centroid = d3.geoCentroid({
type: "MultiPoint",
coordinates: data.map(d => [d[0], d[1]])
});
let p1 = projection(centroid);
centroid.r = 6;
draw(svg.append('g'), [{
x: p1[0],
y: p1[1],
r: centroid.r,
color: '#8e84ff',
stroke: 'black',
}]);
// draw the *weighted* geoCentroid
const wcentroid = weightedCentroid(data.map(d => [d[0], d[1], d[2]]));
let p2 = projection(wcentroid);
wcentroid.r = 12;
let wcentroids = [{
x: p2[0],
y: p2[1],
r: wcentroid.r,
data: wcentroid,
color: '#ff8684',
stroke: 'black',
}];
draw(svg.append('g'), wcentroids);
centroid.name = "Centroid";
centroid.dx = -65;
centroid.dy = -40;
wcentroid.name = "Weighted Centroid";
wcentroid.dx = 90;
wcentroid.dy = -30;
function draw (g, nodes) {
g
.selectAll('circle')
.data(nodes)
.enter()
.append('circle')
.attr('r', d => d.r)
.attr('cx', d => d.x)
.attr('cy', d => d.y)
.attr('fill', d => d.color)
.attr('stroke', d => d.stroke || 'none');
}
annotation = d3.annotation()
.annotations([centroid, wcentroid]
.map(d => {
return {
data: d,
dx: d.dx || 0,
dy: d.dy || 0,
note: {
title: d.name || "??",
label: d.map(d3.format('0.2f')).join(', '),
},
subject: {
radius: d.r,
},
connector: { end: "arrow" },
type: d3.annotationCalloutCircle,
}
}))
.accessors({ x: d => projection(d)[0], y: d => projection(d)[1] })
svg.append("g")
.attr("class", "annotation-centroids")
.call(annotation)
// create a container for tooltips
tipg = svg.append("g")
.attr("class", "annotation-tip");
// this function will call d3.annotation when a tooltip has to be drawn
function tip (d) {
annotationtip = d3.annotation()
.type(d3.annotationCalloutCircle)
.annotations([d].map(d => {
return {
data: d,
dx: d.dx || (d.x > 450) ? -50 : 50,
dy: d.dy || (d.y > 240) ? -10 : 10,
note: {
label: d.name || "??",
},
subject: {
radius: d.r,
radiusPadding: 2,
},
};
}))
.accessors({ x: d => projection(d)[0], y: d => projection(d)[1] })
tipg.call(annotationtip);
}
// use voronoi.find() on mousemove to decide what tooltip to display
let voronoi = null;
svg.on('mousemove', function() {
if (!voronoi) voronoi = d3.voronoi().x(d => d.x).y(d => d.y)(nodes);
let m = d3.mouse(this);
let f = voronoi.find(m[0], m[1], 15 /* voronoi radius */);
if (f) {
tip(f.data);
} else {
tipg.selectAll("g").remove();
}
});
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment