├── .babelrc ├── .vscode └── settings.json ├── README.md ├── dist ├── assets │ ├── images │ │ ├── bls-logo@2x.png │ │ ├── favicon-heart-whr.png │ │ ├── us_map_outline-resized.png │ │ ├── us_map_outline.png │ │ └── whr-heart.png │ └── screenshots │ │ ├── aerbnb_home_index_screenshot.gif │ │ ├── aerbnb_screenshot.gif │ │ ├── aerbnb_show_page_screenshot.gif │ │ ├── screen_test-02.gif │ │ ├── typefighter_multi_player.gif │ │ └── typefighter_single_player.gif ├── data │ └── countries.json ├── main.js └── stylesheets │ └── style.css ├── gitignore ├── index.html ├── package-lock.json ├── package.json ├── src ├── chart.js ├── constants.js ├── data │ └── countries.json ├── filter.js ├── index.js └── world_graph.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/env", 5 | { 6 | "targets": { 7 | "browsers": [ 8 | "last 2 versions", 9 | "safari >= 7" 10 | ] 11 | } 12 | } 13 | ] 14 | ] 15 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # World Happiness Report (Data Visualization) 2 | 3 | **World Happiness Report** is an interactive data visualization based off the annual World Happiness Report. Over 1096 data points from 156 countries were aggregated to give an exploratory visual of the state of global happiness. 4 | 5 | This year's World Happiness Report focuses on happiness and the community: how happiness has evolved over the past dozen years, with a focus on the technologies, social norms, conflicts and government policies that have driven those changes. 6 | 7 | This tool allows you to explore the study, customize the statistics, and share the facts. 8 | 9 | Data provided by [World Happiness Report](https://worldhappiness.report/) and [World Population Review](http://worldpopulationreview.com/). 10 | Visualization created by [Kenneth Choi](https://www.kchoi.io). 11 | 12 | ## Screenshots 13 | 14 | ![World Happiness Report screenshot](https://mrkchoi.github.io/WHR_data_visualization/dist/assets/screenshots/screen_test-02.gif) 15 | 16 | ## Technologies 17 | * D3.js 18 | * JavaScript (ES6) 19 | * Webpack 20 | * Babel 21 | * HTML5 22 | * CSS3 23 | 24 | ## Features 25 | * Users can interact with the individual data points to see further data on each country 26 | * Users can develop correlation hypotheses on GDP, social support, generosity, freedom, life expectancy and population 27 | * Users can filter data by both continent and metrics from individual countries 28 | 29 | ## Data Chart (D3.js) 30 | 31 | Clean and modular code through use of ES6 classes and inheritance. 32 | 33 | ```javascript 34 | 35 | class Chart { 36 | constructor(selector, options) { 37 | this.setChart(selector, options); 38 | this.setLabels(); 39 | } 40 | 41 | setChart(selector, options = { topOffset: 0, leftOffset: 0 }) { 42 | // .. 43 | } 44 | 45 | setData(data) { 46 | // .. 47 | } 48 | 49 | xAxis(ticks = 20, tickFormat = () => {}) { 50 | // .. 51 | } 52 | 53 | yAxis(domain, yScale, ticks = 5, tickFormat = () => {}) { 54 | // .. 55 | } 56 | 57 | setLabels() { 58 | // .. 59 | } 60 | } 61 | 62 | class WorldGraph extends Chart { 63 | constructor(selector) { 64 | super(selector); 65 | this.svg = d3.select(selector); 66 | this.xAxis(); 67 | this.yAxis([1, 0], "scaleLinear", 20, () => d3.format(".0%")); 68 | this.getData("graphGdp"); 69 | } 70 | 71 | getData(metric) { 72 | let that = this; 73 | d3.json("dist/data/countries.json").then(data => { 74 | that.setData(data); 75 | that.circles(metric); 76 | }); 77 | } 78 | // .. 79 | } 80 | ``` 81 | 82 | A parent class, `Chart`, was implemented to initialize the base configuration for the (D3.js) visualization. The rendered data graph was refactored into a child class `WorldGraph`, inheriting from the `Chart` class. 83 | 84 | 85 | ## Data (JSON) 86 | 87 | Data was aggregated from multiple sources and formatted into JSON. The JSON file is loaded asynchronously into the D3 visualization. 88 | 89 | ```javascript 90 | { 91 | "LUXEMBOURG": { 92 | "continent": "Europe", 93 | "country": "Luxembourg", 94 | "class": "city-Luxembourg", 95 | "graphRanking": 143, 96 | "ranking": 14, 97 | "graphSocialSupport": 130, 98 | "socialSupport": 27, 99 | "graphFreedom": 129, 100 | "freedom": 28, 101 | "graphGenerosity": 127, 102 | "generosity": 30, 103 | "graphGdp": 155, 104 | "gdp": 2, 105 | "graphLifeExpectancy": 141, 106 | "lifeExpectancy": 16, 107 | "population": 616596 108 | }, 109 | "UNITED_KINGDOM": { 110 | // .. 111 | }, 112 | // .. 113 | } 114 | ``` 115 | 116 | 117 | ## Future Plans 118 | Some features I plan on implement in the future are: 119 | 120 | * the ability for users to view data from previous years' studies 121 | * slicing and filtering data based on additional parameters (e.g. perceptions of corruption) 122 | -------------------------------------------------------------------------------- /dist/assets/images/bls-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/images/bls-logo@2x.png -------------------------------------------------------------------------------- /dist/assets/images/favicon-heart-whr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/images/favicon-heart-whr.png -------------------------------------------------------------------------------- /dist/assets/images/us_map_outline-resized.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/images/us_map_outline-resized.png -------------------------------------------------------------------------------- /dist/assets/images/us_map_outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/images/us_map_outline.png -------------------------------------------------------------------------------- /dist/assets/images/whr-heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/images/whr-heart.png -------------------------------------------------------------------------------- /dist/assets/screenshots/aerbnb_home_index_screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/screenshots/aerbnb_home_index_screenshot.gif -------------------------------------------------------------------------------- /dist/assets/screenshots/aerbnb_screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/screenshots/aerbnb_screenshot.gif -------------------------------------------------------------------------------- /dist/assets/screenshots/aerbnb_show_page_screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/screenshots/aerbnb_show_page_screenshot.gif -------------------------------------------------------------------------------- /dist/assets/screenshots/screen_test-02.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/screenshots/screen_test-02.gif -------------------------------------------------------------------------------- /dist/assets/screenshots/typefighter_multi_player.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/screenshots/typefighter_multi_player.gif -------------------------------------------------------------------------------- /dist/assets/screenshots/typefighter_single_player.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrkchoi/WHR_data_visualization/cd662dad625debccd5c5d6d8b74227fee746054b/dist/assets/screenshots/typefighter_single_player.gif -------------------------------------------------------------------------------- /dist/data/countries.json: -------------------------------------------------------------------------------- 1 | { 2 | "FINLAND": { 3 | "continent": "Europe", 4 | "country": "Finland", 5 | "class": "city-Finland", 6 | "graphRanking": 156, 7 | "ranking": 1, 8 | "graphSocialSupport": 155, 9 | "socialSupport": 2, 10 | "graphFreedom": 152, 11 | "freedom": 5, 12 | "graphGenerosity": 110, 13 | "generosity": 47, 14 | "graphGdp": 135, 15 | "gdp": 22, 16 | "graphLifeExpectancy": 130, 17 | "lifeExpectancy": 27, 18 | "population": 5532994 19 | }, 20 | "DENMARK": { 21 | "continent": "Europe", 22 | "country": "Denmark", 23 | "class": "city-Denmark", 24 | "graphRanking": 155, 25 | "ranking": 2, 26 | "graphSocialSupport": 153, 27 | "socialSupport": 4, 28 | "graphFreedom": 151, 29 | "freedom": 6, 30 | "graphGenerosity": 135, 31 | "generosity": 22, 32 | "graphGdp": 143, 33 | "gdp": 14, 34 | "graphLifeExpectancy": 134, 35 | "lifeExpectancy": 23, 36 | "population": 5773553 37 | }, 38 | "NORWAY": { 39 | "continent": "Europe", 40 | "country": "Norway", 41 | "class": "city-Norway", 42 | "graphRanking": 154, 43 | "ranking": 3, 44 | "graphSocialSupport": 154, 45 | "socialSupport": 3, 46 | "graphFreedom": 154, 47 | "freedom": 3, 48 | "graphGenerosity": 146, 49 | "generosity": 11, 50 | "graphGdp": 150, 51 | "gdp": 7, 52 | "graphLifeExpectancy": 145, 53 | "lifeExpectancy": 12, 54 | "population": 5382413 55 | }, 56 | "ICELAND": { 57 | "continent": "Europe", 58 | "country": "Iceland", 59 | "class": "city-Iceland", 60 | "graphRanking": 153, 61 | "ranking": 4, 62 | "graphSocialSupport": 156, 63 | "socialSupport": 1, 64 | "graphFreedom": 150, 65 | "freedom": 7, 66 | "graphGenerosity": 154, 67 | "generosity": 3, 68 | "graphGdp": 142, 69 | "gdp": 15, 70 | "graphLifeExpectancy": 144, 71 | "lifeExpectancy": 13, 72 | "population": 339204 73 | }, 74 | "NETHERLANDS": { 75 | "continent": "Europe", 76 | "country": "Netherlands", 77 | "class": "city-Netherlands", 78 | "graphRanking": 152, 79 | "ranking": 5, 80 | "graphSocialSupport": 142, 81 | "socialSupport": 15, 82 | "graphFreedom": 138, 83 | "freedom": 19, 84 | "graphGenerosity": 150, 85 | "generosity": 7, 86 | "graphGdp": 145, 87 | "gdp": 12, 88 | "graphLifeExpectancy": 139, 89 | "lifeExpectancy": 18, 90 | "population": 17100194 91 | }, 92 | "SWITZERLAND": { 93 | "continent": "Europe", 94 | "country": "Switzerland", 95 | "class": "city-Switzerland", 96 | "graphRanking": 151, 97 | "ranking": 6, 98 | "graphSocialSupport": 144, 99 | "socialSupport": 13, 100 | "graphFreedom": 146, 101 | "freedom": 11, 102 | "graphGenerosity": 141, 103 | "generosity": 16, 104 | "graphGdp": 149, 105 | "gdp": 8, 106 | "graphLifeExpectancy": 153, 107 | "lifeExpectancy": 4, 108 | "population": 8596800 109 | }, 110 | "SWEDEN": { 111 | "continent": "Europe", 112 | "country": "Sweden", 113 | "class": "city-Sweden", 114 | "graphRanking": 150, 115 | "ranking": 7, 116 | "graphSocialSupport": 132, 117 | "socialSupport": 25, 118 | "graphFreedom": 147, 119 | "freedom": 10, 120 | "graphGenerosity": 140, 121 | "generosity": 17, 122 | "graphGdp": 144, 123 | "gdp": 13, 124 | "graphLifeExpectancy": 140, 125 | "lifeExpectancy": 17, 126 | "population": 10041496 127 | }, 128 | "NEW_ZEALAND": { 129 | "continent": "Australia", 130 | "country": "New Zealand", 131 | "class": "city-New-Zealand", 132 | "graphRanking": 149, 133 | "ranking": 8, 134 | "graphSocialSupport": 152, 135 | "socialSupport": 5, 136 | "graphFreedom": 149, 137 | "freedom": 8, 138 | "graphGenerosity": 149, 139 | "generosity": 8, 140 | "graphGdp": 131, 141 | "gdp": 26, 142 | "graphLifeExpectancy": 143, 143 | "lifeExpectancy": 14, 144 | "population": 4786243 145 | }, 146 | "CANADA": { 147 | "continent": "North America", 148 | "country": "Canada", 149 | "class": "city-Canada", 150 | "graphRanking": 148, 151 | "ranking": 9, 152 | "graphSocialSupport": 137, 153 | "socialSupport": 20, 154 | "graphFreedom": 148, 155 | "freedom": 9, 156 | "graphGenerosity": 143, 157 | "generosity": 14, 158 | "graphGdp": 138, 159 | "gdp": 19, 160 | "graphLifeExpectancy": 149, 161 | "lifeExpectancy": 8, 162 | "population": 37437787 163 | }, 164 | "AUSTRIA": { 165 | "continent": "Europe", 166 | "country": "Austria", 167 | "class": "city-Austria", 168 | "graphRanking": 147, 169 | "ranking": 10, 170 | "graphSocialSupport": 126, 171 | "socialSupport": 31, 172 | "graphFreedom": 131, 173 | "freedom": 26, 174 | "graphGenerosity": 132, 175 | "generosity": 25, 176 | "graphGdp": 141, 177 | "gdp": 16, 178 | "graphLifeExpectancy": 142, 179 | "lifeExpectancy": 15, 180 | "population": 8959554 181 | }, 182 | "AUSTRALIA": { 183 | "continent": "Australia", 184 | "country": "Australia", 185 | "class": "city-Australia", 186 | "graphRanking": 146, 187 | "ranking": 11, 188 | "graphSocialSupport": 150, 189 | "socialSupport": 7, 190 | "graphFreedom": 140, 191 | "freedom": 17, 192 | "graphGenerosity": 151, 193 | "generosity": 6, 194 | "graphGdp": 139, 195 | "gdp": 18, 196 | "graphLifeExpectancy": 147, 197 | "lifeExpectancy": 10, 198 | "population": 25227423 199 | }, 200 | "COSTA_RICA": { 201 | "continent": "South America", 202 | "country": "Costa Rica", 203 | "class": "city-Costa-Rica", 204 | "graphRanking": 145, 205 | "ranking": 12, 206 | "graphSocialSupport": 115, 207 | "socialSupport": 42, 208 | "graphFreedom": 141, 209 | "freedom": 16, 210 | "graphGenerosity": 82, 211 | "generosity": 75, 212 | "graphGdp": 90, 213 | "gdp": 67, 214 | "graphLifeExpectancy": 129, 215 | "lifeExpectancy": 28, 216 | "population": 5051348 217 | }, 218 | "ISRAEL": { 219 | "continent": "Asia", 220 | "country": "Israel", 221 | "class": "city-Israel", 222 | "graphRanking": 144, 223 | "ranking": 13, 224 | "graphSocialSupport": 119, 225 | "socialSupport": 38, 226 | "graphFreedom": 64, 227 | "freedom": 93, 228 | "graphGenerosity": 133, 229 | "generosity": 24, 230 | "graphGdp": 126, 231 | "gdp": 31, 232 | "graphLifeExpectancy": 146, 233 | "lifeExpectancy": 11, 234 | "population": 8530044 235 | }, 236 | "LUXEMBOURG": { 237 | "continent": "Europe", 238 | "country": "Luxembourg", 239 | "class": "city-Luxembourg", 240 | "graphRanking": 143, 241 | "ranking": 14, 242 | "graphSocialSupport": 130, 243 | "socialSupport": 27, 244 | "graphFreedom": 129, 245 | "freedom": 28, 246 | "graphGenerosity": 127, 247 | "generosity": 30, 248 | "graphGdp": 155, 249 | "gdp": 2, 250 | "graphLifeExpectancy": 141, 251 | "lifeExpectancy": 16, 252 | "population": 616596 253 | }, 254 | "UNITED_KINGDOM": { 255 | "continent": "Europe", 256 | "country": "United Kingdom", 257 | "class": "city-United-Kingdom", 258 | "graphRanking": 142, 259 | "ranking": 15, 260 | "graphSocialSupport": 148, 261 | "socialSupport": 9, 262 | "graphFreedom": 94, 263 | "freedom": 63, 264 | "graphGenerosity": 153, 265 | "generosity": 4, 266 | "graphGdp": 134, 267 | "gdp": 23, 268 | "graphLifeExpectancy": 133, 269 | "lifeExpectancy": 24, 270 | "population": 67560208 271 | }, 272 | "IRELAND": { 273 | "continent": "Europe", 274 | "country": "Ireland", 275 | "class": "city-Ireland", 276 | "graphRanking": 141, 277 | "ranking": 16, 278 | "graphSocialSupport": 151, 279 | "socialSupport": 6, 280 | "graphFreedom": 124, 281 | "freedom": 33, 282 | "graphGenerosity": 148, 283 | "generosity": 9, 284 | "graphGdp": 151, 285 | "gdp": 6, 286 | "graphLifeExpectancy": 137, 287 | "lifeExpectancy": 20, 288 | "population": 4886658 289 | }, 290 | "GERMANY": { 291 | "continent": "Europe", 292 | "country": "Germany", 293 | "class": "city-Germany", 294 | "graphRanking": 140, 295 | "ranking": 17, 296 | "graphSocialSupport": 118, 297 | "socialSupport": 39, 298 | "graphFreedom": 113, 299 | "freedom": 44, 300 | "graphGenerosity": 138, 301 | "generosity": 19, 302 | "graphGdp": 140, 303 | "gdp": 17, 304 | "graphLifeExpectancy": 132, 305 | "lifeExpectancy": 25, 306 | "population": 83541444 307 | }, 308 | "BELGIUM": { 309 | "continent": "Europe", 310 | "country": "Belgium", 311 | "class": "city-Belgium", 312 | "graphRanking": 139, 313 | "ranking": 18, 314 | "graphSocialSupport": 135, 315 | "socialSupport": 22, 316 | "graphFreedom": 104, 317 | "freedom": 53, 318 | "graphGenerosity": 113, 319 | "generosity": 44, 320 | "graphGdp": 136, 321 | "gdp": 21, 322 | "graphLifeExpectancy": 131, 323 | "lifeExpectancy": 26, 324 | "population": 11543664 325 | }, 326 | "UNITED_STATES": { 327 | "continent": "North America", 328 | "country": "United States", 329 | "class": "city-United-States", 330 | "graphRanking": 138, 331 | "ranking": 19, 332 | "graphSocialSupport": 120, 333 | "socialSupport": 37, 334 | "graphFreedom": 95, 335 | "freedom": 62, 336 | "graphGenerosity": 145, 337 | "generosity": 12, 338 | "graphGdp": 147, 339 | "gdp": 10, 340 | "graphLifeExpectancy": 118, 341 | "lifeExpectancy": 39, 342 | "population": 329222905 343 | }, 344 | "CZECH_REPUBLIC": { 345 | "continent": "Europe", 346 | "country": "Czech Republic", 347 | "class": "city-Czech-Republic", 348 | "graphRanking": 137, 349 | "ranking": 20, 350 | "graphSocialSupport": 133, 351 | "socialSupport": 24, 352 | "graphFreedom": 99, 353 | "freedom": 58, 354 | "graphGenerosity": 40, 355 | "generosity": 117, 356 | "graphGdp": 125, 357 | "gdp": 32, 358 | "graphLifeExpectancy": 126, 359 | "lifeExpectancy": 31, 360 | "population": 10690712 361 | }, 362 | "UNITED_ARAB_EMIRATES": { 363 | "continent": "Asia", 364 | "country": "United Arab Emirates", 365 | "class": "city-United-Arab-Emirates", 366 | "graphRanking": 136, 367 | "ranking": 21, 368 | "graphSocialSupport": 85, 369 | "socialSupport": 72, 370 | "graphFreedom": 153, 371 | "freedom": 4, 372 | "graphGenerosity": 142, 373 | "generosity": 15, 374 | "graphGdp": 153, 375 | "gdp": 4, 376 | "graphLifeExpectancy": 97, 377 | "lifeExpectancy": 60, 378 | "population": 9779867 379 | }, 380 | "MALTA": { 381 | "continent": "Europe", 382 | "country": "Malta", 383 | "class": "city-Malta", 384 | "graphRanking": 135, 385 | "ranking": 22, 386 | "graphSocialSupport": 141, 387 | "socialSupport": 16, 388 | "graphFreedom": 145, 389 | "freedom": 12, 390 | "graphGenerosity": 152, 391 | "generosity": 5, 392 | "graphGdp": 129, 393 | "gdp": 28, 394 | "graphLifeExpectancy": 138, 395 | "lifeExpectancy": 19, 396 | "population": 440488 397 | }, 398 | "MEXICO": { 399 | "continent": "South America", 400 | "country": "Mexico", 401 | "class": "city-Mexico", 402 | "graphRanking": 134, 403 | "ranking": 23, 404 | "graphSocialSupport": 90, 405 | "socialSupport": 67, 406 | "graphFreedom": 86, 407 | "freedom": 71, 408 | "graphGenerosity": 37, 409 | "generosity": 120, 410 | "graphGdp": 100, 411 | "gdp": 57, 412 | "graphLifeExpectancy": 111, 413 | "lifeExpectancy": 46, 414 | "population": 127685212 415 | }, 416 | "FRANCE": { 417 | "continent": "Europe", 418 | "country": "France", 419 | "class": "city-France", 420 | "graphRanking": 133, 421 | "ranking": 24, 422 | "graphSocialSupport": 125, 423 | "socialSupport": 32, 424 | "graphFreedom": 88, 425 | "freedom": 69, 426 | "graphGenerosity": 89, 427 | "generosity": 68, 428 | "graphGdp": 132, 429 | "gdp": 25, 430 | "graphLifeExpectancy": 152, 431 | "lifeExpectancy": 5, 432 | "population": 65142593 433 | }, 434 | "CHILE": { 435 | "continent": "South America", 436 | "country": "Chile", 437 | "class": "city-Chile", 438 | "graphRanking": 131, 439 | "ranking": 26, 440 | "graphSocialSupport": 99, 441 | "socialSupport": 58, 442 | "graphFreedom": 59, 443 | "freedom": 98, 444 | "graphGenerosity": 112, 445 | "generosity": 45, 446 | "graphGdp": 108, 447 | "gdp": 49, 448 | "graphLifeExpectancy": 127, 449 | "lifeExpectancy": 30, 450 | "population": 18966955 451 | }, 452 | "GUATEMALA": { 453 | "continent": "South America", 454 | "country": "Guatemala", 455 | "class": "city-Guatemala", 456 | "graphRanking": 130, 457 | "ranking": 27, 458 | "graphSocialSupport": 79, 459 | "socialSupport": 78, 460 | "graphFreedom": 132, 461 | "freedom": 25, 462 | "graphGenerosity": 79, 463 | "generosity": 78, 464 | "graphGdp": 58, 465 | "gdp": 99, 466 | "graphLifeExpectancy": 72, 467 | "lifeExpectancy": 85, 468 | "population": 17607809 469 | }, 470 | "SAUDI_ARABIA": { 471 | "continent": "Asia", 472 | "country": "Saudi Arabia", 473 | "class": "city-Saudi-Arabia", 474 | "graphRanking": 129, 475 | "ranking": 28, 476 | "graphSocialSupport": 95, 477 | "socialSupport": 62, 478 | "graphFreedom": 89, 479 | "freedom": 68, 480 | "graphGenerosity": 75, 481 | "generosity": 82, 482 | "graphGdp": 146, 483 | "gdp": 11, 484 | "graphLifeExpectancy": 83, 485 | "lifeExpectancy": 74, 486 | "population": 34315449 487 | }, 488 | "SPAIN": { 489 | "continent": "Europe", 490 | "country": "Spain", 491 | "class": "city-Spain", 492 | "graphRanking": 127, 493 | "ranking": 30, 494 | "graphSocialSupport": 131, 495 | "socialSupport": 26, 496 | "graphFreedom": 62, 497 | "freedom": 95, 498 | "graphGenerosity": 107, 499 | "generosity": 50, 500 | "graphGdp": 127, 501 | "gdp": 30, 502 | "graphLifeExpectancy": 154, 503 | "lifeExpectancy": 3, 504 | "population": 46737267 505 | }, 506 | "PANAMA": { 507 | "continent": "South America", 508 | "country": "Panama", 509 | "class": "city-Panama", 510 | "graphRanking": 126, 511 | "ranking": 31, 512 | "graphSocialSupport": 116, 513 | "socialSupport": 41, 514 | "graphFreedom": 125, 515 | "freedom": 32, 516 | "graphGenerosity": 69, 517 | "generosity": 88, 518 | "graphGdp": 106, 519 | "gdp": 51, 520 | "graphLifeExpectancy": 124, 521 | "lifeExpectancy": 33, 522 | "population": 4251845 523 | }, 524 | "BRAZIL": { 525 | "continent": "South America", 526 | "country": "Brazil", 527 | "class": "city-Brazil", 528 | "graphRanking": 125, 529 | "ranking": 32, 530 | "graphSocialSupport": 114, 531 | "socialSupport": 43, 532 | "graphFreedom": 73, 533 | "freedom": 84, 534 | "graphGenerosity": 49, 535 | "generosity": 108, 536 | "graphGdp": 87, 537 | "gdp": 70, 538 | "graphLifeExpectancy": 85, 539 | "lifeExpectancy": 72, 540 | "population": 211172424 541 | }, 542 | "URUGUAY": { 543 | "continent": "South America", 544 | "country": "Uruguay", 545 | "class": "city-Uruguay", 546 | "graphRanking": 124, 547 | "ranking": 33, 548 | "graphSocialSupport": 122, 549 | "socialSupport": 35, 550 | "graphFreedom": 127, 551 | "freedom": 30, 552 | "graphGenerosity": 77, 553 | "generosity": 80, 554 | "graphGdp": 105, 555 | "gdp": 52, 556 | "graphLifeExpectancy": 122, 557 | "lifeExpectancy": 35, 558 | "population": 3462659 559 | }, 560 | "SINGAPORE": { 561 | "continent": "Asia", 562 | "country": "Singapore", 563 | "class": "city-Singapore", 564 | "graphRanking": 123, 565 | "ranking": 34, 566 | "graphSocialSupport": 121, 567 | "socialSupport": 36, 568 | "graphFreedom": 137, 569 | "freedom": 20, 570 | "graphGenerosity": 136, 571 | "generosity": 21, 572 | "graphGdp": 154, 573 | "gdp": 3, 574 | "graphLifeExpectancy": 156, 575 | "lifeExpectancy": 1, 576 | "population": 5808327 577 | }, 578 | "EL_SALVADOR": { 579 | "continent": "South America", 580 | "country": "El Salvador", 581 | "class": "city-El-Salvador", 582 | "graphRanking": 122, 583 | "ranking": 35, 584 | "graphSocialSupport": 74, 585 | "socialSupport": 83, 586 | "graphFreedom": 83, 587 | "freedom": 74, 588 | "graphGenerosity": 23, 589 | "generosity": 134, 590 | "graphGdp": 57, 591 | "gdp": 100, 592 | "graphLifeExpectancy": 82, 593 | "lifeExpectancy": 75, 594 | "population": 6456126 595 | }, 596 | "ITALY": { 597 | "continent": "Europe", 598 | "country": "Italy", 599 | "class": "city-Italy", 600 | "graphRanking": 121, 601 | "ranking": 36, 602 | "graphSocialSupport": 134, 603 | "socialSupport": 23, 604 | "graphFreedom": 25, 605 | "freedom": 132, 606 | "graphGenerosity": 109, 607 | "generosity": 48, 608 | "graphGdp": 128, 609 | "gdp": 29, 610 | "graphLifeExpectancy": 150, 611 | "lifeExpectancy": 7, 612 | "population": 60546750 613 | }, 614 | "BAHRAIN": { 615 | "continent": "Asia", 616 | "country": "Bahrain", 617 | "class": "city-Bahrain", 618 | "graphRanking": 120, 619 | "ranking": 37, 620 | "graphSocialSupport": 98, 621 | "socialSupport": 59, 622 | "graphFreedom": 133, 623 | "freedom": 24, 624 | "graphGenerosity": 134, 625 | "generosity": 23, 626 | "graphGdp": 137, 627 | "gdp": 20, 628 | "graphLifeExpectancy": 115, 629 | "lifeExpectancy": 42, 630 | "population": 1645856 631 | }, 632 | "SLOVAKIA": { 633 | "continent": "Europe", 634 | "country": "Slovakia", 635 | "class": "city-Slovakia", 636 | "graphRanking": 119, 637 | "ranking": 38, 638 | "graphSocialSupport": 136, 639 | "socialSupport": 21, 640 | "graphFreedom": 49, 641 | "freedom": 108, 642 | "graphGenerosity": 87, 643 | "generosity": 70, 644 | "graphGdp": 122, 645 | "gdp": 35, 646 | "graphLifeExpectancy": 119, 647 | "lifeExpectancy": 38, 648 | "population": 5457273 649 | }, 650 | "TRINIDAD_AND_TOBAGO": { 651 | "continent": "South America", 652 | "country": "Trinidad and Tobago", 653 | "class": "city-Trinidad-and-Tobago", 654 | "graphRanking": 118, 655 | "ranking": 39, 656 | "graphSocialSupport": 128, 657 | "socialSupport": 29, 658 | "graphFreedom": 106, 659 | "freedom": 51, 660 | "graphGenerosity": 116, 661 | "generosity": 41, 662 | "graphGdp": 119, 663 | "gdp": 38, 664 | "graphLifeExpectancy": 64, 665 | "lifeExpectancy": 93, 666 | "population": 1395407 667 | }, 668 | "POLAND": { 669 | "continent": "Europe", 670 | "country": "Poland", 671 | "class": "city-Poland", 672 | "graphRanking": 117, 673 | "ranking": 40, 674 | "graphSocialSupport": 113, 675 | "socialSupport": 44, 676 | "graphFreedom": 105, 677 | "freedom": 52, 678 | "graphGenerosity": 80, 679 | "generosity": 77, 680 | "graphGdp": 116, 681 | "gdp": 41, 682 | "graphLifeExpectancy": 121, 683 | "lifeExpectancy": 36, 684 | "population": 37884357 685 | }, 686 | "UZBEKISTAN": { 687 | "continent": "Europe", 688 | "country": "Uzbekistan", 689 | "class": "city-Uzbekistan", 690 | "graphRanking": 116, 691 | "ranking": 41, 692 | "graphSocialSupport": 146, 693 | "socialSupport": 11, 694 | "graphFreedom": 156, 695 | "freedom": 1, 696 | "graphGenerosity": 128, 697 | "generosity": 29, 698 | "graphGdp": 53, 699 | "gdp": 104, 700 | "graphLifeExpectancy": 74, 701 | "lifeExpectancy": 83, 702 | "population": 33020717 703 | }, 704 | "LITHUANIA": { 705 | "continent": "Europe", 706 | "country": "Lithuania", 707 | "class": "city-Lithuania", 708 | "graphRanking": 115, 709 | "ranking": 42, 710 | "graphSocialSupport": 140, 711 | "socialSupport": 17, 712 | "graphFreedom": 35, 713 | "freedom": 122, 714 | "graphGenerosity": 33, 715 | "generosity": 124, 716 | "graphGdp": 121, 717 | "gdp": 36, 718 | "graphLifeExpectancy": 95, 719 | "lifeExpectancy": 62, 720 | "population": 2756562 721 | }, 722 | "COLOMBIA": { 723 | "continent": "South America", 724 | "country": "Colombia", 725 | "class": "city-Colombia", 726 | "graphRanking": 114, 727 | "ranking": 43, 728 | "graphSocialSupport": 105, 729 | "socialSupport": 52, 730 | "graphFreedom": 101, 731 | "freedom": 56, 732 | "graphGenerosity": 46, 733 | "generosity": 111, 734 | "graphGdp": 83, 735 | "gdp": 74, 736 | "graphLifeExpectancy": 106, 737 | "lifeExpectancy": 51, 738 | "population": 50385614 739 | }, 740 | "SLOVENIA": { 741 | "continent": "Europe", 742 | "country": "Slovenia", 743 | "class": "city-Slovenia", 744 | "graphRanking": 113, 745 | "ranking": 44, 746 | "graphSocialSupport": 143, 747 | "socialSupport": 14, 748 | "graphFreedom": 144, 749 | "freedom": 13, 750 | "graphGenerosity": 103, 751 | "generosity": 54, 752 | "graphGdp": 123, 753 | "gdp": 34, 754 | "graphLifeExpectancy": 128, 755 | "lifeExpectancy": 29, 756 | "population": 2078712 757 | }, 758 | "NICARAGUA": { 759 | "continent": "South America", 760 | "country": "Nicaragua", 761 | "class": "city-Nicaragua", 762 | "graphRanking": 112, 763 | "ranking": 45, 764 | "graphSocialSupport": 91, 765 | "socialSupport": 66, 766 | "graphFreedom": 87, 767 | "freedom": 70, 768 | "graphGenerosity": 86, 769 | "generosity": 71, 770 | "graphGdp": 49, 771 | "gdp": 108, 772 | "graphLifeExpectancy": 104, 773 | "lifeExpectancy": 53, 774 | "population": 6551834 775 | }, 776 | "ARGENTINA": { 777 | "continent": "South America", 778 | "country": "Argentina", 779 | "class": "city-Argentina", 780 | "graphRanking": 110, 781 | "ranking": 47, 782 | "graphSocialSupport": 111, 783 | "socialSupport": 46, 784 | "graphFreedom": 103, 785 | "freedom": 54, 786 | "graphGenerosity": 34, 787 | "generosity": 123, 788 | "graphGdp": 102, 789 | "gdp": 55, 790 | "graphLifeExpectancy": 120, 791 | "lifeExpectancy": 37, 792 | "population": 44813867 793 | }, 794 | "ROMANIA": { 795 | "continent": "Europe", 796 | "country": "Romania", 797 | "class": "city-Romania", 798 | "graphRanking": 109, 799 | "ranking": 48, 800 | "graphSocialSupport": 71, 801 | "socialSupport": 86, 802 | "graphFreedom": 100, 803 | "freedom": 57, 804 | "graphGenerosity": 55, 805 | "generosity": 102, 806 | "graphGdp": 109, 807 | "gdp": 48, 808 | "graphLifeExpectancy": 96, 809 | "lifeExpectancy": 61, 810 | "population": 19354380 811 | }, 812 | "CYPRUS": { 813 | "continent": "Europe", 814 | "country": "Cyprus", 815 | "class": "city-Cyprus", 816 | "graphRanking": 108, 817 | "ranking": 49, 818 | "graphSocialSupport": 67, 819 | "socialSupport": 90, 820 | "graphFreedom": 76, 821 | "freedom": 81, 822 | "graphGenerosity": 118, 823 | "generosity": 39, 824 | "graphGdp": 124, 825 | "gdp": 33, 826 | "graphLifeExpectancy": 151, 827 | "lifeExpectancy": 6, 828 | "population": 1199298 829 | }, 830 | "ECUADOR": { 831 | "continent": "South America", 832 | "country": "Ecuador", 833 | "class": "city-Ecuador", 834 | "graphRanking": 107, 835 | "ranking": 50, 836 | "graphSocialSupport": 86, 837 | "socialSupport": 71, 838 | "graphFreedom": 115, 839 | "freedom": 42, 840 | "graphGenerosity": 62, 841 | "generosity": 95, 842 | "graphGdp": 71, 843 | "gdp": 86, 844 | "graphLifeExpectancy": 112, 845 | "lifeExpectancy": 45, 846 | "population": 17395259 847 | }, 848 | "KUWAIT": { 849 | "continent": "Asia", 850 | "country": "Kuwait", 851 | "class": "city-Kuwait", 852 | "graphRanking": 106, 853 | "ranking": 51, 854 | "graphSocialSupport": 88, 855 | "socialSupport": 69, 856 | "graphFreedom": 110, 857 | "freedom": 47, 858 | "graphGenerosity": 115, 859 | "generosity": 42, 860 | "graphGdp": 152, 861 | "gdp": 5, 862 | "graphLifeExpectancy": 87, 863 | "lifeExpectancy": 70, 864 | "population": 4213357 865 | }, 866 | "THAILAND": { 867 | "continent": "Asia", 868 | "country": "Thailand", 869 | "class": "city-Thailand", 870 | "graphRanking": 105, 871 | "ranking": 52, 872 | "graphSocialSupport": 104, 873 | "socialSupport": 53, 874 | "graphFreedom": 139, 875 | "freedom": 18, 876 | "graphGenerosity": 147, 877 | "generosity": 10, 878 | "graphGdp": 95, 879 | "gdp": 62, 880 | "graphLifeExpectancy": 99, 881 | "lifeExpectancy": 58, 882 | "population": 69640992 883 | }, 884 | "LATVIA": { 885 | "continent": "Europe", 886 | "country": "Latvia", 887 | "class": "city-Latvia", 888 | "graphRanking": 104, 889 | "ranking": 53, 890 | "graphSocialSupport": 123, 891 | "socialSupport": 34, 892 | "graphFreedom": 31, 893 | "freedom": 126, 894 | "graphGenerosity": 52, 895 | "generosity": 105, 896 | "graphGdp": 114, 897 | "gdp": 43, 898 | "graphLifeExpectancy": 89, 899 | "lifeExpectancy": 68, 900 | "population": 1905065 901 | }, 902 | "SOUTH_KOREA": { 903 | "continent": "Asia", 904 | "country": "South Korea", 905 | "class": "city-South-Korea", 906 | "graphRanking": 103, 907 | "ranking": 54, 908 | "graphSocialSupport": 66, 909 | "socialSupport": 91, 910 | "graphFreedom": 13, 911 | "freedom": 144, 912 | "graphGenerosity": 117, 913 | "generosity": 40, 914 | "graphGdp": 130, 915 | "gdp": 27, 916 | "graphLifeExpectancy": 148, 917 | "lifeExpectancy": 9, 918 | "population": 51231212 919 | }, 920 | "ESTONIA": { 921 | "continent": "Europe", 922 | "country": "Estonia", 923 | "class": "city-Estonia", 924 | "graphRanking": 102, 925 | "ranking": 55, 926 | "graphSocialSupport": 145, 927 | "socialSupport": 12, 928 | "graphFreedom": 112, 929 | "freedom": 45, 930 | "graphGenerosity": 74, 931 | "generosity": 83, 932 | "graphGdp": 120, 933 | "gdp": 37, 934 | "graphLifeExpectancy": 116, 935 | "lifeExpectancy": 41, 936 | "population": 1325735 937 | }, 938 | "JAMAICA": { 939 | "continent": "South America", 940 | "country": "Jamaica", 941 | "class": "city-Jamaica", 942 | "graphRanking": 101, 943 | "ranking": 56, 944 | "graphSocialSupport": 129, 945 | "socialSupport": 28, 946 | "graphFreedom": 108, 947 | "freedom": 49, 948 | "graphGenerosity": 38, 949 | "generosity": 119, 950 | "graphGdp": 64, 951 | "gdp": 93, 952 | "graphLifeExpectancy": 102, 953 | "lifeExpectancy": 55, 954 | "population": 2949350 955 | }, 956 | "MAURITIUS": { 957 | "continent": "South America", 958 | "country": "Mauritius", 959 | "class": "city-Mauritius", 960 | "graphRanking": 100, 961 | "ranking": 57, 962 | "graphSocialSupport": 103, 963 | "socialSupport": 54, 964 | "graphFreedom": 117, 965 | "freedom": 40, 966 | "graphGenerosity": 120, 967 | "generosity": 37, 968 | "graphGdp": 104, 969 | "gdp": 53, 970 | "graphLifeExpectancy": 84, 971 | "lifeExpectancy": 73, 972 | "population": 1269842 973 | }, 974 | "JAPAN": { 975 | "continent": "Asia", 976 | "country": "Japan", 977 | "class": "city-Japan", 978 | "graphRanking": 99, 979 | "ranking": 58, 980 | "graphSocialSupport": 107, 981 | "socialSupport": 50, 982 | "graphFreedom": 93, 983 | "freedom": 64, 984 | "graphGenerosity": 65, 985 | "generosity": 92, 986 | "graphGdp": 133, 987 | "gdp": 24, 988 | "graphLifeExpectancy": 155, 989 | "lifeExpectancy": 2, 990 | "population": 126833243 991 | }, 992 | "HONDURAS": { 993 | "continent": "South America", 994 | "country": "Honduras", 995 | "class": "city-Honduras", 996 | "graphRanking": 98, 997 | "ranking": 59, 998 | "graphSocialSupport": 73, 999 | "socialSupport": 84, 1000 | "graphFreedom": 118, 1001 | "freedom": 39, 1002 | "graphGenerosity": 106, 1003 | "generosity": 51, 1004 | "graphGdp": 44, 1005 | "gdp": 113, 1006 | "graphLifeExpectancy": 100, 1007 | "lifeExpectancy": 57, 1008 | "population": 9758648 1009 | }, 1010 | "KAZAKHSTAN": { 1011 | "continent": "Europe", 1012 | "country": "Kazakhstan", 1013 | "class": "city-Kazakhstan", 1014 | "graphRanking": 97, 1015 | "ranking": 60, 1016 | "graphSocialSupport": 138, 1017 | "socialSupport": 19, 1018 | "graphFreedom": 77, 1019 | "freedom": 80, 1020 | "graphGenerosity": 100, 1021 | "generosity": 57, 1022 | "graphGdp": 110, 1023 | "gdp": 47, 1024 | "graphLifeExpectancy": 69, 1025 | "lifeExpectancy": 88, 1026 | "population": 18569919 1027 | }, 1028 | "BOLIVIA": { 1029 | "continent": "South America", 1030 | "country": "Bolivia", 1031 | "class": "city-Bolivia", 1032 | "graphRanking": 96, 1033 | "ranking": 61, 1034 | "graphSocialSupport": 64, 1035 | "socialSupport": 93, 1036 | "graphFreedom": 122, 1037 | "freedom": 35, 1038 | "graphGenerosity": 53, 1039 | "generosity": 104, 1040 | "graphGdp": 56, 1041 | "gdp": 101, 1042 | "graphLifeExpectancy": 63, 1043 | "lifeExpectancy": 94, 1044 | "population": 11525833 1045 | }, 1046 | "HUNGARY": { 1047 | "continent": "Europe", 1048 | "country": "Hungary", 1049 | "class": "city-Hungary", 1050 | "graphRanking": 95, 1051 | "ranking": 62, 1052 | "graphSocialSupport": 106, 1053 | "socialSupport": 51, 1054 | "graphFreedom": 19, 1055 | "freedom": 138, 1056 | "graphGenerosity": 57, 1057 | "generosity": 100, 1058 | "graphGdp": 115, 1059 | "gdp": 42, 1060 | "graphLifeExpectancy": 101, 1061 | "lifeExpectancy": 56, 1062 | "population": 9682711 1063 | }, 1064 | "PARAGUAY": { 1065 | "continent": "South America", 1066 | "country": "Paraguay", 1067 | "class": "city-Paraguay", 1068 | "graphRanking": 94, 1069 | "ranking": 63, 1070 | "graphSocialSupport": 127, 1071 | "socialSupport": 30, 1072 | "graphFreedom": 123, 1073 | "freedom": 34, 1074 | "graphGenerosity": 90, 1075 | "generosity": 67, 1076 | "graphGdp": 67, 1077 | "gdp": 90, 1078 | "graphLifeExpectancy": 76, 1079 | "lifeExpectancy": 81, 1080 | "population": 7051610 1081 | }, 1082 | "PERU": { 1083 | "continent": "South America", 1084 | "country": "Peru", 1085 | "class": "city-Peru", 1086 | "graphRanking": 92, 1087 | "ranking": 65, 1088 | "graphSocialSupport": 80, 1089 | "socialSupport": 77, 1090 | "graphFreedom": 96, 1091 | "freedom": 61, 1092 | "graphGenerosity": 31, 1093 | "generosity": 126, 1094 | "graphGdp": 81, 1095 | "gdp": 76, 1096 | "graphLifeExpectancy": 110, 1097 | "lifeExpectancy": 47, 1098 | "population": 32547062 1099 | }, 1100 | "PORTUGAL": { 1101 | "continent": "Europe", 1102 | "country": "Portugal", 1103 | "class": "city-Portugal", 1104 | "graphRanking": 91, 1105 | "ranking": 66, 1106 | "graphSocialSupport": 110, 1107 | "socialSupport": 47, 1108 | "graphFreedom": 120, 1109 | "freedom": 37, 1110 | "graphGenerosity": 35, 1111 | "generosity": 122, 1112 | "graphGdp": 118, 1113 | "gdp": 39, 1114 | "graphLifeExpectancy": 135, 1115 | "lifeExpectancy": 22, 1116 | "population": 10223582 1117 | }, 1118 | "PAKISTAN": { 1119 | "continent": "Asia", 1120 | "country": "Pakistan", 1121 | "class": "city-Pakistan", 1122 | "graphRanking": 90, 1123 | "ranking": 67, 1124 | "graphSocialSupport": 27, 1125 | "socialSupport": 130, 1126 | "graphFreedom": 43, 1127 | "freedom": 114, 1128 | "graphGenerosity": 99, 1129 | "generosity": 58, 1130 | "graphGdp": 47, 1131 | "gdp": 110, 1132 | "graphLifeExpectancy": 43, 1133 | "lifeExpectancy": 114, 1134 | "population": 216905133 1135 | }, 1136 | "RUSSIA": { 1137 | "continent": "Europe", 1138 | "country": "Russia", 1139 | "class": "city-Russia", 1140 | "graphRanking": 89, 1141 | "ranking": 68, 1142 | "graphSocialSupport": 117, 1143 | "socialSupport": 40, 1144 | "graphFreedom": 50, 1145 | "freedom": 107, 1146 | "graphGenerosity": 56, 1147 | "generosity": 101, 1148 | "graphGdp": 112, 1149 | "gdp": 45, 1150 | "graphLifeExpectancy": 68, 1151 | "lifeExpectancy": 89, 1152 | "population": 145881748 1153 | }, 1154 | "PHILIPPINES": { 1155 | "continent": "Asia", 1156 | "country": "Philippines", 1157 | "class": "city-Philippines", 1158 | "graphRanking": 88, 1159 | "ranking": 69, 1160 | "graphSocialSupport": 82, 1161 | "socialSupport": 75, 1162 | "graphFreedom": 142, 1163 | "freedom": 15, 1164 | "graphGenerosity": 42, 1165 | "generosity": 115, 1166 | "graphGdp": 60, 1167 | "gdp": 97, 1168 | "graphLifeExpectancy": 58, 1169 | "lifeExpectancy": 99, 1170 | "population": 108234286 1171 | }, 1172 | "SERBIA": { 1173 | "continent": "Europe", 1174 | "country": "Serbia", 1175 | "class": "city-Serbia", 1176 | "graphRanking": 87, 1177 | "ranking": 70, 1178 | "graphSocialSupport": 100, 1179 | "socialSupport": 57, 1180 | "graphFreedom": 33, 1181 | "freedom": 124, 1182 | "graphGenerosity": 73, 1183 | "generosity": 84, 1184 | "graphGdp": 86, 1185 | "gdp": 71, 1186 | "graphLifeExpectancy": 109, 1187 | "lifeExpectancy": 48, 1188 | "population": 8769717 1189 | }, 1190 | "MOLDOVA": { 1191 | "continent": "Europe", 1192 | "country": "Moldova", 1193 | "class": "city-Moldova", 1194 | "graphRanking": 86, 1195 | "ranking": 71, 1196 | "graphSocialSupport": 92, 1197 | "socialSupport": 65, 1198 | "graphFreedom": 29, 1199 | "freedom": 128, 1200 | "graphGenerosity": 71, 1201 | "generosity": 86, 1202 | "graphGdp": 48, 1203 | "gdp": 109, 1204 | "graphLifeExpectancy": 71, 1205 | "lifeExpectancy": 86, 1206 | "population": 4042626 1207 | }, 1208 | "LIBYA": { 1209 | "continent": "Africa", 1210 | "country": "Libya", 1211 | "class": "city-Libya", 1212 | "graphRanking": 85, 1213 | "ranking": 72, 1214 | "graphSocialSupport": 84, 1215 | "socialSupport": 73, 1216 | "graphFreedom": 78, 1217 | "freedom": 79, 1218 | "graphGenerosity": 70, 1219 | "generosity": 87, 1220 | "graphGdp": 94, 1221 | "gdp": 63, 1222 | "graphLifeExpectancy": 61, 1223 | "lifeExpectancy": 96, 1224 | "population": 6784456 1225 | }, 1226 | "MONTENEGRO": { 1227 | "continent": "Europe", 1228 | "country": "Montenegro", 1229 | "class": "city-Montenegro", 1230 | "graphRanking": 84, 1231 | "ranking": 73, 1232 | "graphSocialSupport": 97, 1233 | "socialSupport": 60, 1234 | "graphFreedom": 18, 1235 | "freedom": 139, 1236 | "graphGenerosity": 81, 1237 | "generosity": 76, 1238 | "graphGdp": 96, 1239 | "gdp": 61, 1240 | "graphLifeExpectancy": 113, 1241 | "lifeExpectancy": 44, 1242 | "population": 628016 1243 | }, 1244 | "TAJIKISTAN": { 1245 | "continent": "Europe", 1246 | "country": "Tajikistan", 1247 | "class": "city-Tajikistan", 1248 | "graphRanking": 83, 1249 | "ranking": 74, 1250 | "graphSocialSupport": 44, 1251 | "socialSupport": 113, 1252 | "graphFreedom": 71, 1253 | "freedom": 86, 1254 | "graphGenerosity": 85, 1255 | "generosity": 72, 1256 | "graphGdp": 34, 1257 | "gdp": 123, 1258 | "graphLifeExpectancy": 65, 1259 | "lifeExpectancy": 92, 1260 | "population": 9338006 1261 | }, 1262 | "CROATIA": { 1263 | "continent": "Europe", 1264 | "country": "Croatia", 1265 | "class": "city-Croatia", 1266 | "graphRanking": 82, 1267 | "ranking": 75, 1268 | "graphSocialSupport": 78, 1269 | "socialSupport": 79, 1270 | "graphFreedom": 39, 1271 | "freedom": 118, 1272 | "graphGenerosity": 76, 1273 | "generosity": 81, 1274 | "graphGdp": 107, 1275 | "gdp": 50, 1276 | "graphLifeExpectancy": 125, 1277 | "lifeExpectancy": 32, 1278 | "population": 4128336 1279 | }, 1280 | "DOMINICAN_REPUBLIC": { 1281 | "continent": "South America", 1282 | "country": "Dominican Republic", 1283 | "class": "city-Dominican-Republic", 1284 | "graphRanking": 80, 1285 | "ranking": 77, 1286 | "graphSocialSupport": 102, 1287 | "socialSupport": 55, 1288 | "graphFreedom": 114, 1289 | "freedom": 43, 1290 | "graphGenerosity": 64, 1291 | "generosity": 93, 1292 | "graphGdp": 88, 1293 | "gdp": 69, 1294 | "graphLifeExpectancy": 77, 1295 | "lifeExpectancy": 80, 1296 | "population": 10747698 1297 | }, 1298 | "BOSNIA_AND_HERZEGOVINA": { 1299 | "continent": "Europe", 1300 | "country": "Bosnia and Herzegovina", 1301 | "class": "city-Bosnia-and-Herzegovina", 1302 | "graphRanking": 79, 1303 | "ranking": 78, 1304 | "graphSocialSupport": 65, 1305 | "socialSupport": 92, 1306 | "graphFreedom": 20, 1307 | "freedom": 137, 1308 | "graphGenerosity": 125, 1309 | "generosity": 32, 1310 | "graphGdp": 75, 1311 | "gdp": 82, 1312 | "graphLifeExpectancy": 107, 1313 | "lifeExpectancy": 50, 1314 | "population": 3298858 1315 | }, 1316 | "TURKEY": { 1317 | "continent": "Europe", 1318 | "country": "Turkey", 1319 | "class": "city-Turkey", 1320 | "graphRanking": 78, 1321 | "ranking": 79, 1322 | "graphSocialSupport": 96, 1323 | "socialSupport": 61, 1324 | "graphFreedom": 17, 1325 | "freedom": 140, 1326 | "graphGenerosity": 59, 1327 | "generosity": 98, 1328 | "graphGdp": 113, 1329 | "gdp": 44, 1330 | "graphLifeExpectancy": 88, 1331 | "lifeExpectancy": 69, 1332 | "population": 83510766 1333 | }, 1334 | "MALAYSIA": { 1335 | "continent": "Asia", 1336 | "country": "Malaysia", 1337 | "class": "city-Malaysia", 1338 | "graphRanking": 77, 1339 | "ranking": 80, 1340 | "graphSocialSupport": 60, 1341 | "socialSupport": 97, 1342 | "graphFreedom": 121, 1343 | "freedom": 36, 1344 | "graphGenerosity": 130, 1345 | "generosity": 27, 1346 | "graphGdp": 117, 1347 | "gdp": 40, 1348 | "graphLifeExpectancy": 98, 1349 | "lifeExpectancy": 59, 1350 | "population": 31982625 1351 | }, 1352 | "BELARUS": { 1353 | "continent": "Europe", 1354 | "country": "Belarus", 1355 | "class": "city-Belarus", 1356 | "graphRanking": 76, 1357 | "ranking": 81, 1358 | "graphSocialSupport": 124, 1359 | "socialSupport": 33, 1360 | "graphFreedom": 26, 1361 | "freedom": 131, 1362 | "graphGenerosity": 54, 1363 | "generosity": 103, 1364 | "graphGdp": 99, 1365 | "gdp": 58, 1366 | "graphLifeExpectancy": 81, 1367 | "lifeExpectancy": 76, 1368 | "population": 9452324 1369 | }, 1370 | "GREECE": { 1371 | "continent": "Europe", 1372 | "country": "Greece", 1373 | "class": "city-Greece", 1374 | "graphRanking": 75, 1375 | "ranking": 82, 1376 | "graphSocialSupport": 55, 1377 | "socialSupport": 102, 1378 | "graphFreedom": 7, 1379 | "freedom": 150, 1380 | "graphGenerosity": 5, 1381 | "generosity": 152, 1382 | "graphGdp": 111, 1383 | "gdp": 46, 1384 | "graphLifeExpectancy": 136, 1385 | "lifeExpectancy": 21, 1386 | "population": 10469606 1387 | }, 1388 | "MONGOLIA": { 1389 | "continent": "Asia", 1390 | "country": "Mongolia", 1391 | "class": "city-Mongolia", 1392 | "graphRanking": 74, 1393 | "ranking": 83, 1394 | "graphSocialSupport": 147, 1395 | "socialSupport": 10, 1396 | "graphFreedom": 45, 1397 | "freedom": 112, 1398 | "graphGenerosity": 119, 1399 | "generosity": 38, 1400 | "graphGdp": 77, 1401 | "gdp": 80, 1402 | "graphLifeExpectancy": 60, 1403 | "lifeExpectancy": 97, 1404 | "population": 3229479 1405 | }, 1406 | "MACEDONIA": { 1407 | "continent": "Europe", 1408 | "country": "Macedonia", 1409 | "class": "city-Macedonia", 1410 | "graphRanking": 73, 1411 | "ranking": 84, 1412 | "graphSocialSupport": 83, 1413 | "socialSupport": 74, 1414 | "graphFreedom": 52, 1415 | "freedom": 105, 1416 | "graphGenerosity": 102, 1417 | "generosity": 55, 1418 | "graphGdp": 82, 1419 | "gdp": 75, 1420 | "graphLifeExpectancy": 105, 1421 | "lifeExpectancy": 52, 1422 | "population": 2083459 1423 | }, 1424 | "NIGERIA": { 1425 | "continent": "Africa", 1426 | "country": "Nigeria", 1427 | "class": "city-Nigeria", 1428 | "graphRanking": 72, 1429 | "ranking": 85, 1430 | "graphSocialSupport": 46, 1431 | "socialSupport": 111, 1432 | "graphFreedom": 82, 1433 | "freedom": 75, 1434 | "graphGenerosity": 98, 1435 | "generosity": 59, 1436 | "graphGdp": 50, 1437 | "gdp": 107, 1438 | "graphLifeExpectancy": 12, 1439 | "lifeExpectancy": 145, 1440 | "population": 201366869 1441 | }, 1442 | "KYRGYZSTAN": { 1443 | "continent": "Europe", 1444 | "country": "Kyrgyzstan", 1445 | "class": "city-Kyrgyzstan", 1446 | "graphRanking": 71, 1447 | "ranking": 86, 1448 | "graphSocialSupport": 112, 1449 | "socialSupport": 45, 1450 | "graphFreedom": 119, 1451 | "freedom": 38, 1452 | "graphGenerosity": 121, 1453 | "generosity": 36, 1454 | "graphGdp": 37, 1455 | "gdp": 120, 1456 | "graphLifeExpectancy": 66, 1457 | "lifeExpectancy": 91, 1458 | "population": 6424561 1459 | }, 1460 | "TURKMENISTAN": { 1461 | "continent": "Europe", 1462 | "country": "Turkmenistan", 1463 | "class": "city-Turkmenistan", 1464 | "graphRanking": 70, 1465 | "ranking": 87, 1466 | "graphSocialSupport": 149, 1467 | "socialSupport": 8, 1468 | "graphFreedom": 74, 1469 | "freedom": 83, 1470 | "graphGenerosity": 124, 1471 | "generosity": 33, 1472 | "graphGdp": 97, 1473 | "gdp": 60, 1474 | "graphLifeExpectancy": 57, 1475 | "lifeExpectancy": 100, 1476 | "population": 5949295 1477 | }, 1478 | "ALGERIA": { 1479 | "continent": "Africa", 1480 | "country": "Algeria", 1481 | "class": "city-Algeria", 1482 | "graphRanking": 69, 1483 | "ranking": 88, 1484 | "graphSocialSupport": 56, 1485 | "socialSupport": 101, 1486 | "graphFreedom": 8, 1487 | "freedom": 149, 1488 | "graphGenerosity": 29, 1489 | "generosity": 128, 1490 | "graphGdp": 85, 1491 | "gdp": 72, 1492 | "graphLifeExpectancy": 79, 1493 | "lifeExpectancy": 78, 1494 | "population": 43116552 1495 | }, 1496 | "MOROCCO": { 1497 | "continent": "Africa", 1498 | "country": "Morocco", 1499 | "class": "city-Morocco", 1500 | "graphRanking": 68, 1501 | "ranking": 89, 1502 | "graphSocialSupport": 18, 1503 | "socialSupport": 139, 1504 | "graphFreedom": 81, 1505 | "freedom": 76, 1506 | "graphGenerosity": 3, 1507 | "generosity": 154, 1508 | "graphGdp": 59, 1509 | "gdp": 98, 1510 | "graphLifeExpectancy": 78, 1511 | "lifeExpectancy": 79, 1512 | "population": 36506904 1513 | }, 1514 | "AZERBAIJAN": { 1515 | "continent": "Asia", 1516 | "country": "Azerbaijan", 1517 | "class": "city-Azerbaijan", 1518 | "graphRanking": 67, 1519 | "ranking": 90, 1520 | "graphSocialSupport": 53, 1521 | "socialSupport": 104, 1522 | "graphFreedom": 56, 1523 | "freedom": 101, 1524 | "graphGenerosity": 11, 1525 | "generosity": 146, 1526 | "graphGdp": 92, 1527 | "gdp": 65, 1528 | "graphLifeExpectancy": 75, 1529 | "lifeExpectancy": 82, 1530 | "population": 10055417 1531 | }, 1532 | "LEBANON": { 1533 | "continent": "Asia", 1534 | "country": "Lebanon", 1535 | "class": "city-Lebanon", 1536 | "graphRanking": 66, 1537 | "ranking": 91, 1538 | "graphSocialSupport": 68, 1539 | "socialSupport": 89, 1540 | "graphFreedom": 21, 1541 | "freedom": 136, 1542 | "graphGenerosity": 94, 1543 | "generosity": 63, 1544 | "graphGdp": 84, 1545 | "gdp": 73, 1546 | "graphLifeExpectancy": 91, 1547 | "lifeExpectancy": 66, 1548 | "population": 6858057 1549 | }, 1550 | "INDONESIA": { 1551 | "continent": "Asia", 1552 | "country": "Indonesia", 1553 | "class": "city-Indonesia", 1554 | "graphRanking": 65, 1555 | "ranking": 92, 1556 | "graphSocialSupport": 63, 1557 | "socialSupport": 94, 1558 | "graphFreedom": 109, 1559 | "freedom": 48, 1560 | "graphGenerosity": 155, 1561 | "generosity": 2, 1562 | "graphGdp": 74, 1563 | "gdp": 83, 1564 | "graphLifeExpectancy": 59, 1565 | "lifeExpectancy": 98, 1566 | "population": 270860549 1567 | }, 1568 | "CHINA": { 1569 | "continent": "Asia", 1570 | "country": "China", 1571 | "class": "city-China", 1572 | "graphRanking": 64, 1573 | "ranking": 93, 1574 | "graphSocialSupport": 49, 1575 | "socialSupport": 108, 1576 | "graphFreedom": 126, 1577 | "freedom": 31, 1578 | "graphGenerosity": 24, 1579 | "generosity": 133, 1580 | "graphGdp": 89, 1581 | "gdp": 68, 1582 | "graphLifeExpectancy": 123, 1583 | "lifeExpectancy": 34, 1584 | "population": 1434254374 1585 | }, 1586 | "VIETNAM": { 1587 | "continent": "Asia", 1588 | "country": "Vietnam", 1589 | "class": "city-Vietnam", 1590 | "graphRanking": 63, 1591 | "ranking": 94, 1592 | "graphSocialSupport": 93, 1593 | "socialSupport": 64, 1594 | "graphFreedom": 134, 1595 | "freedom": 23, 1596 | "graphGenerosity": 60, 1597 | "generosity": 97, 1598 | "graphGdp": 52, 1599 | "gdp": 105, 1600 | "graphLifeExpectancy": 108, 1601 | "lifeExpectancy": 49, 1602 | "population": 96533160 1603 | }, 1604 | "BHUTAN": { 1605 | "continent": "Asia", 1606 | "country": "Bhutan", 1607 | "class": "city-Bhutan", 1608 | "graphRanking": 62, 1609 | "ranking": 95, 1610 | "graphSocialSupport": 89, 1611 | "socialSupport": 68, 1612 | "graphFreedom": 98, 1613 | "freedom": 59, 1614 | "graphGenerosity": 144, 1615 | "generosity": 13, 1616 | "graphGdp": 62, 1617 | "gdp": 95, 1618 | "graphLifeExpectancy": 53, 1619 | "lifeExpectancy": 104, 1620 | "population": 763787 1621 | }, 1622 | "CAMEROON": { 1623 | "continent": "Africa", 1624 | "country": "Cameroon", 1625 | "class": "city-Cameroon", 1626 | "graphRanking": 61, 1627 | "ranking": 96, 1628 | "graphSocialSupport": 28, 1629 | "socialSupport": 129, 1630 | "graphFreedom": 67, 1631 | "freedom": 90, 1632 | "graphGenerosity": 66, 1633 | "generosity": 91, 1634 | "graphGdp": 36, 1635 | "gdp": 121, 1636 | "graphLifeExpectancy": 16, 1637 | "lifeExpectancy": 141, 1638 | "population": 25928621 1639 | }, 1640 | "BULGARIA": { 1641 | "continent": "Europe", 1642 | "country": "Bulgaria", 1643 | "class": "city-Bulgaria", 1644 | "graphRanking": 60, 1645 | "ranking": 97, 1646 | "graphSocialSupport": 139, 1647 | "socialSupport": 18, 1648 | "graphFreedom": 42, 1649 | "freedom": 115, 1650 | "graphGenerosity": 45, 1651 | "generosity": 112, 1652 | "graphGdp": 101, 1653 | "gdp": 56, 1654 | "graphLifeExpectancy": 92, 1655 | "lifeExpectancy": 65, 1656 | "population": 6996096 1657 | }, 1658 | "GHANA": { 1659 | "continent": "Africa", 1660 | "country": "Ghana", 1661 | "class": "city-Ghana", 1662 | "graphRanking": 59, 1663 | "ranking": 98, 1664 | "graphSocialSupport": 25, 1665 | "socialSupport": 132, 1666 | "graphFreedom": 66, 1667 | "freedom": 91, 1668 | "graphGenerosity": 105, 1669 | "generosity": 52, 1670 | "graphGdp": 43, 1671 | "gdp": 114, 1672 | "graphLifeExpectancy": 36, 1673 | "lifeExpectancy": 121, 1674 | "population": 30469316 1675 | }, 1676 | "IVORY_COAST": { 1677 | "continent": "Africa", 1678 | "country": "Ivory Coast", 1679 | "class": "city-Ivory-Coast", 1680 | "graphRanking": 58, 1681 | "ranking": 99, 1682 | "graphSocialSupport": 20, 1683 | "socialSupport": 137, 1684 | "graphFreedom": 57, 1685 | "freedom": 100, 1686 | "graphGenerosity": 43, 1687 | "generosity": 114, 1688 | "graphGdp": 39, 1689 | "gdp": 118, 1690 | "graphLifeExpectancy": 10, 1691 | "lifeExpectancy": 147, 1692 | "population": 25767628 1693 | }, 1694 | "NEPAL": { 1695 | "continent": "Asia", 1696 | "country": "Nepal", 1697 | "class": "city-Nepal", 1698 | "graphRanking": 57, 1699 | "ranking": 100, 1700 | "graphSocialSupport": 70, 1701 | "socialSupport": 87, 1702 | "graphFreedom": 90, 1703 | "freedom": 67, 1704 | "graphGenerosity": 111, 1705 | "generosity": 46, 1706 | "graphGdp": 30, 1707 | "gdp": 127, 1708 | "graphLifeExpectancy": 62, 1709 | "lifeExpectancy": 95, 1710 | "population": 28643933 1711 | }, 1712 | "JORDAN": { 1713 | "continent": "Asia", 1714 | "country": "Jordan", 1715 | "class": "city-Jordan", 1716 | "graphRanking": 56, 1717 | "ranking": 101, 1718 | "graphSocialSupport": 69, 1719 | "socialSupport": 88, 1720 | "graphFreedom": 69, 1721 | "freedom": 88, 1722 | "graphGenerosity": 39, 1723 | "generosity": 118, 1724 | "graphGdp": 65, 1725 | "gdp": 92, 1726 | "graphLifeExpectancy": 94, 1727 | "lifeExpectancy": 63, 1728 | "population": 10114024 1729 | }, 1730 | "BENIN": { 1731 | "continent": "Africa", 1732 | "country": "Benin", 1733 | "class": "city-Benin", 1734 | "graphRanking": 55, 1735 | "ranking": 102, 1736 | "graphSocialSupport": 4, 1737 | "socialSupport": 153, 1738 | "graphFreedom": 54, 1739 | "freedom": 103, 1740 | "graphGenerosity": 41, 1741 | "generosity": 116, 1742 | "graphGdp": 29, 1743 | "gdp": 128, 1744 | "graphLifeExpectancy": 24, 1745 | "lifeExpectancy": 133, 1746 | "population": 11826158 1747 | }, 1748 | "CONGO_BRAZZAVILLE": { 1749 | "continent": "Africa", 1750 | "country": "Congo (Brazzaville)", 1751 | "class": "city-Congo-(Brazzaville)", 1752 | "graphRanking": 54, 1753 | "ranking": 103, 1754 | "graphSocialSupport": 19, 1755 | "socialSupport": 138, 1756 | "graphFreedom": 65, 1757 | "freedom": 92, 1758 | "graphGenerosity": 17, 1759 | "generosity": 140, 1760 | "graphGdp": 46, 1761 | "gdp": 111, 1762 | "graphLifeExpectancy": 41, 1763 | "lifeExpectancy": 116, 1764 | "population": 5391159 1765 | }, 1766 | "GABON": { 1767 | "continent": "Africa", 1768 | "country": "Gabon", 1769 | "class": "city-Gabon", 1770 | "graphRanking": 53, 1771 | "ranking": 104, 1772 | "graphSocialSupport": 62, 1773 | "socialSupport": 95, 1774 | "graphFreedom": 38, 1775 | "freedom": 119, 1776 | "graphGenerosity": 14, 1777 | "generosity": 143, 1778 | "graphGdp": 98, 1779 | "gdp": 59, 1780 | "graphLifeExpectancy": 49, 1781 | "lifeExpectancy": 108, 1782 | "population": 2176949 1783 | }, 1784 | "LAOS": { 1785 | "continent": "Asia", 1786 | "country": "Laos", 1787 | "class": "city-Laos", 1788 | "graphRanking": 52, 1789 | "ranking": 105, 1790 | "graphSocialSupport": 37, 1791 | "socialSupport": 120, 1792 | "graphFreedom": 135, 1793 | "freedom": 22, 1794 | "graphGenerosity": 123, 1795 | "generosity": 34, 1796 | "graphGdp": 55, 1797 | "gdp": 102, 1798 | "graphLifeExpectancy": 45, 1799 | "lifeExpectancy": 112, 1800 | "population": 7177820 1801 | }, 1802 | "SOUTH_AFRICA": { 1803 | "continent": "Africa", 1804 | "country": "South Africa", 1805 | "class": "city-South-Africa", 1806 | "graphRanking": 51, 1807 | "ranking": 106, 1808 | "graphSocialSupport": 94, 1809 | "socialSupport": 63, 1810 | "graphFreedom": 72, 1811 | "freedom": 85, 1812 | "graphGenerosity": 68, 1813 | "generosity": 89, 1814 | "graphGdp": 80, 1815 | "gdp": 77, 1816 | "graphLifeExpectancy": 34, 1817 | "lifeExpectancy": 123, 1818 | "population": 58619080 1819 | }, 1820 | "ALBANIA": { 1821 | "continent": "Europe", 1822 | "country": "Albania", 1823 | "class": "city-Albania", 1824 | "graphRanking": 50, 1825 | "ranking": 107, 1826 | "graphSocialSupport": 24, 1827 | "socialSupport": 133, 1828 | "graphFreedom": 70, 1829 | "freedom": 87, 1830 | "graphGenerosity": 97, 1831 | "generosity": 60, 1832 | "graphGdp": 76, 1833 | "gdp": 81, 1834 | "graphLifeExpectancy": 117, 1835 | "lifeExpectancy": 40, 1836 | "population": 2880657 1837 | }, 1838 | "VENEZUELA": { 1839 | "continent": "South America", 1840 | "country": "Venezuela", 1841 | "class": "city-Venezuela", 1842 | "graphRanking": 49, 1843 | "ranking": 108, 1844 | "graphSocialSupport": 108, 1845 | "socialSupport": 49, 1846 | "graphFreedom": 12, 1847 | "freedom": 145, 1848 | "graphGenerosity": 18, 1849 | "generosity": 139, 1850 | "graphGdp": 79, 1851 | "gdp": 78, 1852 | "graphLifeExpectancy": 86, 1853 | "lifeExpectancy": 71, 1854 | "population": 28504599 1855 | }, 1856 | "CAMBODIA": { 1857 | "continent": "South America", 1858 | "country": "Cambodia", 1859 | "class": "city-Cambodia", 1860 | "graphRanking": 48, 1861 | "ranking": 109, 1862 | "graphSocialSupport": 48, 1863 | "socialSupport": 109, 1864 | "graphFreedom": 155, 1865 | "freedom": 2, 1866 | "graphGenerosity": 96, 1867 | "generosity": 61, 1868 | "graphGdp": 41, 1869 | "gdp": 116, 1870 | "graphLifeExpectancy": 55, 1871 | "lifeExpectancy": 102, 1872 | "population": 16505153 1873 | }, 1874 | "SENEGAL": { 1875 | "continent": "Africa", 1876 | "country": "Senegal", 1877 | "class": "city-Senegal", 1878 | "graphRanking": 46, 1879 | "ranking": 111, 1880 | "graphSocialSupport": 51, 1881 | "socialSupport": 106, 1882 | "graphFreedom": 36, 1883 | "freedom": 121, 1884 | "graphGenerosity": 27, 1885 | "generosity": 130, 1886 | "graphGdp": 31, 1887 | "gdp": 126, 1888 | "graphLifeExpectancy": 48, 1889 | "lifeExpectancy": 109, 1890 | "population": 16331184 1891 | }, 1892 | "NAMIBIA": { 1893 | "continent": "Africa", 1894 | "country": "Namibia", 1895 | "class": "city-Namibia", 1896 | "graphRanking": 44, 1897 | "ranking": 113, 1898 | "graphSocialSupport": 87, 1899 | "socialSupport": 70, 1900 | "graphFreedom": 75, 1901 | "freedom": 82, 1902 | "graphGenerosity": 15, 1903 | "generosity": 142, 1904 | "graphGdp": 68, 1905 | "gdp": 89, 1906 | "graphLifeExpectancy": 35, 1907 | "lifeExpectancy": 122, 1908 | "population": 2498119 1909 | }, 1910 | "NIGER": { 1911 | "continent": "Africa", 1912 | "country": "Niger", 1913 | "class": "city-Niger", 1914 | "graphRanking": 43, 1915 | "ranking": 114, 1916 | "graphSocialSupport": 17, 1917 | "socialSupport": 140, 1918 | "graphFreedom": 46, 1919 | "freedom": 111, 1920 | "graphGenerosity": 22, 1921 | "generosity": 135, 1922 | "graphGdp": 9, 1923 | "gdp": 148, 1924 | "graphLifeExpectancy": 19, 1925 | "lifeExpectancy": 138, 1926 | "population": 23379603 1927 | }, 1928 | "BURKINA_FASO": { 1929 | "continent": "Africa", 1930 | "country": "Burkina Faso", 1931 | "class": "city-Burkina-Faso", 1932 | "graphRanking": 42, 1933 | "ranking": 115, 1934 | "graphSocialSupport": 41, 1935 | "socialSupport": 116, 1936 | "graphFreedom": 30, 1937 | "freedom": 127, 1938 | "graphGenerosity": 32, 1939 | "generosity": 125, 1940 | "graphGdp": 20, 1941 | "gdp": 137, 1942 | "graphLifeExpectancy": 21, 1943 | "lifeExpectancy": 136, 1944 | "population": 20366589 1945 | }, 1946 | "ARMENIA": { 1947 | "continent": "Europe", 1948 | "country": "Armenia", 1949 | "class": "city-Armenia", 1950 | "graphRanking": 41, 1951 | "ranking": 116, 1952 | "graphSocialSupport": 40, 1953 | "socialSupport": 117, 1954 | "graphFreedom": 34, 1955 | "freedom": 123, 1956 | "graphGenerosity": 28, 1957 | "generosity": 129, 1958 | "graphGdp": 66, 1959 | "gdp": 91, 1960 | "graphLifeExpectancy": 93, 1961 | "lifeExpectancy": 64, 1962 | "population": 2958223 1963 | }, 1964 | "IRAN": { 1965 | "continent": "Asia", 1966 | "country": "Iran", 1967 | "class": "city-Iran", 1968 | "graphRanking": 40, 1969 | "ranking": 117, 1970 | "graphSocialSupport": 23, 1971 | "socialSupport": 134, 1972 | "graphFreedom": 40, 1973 | "freedom": 117, 1974 | "graphGenerosity": 129, 1975 | "generosity": 28, 1976 | "graphGdp": 103, 1977 | "gdp": 54, 1978 | "graphLifeExpectancy": 80, 1979 | "lifeExpectancy": 77, 1980 | "population": 82998830 1981 | }, 1982 | "GUINEA": { 1983 | "continent": "Africa", 1984 | "country": "Guinea", 1985 | "class": "city-Guinea", 1986 | "graphRanking": 39, 1987 | "ranking": 118, 1988 | "graphSocialSupport": 21, 1989 | "socialSupport": 136, 1990 | "graphFreedom": 48, 1991 | "freedom": 109, 1992 | "graphGenerosity": 63, 1993 | "generosity": 94, 1994 | "graphGdp": 27, 1995 | "gdp": 130, 1996 | "graphLifeExpectancy": 20, 1997 | "lifeExpectancy": 137, 1998 | "population": 1359691 1999 | }, 2000 | "GEORGIA": { 2001 | "continent": "Europe", 2002 | "country": "Georgia", 2003 | "class": "city-Georgia", 2004 | "graphRanking": 38, 2005 | "ranking": 119, 2006 | "graphSocialSupport": 10, 2007 | "socialSupport": 147, 2008 | "graphFreedom": 53, 2009 | "freedom": 104, 2010 | "graphGenerosity": 4, 2011 | "generosity": 153, 2012 | "graphGdp": 70, 2013 | "gdp": 87, 2014 | "graphLifeExpectancy": 73, 2015 | "lifeExpectancy": 84, 2016 | "population": 3996157 2017 | }, 2018 | "GAMBIA": { 2019 | "continent": "Africa", 2020 | "country": "Gambia", 2021 | "class": "city-Gambia", 2022 | "graphRanking": 37, 2023 | "ranking": 120, 2024 | "graphSocialSupport": 32, 2025 | "socialSupport": 125, 2026 | "graphFreedom": 68, 2027 | "freedom": 89, 2028 | "graphGenerosity": 93, 2029 | "generosity": 64, 2030 | "graphGdp": 18, 2031 | "gdp": 139, 2032 | "graphLifeExpectancy": 27, 2033 | "lifeExpectancy": 130, 2034 | "population": 2353061 2035 | }, 2036 | "KENYA": { 2037 | "continent": "Africa", 2038 | "country": "Kenya", 2039 | "class": "city-Kenya", 2040 | "graphRanking": 36, 2041 | "ranking": 121, 2042 | "graphSocialSupport": 34, 2043 | "socialSupport": 123, 2044 | "graphFreedom": 85, 2045 | "freedom": 72, 2046 | "graphGenerosity": 131, 2047 | "generosity": 26, 2048 | "graphGdp": 35, 2049 | "gdp": 122, 2050 | "graphLifeExpectancy": 51, 2051 | "lifeExpectancy": 106, 2052 | "population": 52668392 2053 | }, 2054 | "MAURITANIA": { 2055 | "continent": "Africa", 2056 | "country": "Mauritania", 2057 | "class": "city-Mauritania", 2058 | "graphRanking": 35, 2059 | "ranking": 122, 2060 | "graphSocialSupport": 58, 2061 | "socialSupport": 99, 2062 | "graphFreedom": 6, 2063 | "freedom": 151, 2064 | "graphGenerosity": 9, 2065 | "generosity": 148, 2066 | "graphGdp": 40, 2067 | "gdp": 117, 2068 | "graphLifeExpectancy": 37, 2069 | "lifeExpectancy": 120, 2070 | "population": 4535364 2071 | }, 2072 | "MOZAMBIQUE": { 2073 | "continent": "Africa", 2074 | "country": "Mozambique", 2075 | "class": "city-Mozambique", 2076 | "graphRanking": 34, 2077 | "ranking": 123, 2078 | "graphSocialSupport": 35, 2079 | "socialSupport": 122, 2080 | "graphFreedom": 111, 2081 | "freedom": 46, 2082 | "graphGenerosity": 36, 2083 | "generosity": 121, 2084 | "graphGdp": 11, 2085 | "gdp": 146, 2086 | "graphLifeExpectancy": 23, 2087 | "lifeExpectancy": 134, 2088 | "population": 30434434 2089 | }, 2090 | "TUNISIA": { 2091 | "continent": "Africa", 2092 | "country": "Tunisia", 2093 | "class": "city-Tunisia", 2094 | "graphRanking": 33, 2095 | "ranking": 124, 2096 | "graphSocialSupport": 36, 2097 | "socialSupport": 121, 2098 | "graphFreedom": 14, 2099 | "freedom": 143, 2100 | "graphGenerosity": 13, 2101 | "generosity": 144, 2102 | "graphGdp": 73, 2103 | "gdp": 84, 2104 | "graphLifeExpectancy": 90, 2105 | "lifeExpectancy": 67, 2106 | "population": 11704503 2107 | }, 2108 | "BANGLADESH": { 2109 | "continent": "Asia", 2110 | "country": "Bangladesh", 2111 | "class": "city-Bangladesh", 2112 | "graphRanking": 32, 2113 | "ranking": 125, 2114 | "graphSocialSupport": 31, 2115 | "socialSupport": 126, 2116 | "graphFreedom": 130, 2117 | "freedom": 27, 2118 | "graphGenerosity": 50, 2119 | "generosity": 107, 2120 | "graphGdp": 38, 2121 | "gdp": 119, 2122 | "graphLifeExpectancy": 67, 2123 | "lifeExpectancy": 90, 2124 | "population": 163177545 2125 | }, 2126 | "IRAQ": { 2127 | "continent": "Asia", 2128 | "country": "Iraq", 2129 | "class": "city-Iraq", 2130 | "graphRanking": 31, 2131 | "ranking": 126, 2132 | "graphSocialSupport": 33, 2133 | "socialSupport": 124, 2134 | "graphFreedom": 27, 2135 | "freedom": 130, 2136 | "graphGenerosity": 84, 2137 | "generosity": 73, 2138 | "graphGdp": 93, 2139 | "gdp": 64, 2140 | "graphLifeExpectancy": 50, 2141 | "lifeExpectancy": 107, 2142 | "population": 39384492 2143 | }, 2144 | "CONGO_KINSHASA": { 2145 | "continent": "Africa", 2146 | "country": "Congo (Kinshasa)", 2147 | "class": "city-Congo-(Kinshasa)", 2148 | "graphRanking": 30, 2149 | "ranking": 127, 2150 | "graphSocialSupport": 50, 2151 | "socialSupport": 107, 2152 | "graphFreedom": 32, 2153 | "freedom": 125, 2154 | "graphGenerosity": 30, 2155 | "generosity": 127, 2156 | "graphGdp": 8, 2157 | "gdp": 149, 2158 | "graphLifeExpectancy": 17, 2159 | "lifeExpectancy": 140, 2160 | "population": 87005619 2161 | }, 2162 | "MALI": { 2163 | "continent": "Africa", 2164 | "country": "Mali", 2165 | "class": "city-Mali", 2166 | "graphRanking": 29, 2167 | "ranking": 128, 2168 | "graphSocialSupport": 45, 2169 | "socialSupport": 112, 2170 | "graphFreedom": 47, 2171 | "freedom": 110, 2172 | "graphGenerosity": 19, 2173 | "generosity": 138, 2174 | "graphGdp": 28, 2175 | "gdp": 129, 2176 | "graphLifeExpectancy": 15, 2177 | "lifeExpectancy": 142, 2178 | "population": 19703707 2179 | }, 2180 | "SIERRA_LEONE": { 2181 | "continent": "Africa", 2182 | "country": "Sierra Leone", 2183 | "class": "city-Sierra-Leone", 2184 | "graphRanking": 28, 2185 | "ranking": 129, 2186 | "graphSocialSupport": 22, 2187 | "socialSupport": 135, 2188 | "graphFreedom": 41, 2189 | "freedom": 116, 2190 | "graphGenerosity": 78, 2191 | "generosity": 79, 2192 | "graphGdp": 12, 2193 | "gdp": 145, 2194 | "graphLifeExpectancy": 11, 2195 | "lifeExpectancy": 146, 2196 | "population": 7826067 2197 | }, 2198 | "SRI_LANKA": { 2199 | "continent": "Asia", 2200 | "country": "Sri Lanka", 2201 | "class": "city-Sri-Lanka", 2202 | "graphRanking": 27, 2203 | "ranking": 130, 2204 | "graphSocialSupport": 77, 2205 | "socialSupport": 80, 2206 | "graphFreedom": 102, 2207 | "freedom": 55, 2208 | "graphGenerosity": 122, 2209 | "generosity": 35, 2210 | "graphGdp": 78, 2211 | "gdp": 79, 2212 | "graphLifeExpectancy": 103, 2213 | "lifeExpectancy": 54, 2214 | "population": 21331317 2215 | }, 2216 | "MYANMAR": { 2217 | "continent": "Asia", 2218 | "country": "Myanmar", 2219 | "class": "city-Myanmar", 2220 | "graphRanking": 26, 2221 | "ranking": 131, 2222 | "graphSocialSupport": 61, 2223 | "socialSupport": 96, 2224 | "graphFreedom": 128, 2225 | "freedom": 29, 2226 | "graphGenerosity": 156, 2227 | "generosity": 1, 2228 | "graphGdp": 51, 2229 | "gdp": 106, 2230 | "graphLifeExpectancy": 47, 2231 | "lifeExpectancy": 110, 2232 | "population": 54074047 2233 | }, 2234 | "CHAD": { 2235 | "continent": "Africa", 2236 | "country": "Chad", 2237 | "class": "city-Chad", 2238 | "graphRanking": 25, 2239 | "ranking": 132, 2240 | "graphSocialSupport": 16, 2241 | "socialSupport": 141, 2242 | "graphFreedom": 15, 2243 | "freedom": 142, 2244 | "graphGenerosity": 51, 2245 | "generosity": 106, 2246 | "graphGdp": 24, 2247 | "gdp": 133, 2248 | "graphLifeExpectancy": 9, 2249 | "lifeExpectancy": 148, 2250 | "population": 15984245 2251 | }, 2252 | "UKRAINE": { 2253 | "continent": "Europe", 2254 | "country": "Ukraine", 2255 | "class": "city-Ukraine", 2256 | "graphRanking": 24, 2257 | "ranking": 133, 2258 | "graphSocialSupport": 101, 2259 | "socialSupport": 56, 2260 | "graphFreedom": 16, 2261 | "freedom": 141, 2262 | "graphGenerosity": 91, 2263 | "generosity": 66, 2264 | "graphGdp": 63, 2265 | "gdp": 94, 2266 | "graphLifeExpectancy": 70, 2267 | "lifeExpectancy": 87, 2268 | "population": 43974157 2269 | }, 2270 | "ETHIOPIA": { 2271 | "continent": "Africa", 2272 | "country": "Ethiopia", 2273 | "class": "city-Ethiopia", 2274 | "graphRanking": 23, 2275 | "ranking": 134, 2276 | "graphSocialSupport": 38, 2277 | "socialSupport": 119, 2278 | "graphFreedom": 51, 2279 | "freedom": 106, 2280 | "graphGenerosity": 58, 2281 | "generosity": 99, 2282 | "graphGdp": 22, 2283 | "gdp": 135, 2284 | "graphLifeExpectancy": 42, 2285 | "lifeExpectancy": 115, 2286 | "population": 112304772 2287 | }, 2288 | "UGANDA": { 2289 | "continent": "Africa", 2290 | "country": "Uganda", 2291 | "class": "city-Uganda", 2292 | "graphRanking": 21, 2293 | "ranking": 136, 2294 | "graphSocialSupport": 43, 2295 | "socialSupport": 114, 2296 | "graphFreedom": 58, 2297 | "freedom": 99, 2298 | "graphGenerosity": 83, 2299 | "generosity": 74, 2300 | "graphGdp": 21, 2301 | "gdp": 136, 2302 | "graphLifeExpectancy": 30, 2303 | "lifeExpectancy": 127, 2304 | "population": 44385669 2305 | }, 2306 | "EGYPT": { 2307 | "continent": "Africa", 2308 | "country": "Egypt", 2309 | "class": "city-Egypt", 2310 | "graphRanking": 20, 2311 | "ranking": 137, 2312 | "graphSocialSupport": 39, 2313 | "socialSupport": 118, 2314 | "graphFreedom": 28, 2315 | "freedom": 129, 2316 | "graphGenerosity": 25, 2317 | "generosity": 132, 2318 | "graphGdp": 72, 2319 | "gdp": 85, 2320 | "graphLifeExpectancy": 56, 2321 | "lifeExpectancy": 101, 2322 | "population": 100543313 2323 | }, 2324 | "ZAMBIA": { 2325 | "continent": "Africa", 2326 | "country": "Zambia", 2327 | "class": "city-Zambia", 2328 | "graphRanking": 19, 2329 | "ranking": 138, 2330 | "graphSocialSupport": 42, 2331 | "socialSupport": 115, 2332 | "graphFreedom": 84, 2333 | "freedom": 73, 2334 | "graphGenerosity": 104, 2335 | "generosity": 53, 2336 | "graphGdp": 42, 2337 | "gdp": 115, 2338 | "graphLifeExpectancy": 26, 2339 | "lifeExpectancy": 131, 2340 | "population": 17901700 2341 | }, 2342 | "TOGO": { 2343 | "continent": "Africa", 2344 | "country": "Togo", 2345 | "class": "city-Togo", 2346 | "graphRanking": 18, 2347 | "ranking": 139, 2348 | "graphSocialSupport": 8, 2349 | "socialSupport": 149, 2350 | "graphFreedom": 37, 2351 | "freedom": 120, 2352 | "graphGenerosity": 26, 2353 | "generosity": 131, 2354 | "graphGdp": 15, 2355 | "gdp": 142, 2356 | "graphLifeExpectancy": 25, 2357 | "lifeExpectancy": 132, 2358 | "population": 8097766 2359 | }, 2360 | "INDIA": { 2361 | "continent": "Asia", 2362 | "country": "India", 2363 | "class": "city-India", 2364 | "graphRanking": 17, 2365 | "ranking": 140, 2366 | "graphSocialSupport": 15, 2367 | "socialSupport": 142, 2368 | "graphFreedom": 116, 2369 | "freedom": 41, 2370 | "graphGenerosity": 92, 2371 | "generosity": 65, 2372 | "graphGdp": 54, 2373 | "gdp": 103, 2374 | "graphLifeExpectancy": 52, 2375 | "lifeExpectancy": 105, 2376 | "population": 1367509713 2377 | }, 2378 | "LIBERIA": { 2379 | "continent": "Africa", 2380 | "country": "Liberia", 2381 | "class": "city-Liberia", 2382 | "graphRanking": 16, 2383 | "ranking": 141, 2384 | "graphSocialSupport": 30, 2385 | "socialSupport": 127, 2386 | "graphFreedom": 63, 2387 | "freedom": 94, 2388 | "graphGenerosity": 47, 2389 | "generosity": 110, 2390 | "graphGdp": 7, 2391 | "gdp": 150, 2392 | "graphLifeExpectancy": 31, 2393 | "lifeExpectancy": 126, 2394 | "population": 4946811 2395 | }, 2396 | "COMOROS": { 2397 | "continent": "Africa", 2398 | "country": "Comoros", 2399 | "class": "city-Comoros", 2400 | "graphRanking": 15, 2401 | "ranking": 142, 2402 | "graphSocialSupport": 14, 2403 | "socialSupport": 143, 2404 | "graphFreedom": 9, 2405 | "freedom": 148, 2406 | "graphGenerosity": 95, 2407 | "generosity": 62, 2408 | "graphGdp": 14, 2409 | "gdp": 143, 2410 | "graphLifeExpectancy": 40, 2411 | "lifeExpectancy": 117, 2412 | "population": 852362 2413 | }, 2414 | "MADAGASCAR": { 2415 | "continent": "Africa", 2416 | "country": "Madagascar", 2417 | "class": "city-Madagascar", 2418 | "graphRanking": 14, 2419 | "ranking": 143, 2420 | "graphSocialSupport": 29, 2421 | "socialSupport": 128, 2422 | "graphFreedom": 11, 2423 | "freedom": 146, 2424 | "graphGenerosity": 21, 2425 | "generosity": 136, 2426 | "graphGdp": 13, 2427 | "gdp": 144, 2428 | "graphLifeExpectancy": 46, 2429 | "lifeExpectancy": 111, 2430 | "population": 27025262 2431 | }, 2432 | "LESOTHO": { 2433 | "continent": "Africa", 2434 | "country": "Lesotho", 2435 | "class": "city-Lesotho", 2436 | "graphRanking": 13, 2437 | "ranking": 144, 2438 | "graphSocialSupport": 59, 2439 | "socialSupport": 98, 2440 | "graphFreedom": 60, 2441 | "freedom": 97, 2442 | "graphGenerosity": 6, 2443 | "generosity": 151, 2444 | "graphGdp": 33, 2445 | "gdp": 124, 2446 | "graphLifeExpectancy": 8, 2447 | "lifeExpectancy": 149, 2448 | "population": 2126600 2449 | }, 2450 | "BURUNDI": { 2451 | "continent": "Africa", 2452 | "country": "Burundi", 2453 | "class": "city-Burundi", 2454 | "graphRanking": 12, 2455 | "ranking": 145, 2456 | "graphSocialSupport": 5, 2457 | "socialSupport": 152, 2458 | "graphFreedom": 22, 2459 | "freedom": 135, 2460 | "graphGenerosity": 8, 2461 | "generosity": 149, 2462 | "graphGdp": 6, 2463 | "gdp": 151, 2464 | "graphLifeExpectancy": 22, 2465 | "lifeExpectancy": 135, 2466 | "population": 11558456 2467 | }, 2468 | "ZIMBABWE": { 2469 | "continent": "Africa", 2470 | "country": "Zimbabwe", 2471 | "class": "city-Zimbabwe", 2472 | "graphRanking": 11, 2473 | "ranking": 146, 2474 | "graphSocialSupport": 47, 2475 | "socialSupport": 110, 2476 | "graphFreedom": 61, 2477 | "freedom": 96, 2478 | "graphGenerosity": 16, 2479 | "generosity": 141, 2480 | "graphGdp": 26, 2481 | "gdp": 131, 2482 | "graphLifeExpectancy": 28, 2483 | "lifeExpectancy": 129, 2484 | "population": 14662721 2485 | }, 2486 | "HAITI": { 2487 | "continent": "South America", 2488 | "country": "Haiti", 2489 | "class": "city-Haiti", 2490 | "graphRanking": 10, 2491 | "ranking": 147, 2492 | "graphSocialSupport": 11, 2493 | "socialSupport": 146, 2494 | "graphFreedom": 5, 2495 | "freedom": 152, 2496 | "graphGenerosity": 137, 2497 | "generosity": 20, 2498 | "graphGdp": 19, 2499 | "gdp": 138, 2500 | "graphLifeExpectancy": 32, 2501 | "lifeExpectancy": 125, 2502 | "population": 11274222 2503 | }, 2504 | "BOTSWANA": { 2505 | "continent": "Africa", 2506 | "country": "Botswana", 2507 | "class": "city-Botswana", 2508 | "graphRanking": 9, 2509 | "ranking": 148, 2510 | "graphSocialSupport": 52, 2511 | "socialSupport": 105, 2512 | "graphFreedom": 97, 2513 | "freedom": 60, 2514 | "graphGenerosity": 7, 2515 | "generosity": 150, 2516 | "graphGdp": 91, 2517 | "gdp": 66, 2518 | "graphLifeExpectancy": 44, 2519 | "lifeExpectancy": 113, 2520 | "population": 2307316 2521 | }, 2522 | "MALAWI": { 2523 | "continent": "Africa", 2524 | "country": "Malawi", 2525 | "class": "city-Malawi", 2526 | "graphRanking": 7, 2527 | "ranking": 150, 2528 | "graphSocialSupport": 7, 2529 | "socialSupport": 150, 2530 | "graphFreedom": 92, 2531 | "freedom": 65, 2532 | "graphGenerosity": 48, 2533 | "generosity": 109, 2534 | "graphGdp": 10, 2535 | "gdp": 147, 2536 | "graphLifeExpectancy": 38, 2537 | "lifeExpectancy": 119, 2538 | "population": 18667625 2539 | }, 2540 | "YEMEN": { 2541 | "continent": "Asia", 2542 | "country": "Yemen", 2543 | "class": "city-Yemen", 2544 | "graphRanking": 6, 2545 | "ranking": 151, 2546 | "graphSocialSupport": 57, 2547 | "socialSupport": 100, 2548 | "graphFreedom": 10, 2549 | "freedom": 147, 2550 | "graphGenerosity": 2, 2551 | "generosity": 155, 2552 | "graphGdp": 16, 2553 | "gdp": 141, 2554 | "graphLifeExpectancy": 33, 2555 | "lifeExpectancy": 124, 2556 | "population": 29214637 2557 | }, 2558 | "RWANDA": { 2559 | "continent": "Africa", 2560 | "country": "Rwanda", 2561 | "class": "city-Rwanda", 2562 | "graphRanking": 5, 2563 | "ranking": 152, 2564 | "graphSocialSupport": 13, 2565 | "socialSupport": 144, 2566 | "graphFreedom": 136, 2567 | "freedom": 21, 2568 | "graphGenerosity": 67, 2569 | "generosity": 90, 2570 | "graphGdp": 25, 2571 | "gdp": 132, 2572 | "graphLifeExpectancy": 54, 2573 | "lifeExpectancy": 103, 2574 | "population": 12652164 2575 | }, 2576 | "TANZANIA": { 2577 | "continent": "Africa", 2578 | "country": "Tanzania", 2579 | "class": "city-Tanzania", 2580 | "graphRanking": 4, 2581 | "ranking": 153, 2582 | "graphSocialSupport": 26, 2583 | "socialSupport": 131, 2584 | "graphFreedom": 79, 2585 | "freedom": 78, 2586 | "graphGenerosity": 108, 2587 | "generosity": 49, 2588 | "graphGdp": 32, 2589 | "gdp": 125, 2590 | "graphLifeExpectancy": 39, 2591 | "lifeExpectancy": 118, 2592 | "population": 58139264 2593 | }, 2594 | "AFGHANISTAN": { 2595 | "continent": "Asia", 2596 | "country": "Afghanistan", 2597 | "class": "city-Afghanistan", 2598 | "graphRanking": 3, 2599 | "ranking": 154, 2600 | "graphSocialSupport": 6, 2601 | "socialSupport": 151, 2602 | "graphFreedom": 2, 2603 | "freedom": 155, 2604 | "graphGenerosity": 20, 2605 | "generosity": 137, 2606 | "graphGdp": 23, 2607 | "gdp": 134, 2608 | "graphLifeExpectancy": 18, 2609 | "lifeExpectancy": 139, 2610 | "population": 38113576 2611 | }, 2612 | "CENTRAL_AFRICAN_REPUBLIC": { 2613 | "continent": "Africa", 2614 | "country": "Central African Republic", 2615 | "class": "city-Central-African-Republic", 2616 | "graphRanking": 2, 2617 | "ranking": 155, 2618 | "graphSocialSupport": 2, 2619 | "socialSupport": 155, 2620 | "graphFreedom": 24, 2621 | "freedom": 133, 2622 | "graphGenerosity": 44, 2623 | "generosity": 113, 2624 | "graphGdp": 5, 2625 | "gdp": 152, 2626 | "graphLifeExpectancy": 7, 2627 | "lifeExpectancy": 150, 2628 | "population": 4751091 2629 | }, 2630 | "SOUTH_SUDAN": { 2631 | "continent": "Africa", 2632 | "country": "South Sudan", 2633 | "class": "city-South-Sudan", 2634 | "graphRanking": 1, 2635 | "ranking": 156, 2636 | "graphSocialSupport": 9, 2637 | "socialSupport": 148, 2638 | "graphFreedom": 3, 2639 | "freedom": 154, 2640 | "graphGenerosity": 72, 2641 | "generosity": 85, 2642 | "graphGdp": 17, 2643 | "gdp": 140, 2644 | "graphLifeExpectancy": 14, 2645 | "lifeExpectancy": 143, 2646 | "population": 11072187 2647 | } 2648 | } -------------------------------------------------------------------------------- /dist/main.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | /******/ 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ } 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {} 17 | /******/ }; 18 | /******/ 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | /******/ 22 | /******/ // Flag the module as loaded 23 | /******/ module.l = true; 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | /******/ 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | /******/ 36 | /******/ // define getter function for harmony exports 37 | /******/ __webpack_require__.d = function(exports, name, getter) { 38 | /******/ if(!__webpack_require__.o(exports, name)) { 39 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40 | /******/ } 41 | /******/ }; 42 | /******/ 43 | /******/ // define __esModule on exports 44 | /******/ __webpack_require__.r = function(exports) { 45 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47 | /******/ } 48 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 49 | /******/ }; 50 | /******/ 51 | /******/ // create a fake namespace object 52 | /******/ // mode & 1: value is a module id, require it 53 | /******/ // mode & 2: merge all properties of value into the ns 54 | /******/ // mode & 4: return value when already ns object 55 | /******/ // mode & 8|1: behave like require 56 | /******/ __webpack_require__.t = function(value, mode) { 57 | /******/ if(mode & 1) value = __webpack_require__(value); 58 | /******/ if(mode & 8) return value; 59 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60 | /******/ var ns = Object.create(null); 61 | /******/ __webpack_require__.r(ns); 62 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64 | /******/ return ns; 65 | /******/ }; 66 | /******/ 67 | /******/ // getDefaultExport function for compatibility with non-harmony modules 68 | /******/ __webpack_require__.n = function(module) { 69 | /******/ var getter = module && module.__esModule ? 70 | /******/ function getDefault() { return module['default']; } : 71 | /******/ function getModuleExports() { return module; }; 72 | /******/ __webpack_require__.d(getter, 'a', getter); 73 | /******/ return getter; 74 | /******/ }; 75 | /******/ 76 | /******/ // Object.prototype.hasOwnProperty.call 77 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78 | /******/ 79 | /******/ // __webpack_public_path__ 80 | /******/ __webpack_require__.p = ""; 81 | /******/ 82 | /******/ 83 | /******/ // Load entry module and return exports 84 | /******/ return __webpack_require__(__webpack_require__.s = "./src/index.js"); 85 | /******/ }) 86 | /************************************************************************/ 87 | /******/ ({ 88 | 89 | /***/ "./src/chart.js": 90 | /*!**********************!*\ 91 | !*** ./src/chart.js ***! 92 | \**********************/ 93 | /*! exports provided: default */ 94 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 95 | 96 | "use strict"; 97 | __webpack_require__.r(__webpack_exports__); 98 | /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./constants */ "./src/constants.js"); 99 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 100 | 101 | 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); } } 102 | 103 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 104 | 105 | 106 | 107 | var Chart = 108 | /*#__PURE__*/ 109 | function () { 110 | function Chart(selector, options) { 111 | _classCallCheck(this, Chart); 112 | 113 | this.setChart(selector, options); 114 | this.setLabels(); 115 | } 116 | 117 | _createClass(Chart, [{ 118 | key: "setChart", 119 | value: function setChart(selector) { 120 | var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { 121 | topOffset: 0, 122 | leftOffset: 0 123 | }; 124 | var svg = d3.select(selector).attr("height", _constants__WEBPACK_IMPORTED_MODULE_0__["HEIGHT"] + _constants__WEBPACK_IMPORTED_MODULE_0__["MARGINS"] * 2).attr("width", _constants__WEBPACK_IMPORTED_MODULE_0__["WIDTH"] + _constants__WEBPACK_IMPORTED_MODULE_0__["MARGINS"] * 2); 125 | this.chart = svg.append("g").attr("position", "relative").attr("class", "main__svg").attr("transform", "translate(".concat(_constants__WEBPACK_IMPORTED_MODULE_0__["MARGINS"] + options.leftOffset, ", ").concat(_constants__WEBPACK_IMPORTED_MODULE_0__["MARGINS"] / 2 + options.topOffset, ")")); 126 | } 127 | }, { 128 | key: "setData", 129 | value: function setData(data) { 130 | this.data = data; 131 | } 132 | }, { 133 | key: "xAxis", 134 | value: function xAxis() { 135 | var ticks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 20; 136 | var tickFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; 137 | this.xScale = d3.scaleLinear().range([0, _constants__WEBPACK_IMPORTED_MODULE_0__["WIDTH"]]); // .domain([0, 1]); 138 | 139 | var xAxisCall = d3.axisBottom(this.xScale).ticks(ticks).tickFormat(d3.format(".0%")); 140 | this.chart.append("g").attr("transform", "translate(0, ".concat(_constants__WEBPACK_IMPORTED_MODULE_0__["HEIGHT"], ")")).call(xAxisCall); 141 | } 142 | }, { 143 | key: "yAxis", 144 | value: function yAxis(domain, yScale) { 145 | var ticks = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 5; 146 | var tickFormat = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {}; 147 | 148 | if (yScale === "scaleBand") { 149 | this.yScale = d3[yScale]().domain(domain).range([0, _constants__WEBPACK_IMPORTED_MODULE_0__["HEIGHT"]]).padding(0.8); 150 | } else { 151 | this.yScale = d3[yScale]().domain(domain).range([0, _constants__WEBPACK_IMPORTED_MODULE_0__["HEIGHT"]]); 152 | } 153 | 154 | this.chart.append("g").call(d3.axisLeft(this.yScale).ticks(ticks).tickFormat(tickFormat())); 155 | } 156 | }, { 157 | key: "setLabels", 158 | value: function setLabels() { 159 | // Labels 160 | var xLabel = this.chart.append("g").append("text").attr("class", "x-axis-label").attr("y", _constants__WEBPACK_IMPORTED_MODULE_0__["HEIGHT"] + 50).attr("x", _constants__WEBPACK_IMPORTED_MODULE_0__["WIDTH"] / 2).attr("font-size", "18px").attr("font-weight", "600").attr("text-anchor", "middle").text("GDP Per Capita ($)"); 161 | var yLabel = this.chart.append("g").attr("class", "yAxisGroup").append("text").attr("transform", "rotate(-90)") // .attr("position", 'relative') 162 | .attr("x", -(_constants__WEBPACK_IMPORTED_MODULE_0__["HEIGHT"] / 2)).attr("y", -50).attr("font-size", "18px").attr("font-weight", "600").attr("text-anchor", "middle").text("Happiness Index (%)"); 163 | } 164 | }]); 165 | 166 | return Chart; 167 | }(); 168 | 169 | /* harmony default export */ __webpack_exports__["default"] = (Chart); 170 | 171 | /***/ }), 172 | 173 | /***/ "./src/constants.js": 174 | /*!**************************!*\ 175 | !*** ./src/constants.js ***! 176 | \**************************/ 177 | /*! exports provided: ANIMATION_DURATION, ANIMATION_DELAY, ANIMATION_EASING, WIDTH, HEIGHT, MARGINS */ 178 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 179 | 180 | "use strict"; 181 | __webpack_require__.r(__webpack_exports__); 182 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ANIMATION_DURATION", function() { return ANIMATION_DURATION; }); 183 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ANIMATION_DELAY", function() { return ANIMATION_DELAY; }); 184 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ANIMATION_EASING", function() { return ANIMATION_EASING; }); 185 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WIDTH", function() { return WIDTH; }); 186 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HEIGHT", function() { return HEIGHT; }); 187 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MARGINS", function() { return MARGINS; }); 188 | var ANIMATION_DURATION = 1000; 189 | var ANIMATION_DELAY = 0; 190 | var ANIMATION_EASING = d3.easePoly; 191 | var WIDTH = window.innerWidth - 250; 192 | var HEIGHT = window.innerHeight - 300; 193 | var MARGINS = 100; 194 | 195 | /***/ }), 196 | 197 | /***/ "./src/index.js": 198 | /*!**********************!*\ 199 | !*** ./src/index.js ***! 200 | \**********************/ 201 | /*! no exports provided */ 202 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 203 | 204 | "use strict"; 205 | __webpack_require__.r(__webpack_exports__); 206 | /* harmony import */ var _world_graph__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./world_graph */ "./src/world_graph.js"); 207 | 208 | var worldGraph; 209 | document.addEventListener("DOMContentLoaded", function () { 210 | // initialize data visualzation 211 | worldGraph = new _world_graph__WEBPACK_IMPORTED_MODULE_0__["default"]("svg.graph"); // button group event listener 212 | 213 | var btnGroup = document.querySelector(".btn-group"); 214 | btnGroup.addEventListener("mousedown", function (e) { 215 | e.preventDefault(); 216 | var currentBtn = e.target; 217 | var currentBtnType = currentBtn.classList[1]; 218 | var currentBtnClass; 219 | 220 | if (currentBtnType === "header-graph__btn") { 221 | currentBtnClass = currentBtn.classList[0].split("-")[1]; 222 | } 223 | 224 | if (currentBtnType === "header-graph__btn") { 225 | worldGraph.updateData(currentBtnClass); 226 | var allBtns = btnGroup.querySelectorAll("a"); 227 | allBtns.forEach(function (btn) { 228 | btn.classList.remove("active"); 229 | }); 230 | currentBtn.classList.add("active"); 231 | } 232 | }); // modal actions 233 | 234 | var modalBg = document.querySelector('.modal-bg'); 235 | modalBg.addEventListener('click', handleModalBgClick); 236 | }); // modal close 237 | 238 | function handleModalBgClick(e) { 239 | e.stopPropagation(); 240 | var modalBg = document.querySelector(".modal-bg"); 241 | var modal = document.querySelector('.modal'); 242 | 243 | if (e.target.classList[0] === "modal-bg" || e.target.classList[0] === "modal-close__btn-single") { 244 | modal.setAttribute("style", "opacity: 0; visibility: hidden"); 245 | modalBg.setAttribute("style", "opacity: 0; visibility: hidden"); 246 | } 247 | } 248 | 249 | /***/ }), 250 | 251 | /***/ "./src/world_graph.js": 252 | /*!****************************!*\ 253 | !*** ./src/world_graph.js ***! 254 | \****************************/ 255 | /*! exports provided: default */ 256 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 257 | 258 | "use strict"; 259 | __webpack_require__.r(__webpack_exports__); 260 | /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./constants */ "./src/constants.js"); 261 | /* harmony import */ var _chart__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./chart */ "./src/chart.js"); 262 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 263 | 264 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 265 | 266 | 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); } } 267 | 268 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 269 | 270 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 271 | 272 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 273 | 274 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 275 | 276 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 277 | 278 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 279 | 280 | 281 | 282 | 283 | var WorldGraph = 284 | /*#__PURE__*/ 285 | function (_Chart) { 286 | _inherits(WorldGraph, _Chart); 287 | 288 | function WorldGraph(selector) { 289 | var _this; 290 | 291 | _classCallCheck(this, WorldGraph); 292 | 293 | _this = _possibleConstructorReturn(this, _getPrototypeOf(WorldGraph).call(this, selector)); 294 | _this.svg = d3.select(selector); 295 | 296 | _this.xAxis(); 297 | 298 | _this.yAxis([1, 0], "scaleLinear", 20, function () { 299 | return d3.format(".0%"); 300 | }); 301 | 302 | _this.getData("graphGdp"); 303 | 304 | return _this; 305 | } 306 | 307 | _createClass(WorldGraph, [{ 308 | key: "getData", 309 | value: function getData(metric) { 310 | var that = this; 311 | d3.json("dist/data/countries.json").then(function (data) { 312 | that.setData(data); 313 | that.circles(metric); 314 | }); 315 | } 316 | }, { 317 | key: "formatOrdinal", 318 | value: function formatOrdinal(num) { 319 | var _int = parseInt(num), 320 | digits = [_int % 10, _int % 100], 321 | ordinals = ['st', 'nd', 'rd', 'th'], 322 | oPattern = [1, 2, 3, 4], 323 | tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; 324 | 325 | return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? _int + ordinals[digits[0] - 1] : _int + ordinals[3]; 326 | } 327 | }, { 328 | key: "circles", 329 | value: function circles(metric) { 330 | var _this2 = this; 331 | 332 | //////////////////////// 333 | // tooltip 334 | //////////////////////// 335 | var tooltip = d3.select("body").append("div").style("visibility", "hidden").attr("class", "tooltip").style("background-color", "black").style("border-radius", "5px").style("padding", "10px").style("color", "white").style("z-index", "999999999").style("position", "absolute").style("display", "block"); 336 | var that = this; 337 | 338 | var showTooltip = function showTooltip(d) { 339 | tooltip.transition().duration(200); 340 | tooltip.style("visibility", "visible").html("\n Country: ".concat(d.country, " (").concat(d.continent, ")
\n Happiness Ranking: ").concat(that.formatOrdinal(d.ranking), "\n")).style("top", d3.event.clientY - 100 + "px").style("left", d3.event.clientX - 160 + "px"); 341 | }; 342 | 343 | var moveTooltip = function moveTooltip(d) { 344 | showTooltip(d); 345 | tooltip.style("top", d3.event.clientY - 100 + "px").style("left", d3.event.clientX - 160 + "px"); 346 | }; 347 | 348 | var hideTooltip = function hideTooltip(d) { 349 | tooltip.transition().duration(200).style("visibility", "hidden"); 350 | }; //////////////////////// 351 | // chart rendering 352 | //////////////////////// 353 | 354 | 355 | this.chart.selectAll("circle").data(Object.values(this.data)).enter().append("circle").attr("class", function (d) { 356 | return "country ".concat(d["class"], " continent-").concat(d.continent.split(" ").join("-"), " country-bubble"); 357 | }).attr("fill", function (d) { 358 | if (d.continent === "Africa") { 359 | return "#7cbd1e"; 360 | } else if (d.continent === "Asia") { 361 | return "#ff1f5a"; 362 | } else if (d.continent === "North America") { 363 | return "#303481"; 364 | } else if (d.continent === "South America") { 365 | return "#ff5b44"; 366 | } else if (d.continent === "Europe") { 367 | return "#2fc5cc"; 368 | } else { 369 | return "red"; 370 | } 371 | }).attr("opacity", ".7").attr("stroke", "#CDCDCD").attr("stroke-width", "2px").attr("cx", function (d) { 372 | return _this2.xScale(d[metric] / 156) + 25; 373 | }).on("mouseover", showTooltip).on("mousemove", moveTooltip).on("mouseleave", hideTooltip).transition().delay(function (d, i) { 374 | return i * _constants__WEBPACK_IMPORTED_MODULE_0__["ANIMATION_DELAY"]; 375 | }).duration(_constants__WEBPACK_IMPORTED_MODULE_0__["ANIMATION_DURATION"]).ease(_constants__WEBPACK_IMPORTED_MODULE_0__["ANIMATION_EASING"]).attr("r", function (d) { 376 | if (d.population > 800000000) { 377 | return d.population / 25000000; 378 | } else if (d.population > 50000000) { 379 | return d.population / 10000000; 380 | } else if (d.population > 1000000) { 381 | return d.population / 1500000; 382 | } else { 383 | return d.population / 100000; 384 | } 385 | }).attr("cy", function (d) { 386 | return _this2.yScale(d.graphRanking / 156); 387 | }); //////////////////////// 388 | // legend 389 | //////////////////////// 390 | 391 | var continents = { 392 | AFRICA: { 393 | continent: "Africa" 394 | }, 395 | ASIA: { 396 | continent: "Asia" 397 | }, 398 | NORTH_AMERICA: { 399 | continent: "North America" 400 | }, 401 | SOUTH_AMERICA: { 402 | continent: "South America" 403 | }, 404 | EUROPE: { 405 | continent: "Europe" 406 | } 407 | }; 408 | 409 | var continentFocusOn = function continentFocusOn(continentName) { 410 | _this2.chart.selectAll("circle:not(.continent-".concat(continentName.split(" ").join("-"), ")")).attr("opacity", "0.05"); 411 | }; 412 | 413 | var continentFocusOff = function continentFocusOff(continentName) { 414 | _this2.chart.selectAll("circle:not(.continent-".concat(continentName.split(" ").join("-"), ")")).attr("opacity", "0.7"); 415 | }; 416 | 417 | var legend = this.chart.selectAll(".legend").data(Object.values(continents)).enter().append("g").attr("class", "legend").attr("position", "absolute").attr("transform", "translate(".concat(_constants__WEBPACK_IMPORTED_MODULE_0__["WIDTH"] - 130, ", ").concat(_constants__WEBPACK_IMPORTED_MODULE_0__["HEIGHT"] - 120, ")")); 418 | legend.append("rect").attr("x", 0).attr("y", function (d, i) { 419 | return 20 * i; 420 | }).attr("width", 20).attr("height", 20).style("fill", function (d) { 421 | if (d.continent === "Africa") { 422 | return "#7cbd1e"; 423 | } else if (d.continent === "Asia") { 424 | return "#ff1f5a"; 425 | } else if (d.continent === "North America") { 426 | return "#303481"; 427 | } else if (d.continent === "South America") { 428 | return "#ff5b44"; 429 | } else if (d.continent === "Europe") { 430 | return "#2fc5cc"; 431 | } else { 432 | return "red"; 433 | } 434 | }).on("mouseover", function (d) { 435 | return continentFocusOn(d.continent); 436 | }).on("mouseleave", function (d) { 437 | return continentFocusOff(d.continent); 438 | }); 439 | legend.append("text").attr("x", 25).attr("text-anchor", "start").attr("dy", "1em").attr("class", function (d) { 440 | return "legend-".concat(d.continent.split(" ").join("-")); 441 | }).attr("y", function (d, i) { 442 | return 20 * i; 443 | }).text(function (d) { 444 | return d.continent; 445 | }).attr("font-size", "12px").on("mouseover", function (d) { 446 | return continentFocusOn(d.continent); 447 | }).on("mouseleave", function (d) { 448 | return continentFocusOff(d.continent); 449 | }); 450 | legend.append("text").attr("x", 31).attr("dy", "-.2em").attr("y", -10).text("Continent").attr("font-size", "17px").style("text-align", "left"); 451 | } 452 | }, { 453 | key: "updateData", 454 | value: function updateData(dataType) { 455 | var _this3 = this; 456 | 457 | d3.json("dist/data/countries.json").then(function (data) { 458 | _this3.chart.selectAll(".country-bubble").transition().duration(500).ease(_constants__WEBPACK_IMPORTED_MODULE_0__["ANIMATION_EASING"]).attr("cx", function (d) { 459 | return _this3.xScale(d[dataType] / 156) + 25; 460 | }); 461 | 462 | _this3.updateAxisLabel(dataType); 463 | }); 464 | } 465 | }, { 466 | key: "updateAxisLabel", 467 | value: function updateAxisLabel(type) { 468 | // xLabel 469 | var label; 470 | 471 | if (type === 'graphSocialSupport') { 472 | label = 'Social Support'; 473 | } else if (type === "graphFreedom") { 474 | label = 'Freedom'; 475 | } else if (type === "graphGenerosity") { 476 | label = 'Generosity'; 477 | } else if (type === "graphLifeExpectancy") { 478 | label = 'Life Expectancy'; 479 | } else if (type === 'graphGdp') { 480 | label = 'GDP Per Capita ($)'; 481 | } 482 | 483 | this.chart.select(".x-axis-label").text("".concat(label)); 484 | } 485 | }]); 486 | 487 | return WorldGraph; 488 | }(_chart__WEBPACK_IMPORTED_MODULE_1__["default"]); 489 | 490 | /* harmony default export */ __webpack_exports__["default"] = (WorldGraph); 491 | 492 | /***/ }) 493 | 494 | /******/ }); 495 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NoYXJ0LmpzIiwid2VicGFjazovLy8uL3NyYy9jb25zdGFudHMuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2luZGV4LmpzIiwid2VicGFjazovLy8uL3NyYy93b3JsZF9ncmFwaC5qcyJdLCJuYW1lcyI6WyJDaGFydCIsInNlbGVjdG9yIiwib3B0aW9ucyIsInNldENoYXJ0Iiwic2V0TGFiZWxzIiwidG9wT2Zmc2V0IiwibGVmdE9mZnNldCIsInN2ZyIsImQzIiwic2VsZWN0IiwiYXR0ciIsIkhFSUdIVCIsIk1BUkdJTlMiLCJXSURUSCIsImNoYXJ0IiwiYXBwZW5kIiwiZGF0YSIsInRpY2tzIiwidGlja0Zvcm1hdCIsInhTY2FsZSIsInNjYWxlTGluZWFyIiwicmFuZ2UiLCJ4QXhpc0NhbGwiLCJheGlzQm90dG9tIiwiZm9ybWF0IiwiY2FsbCIsImRvbWFpbiIsInlTY2FsZSIsInBhZGRpbmciLCJheGlzTGVmdCIsInhMYWJlbCIsInRleHQiLCJ5TGFiZWwiLCJBTklNQVRJT05fRFVSQVRJT04iLCJBTklNQVRJT05fREVMQVkiLCJBTklNQVRJT05fRUFTSU5HIiwiZWFzZVBvbHkiLCJ3aW5kb3ciLCJpbm5lcldpZHRoIiwiaW5uZXJIZWlnaHQiLCJ3b3JsZEdyYXBoIiwiZG9jdW1lbnQiLCJhZGRFdmVudExpc3RlbmVyIiwiV29ybGRHcmFwaCIsImJ0bkdyb3VwIiwicXVlcnlTZWxlY3RvciIsImUiLCJwcmV2ZW50RGVmYXVsdCIsImN1cnJlbnRCdG4iLCJ0YXJnZXQiLCJjdXJyZW50QnRuVHlwZSIsImNsYXNzTGlzdCIsImN1cnJlbnRCdG5DbGFzcyIsInNwbGl0IiwidXBkYXRlRGF0YSIsImFsbEJ0bnMiLCJxdWVyeVNlbGVjdG9yQWxsIiwiZm9yRWFjaCIsImJ0biIsInJlbW92ZSIsImFkZCIsIm1vZGFsQmciLCJoYW5kbGVNb2RhbEJnQ2xpY2siLCJzdG9wUHJvcGFnYXRpb24iLCJtb2RhbCIsInNldEF0dHJpYnV0ZSIsInhBeGlzIiwieUF4aXMiLCJnZXREYXRhIiwibWV0cmljIiwidGhhdCIsImpzb24iLCJ0aGVuIiwic2V0RGF0YSIsImNpcmNsZXMiLCJudW0iLCJpbnQiLCJwYXJzZUludCIsImRpZ2l0cyIsIm9yZGluYWxzIiwib1BhdHRlcm4iLCJ0UGF0dGVybiIsImluY2x1ZGVzIiwidG9vbHRpcCIsInN0eWxlIiwic2hvd1Rvb2x0aXAiLCJkIiwidHJhbnNpdGlvbiIsImR1cmF0aW9uIiwiaHRtbCIsImNvdW50cnkiLCJjb250aW5lbnQiLCJmb3JtYXRPcmRpbmFsIiwicmFua2luZyIsImV2ZW50IiwiY2xpZW50WSIsImNsaWVudFgiLCJtb3ZlVG9vbHRpcCIsImhpZGVUb29sdGlwIiwic2VsZWN0QWxsIiwiT2JqZWN0IiwidmFsdWVzIiwiZW50ZXIiLCJqb2luIiwib24iLCJkZWxheSIsImkiLCJlYXNlIiwicG9wdWxhdGlvbiIsImdyYXBoUmFua2luZyIsImNvbnRpbmVudHMiLCJBRlJJQ0EiLCJBU0lBIiwiTk9SVEhfQU1FUklDQSIsIlNPVVRIX0FNRVJJQ0EiLCJFVVJPUEUiLCJjb250aW5lbnRGb2N1c09uIiwiY29udGluZW50TmFtZSIsImNvbnRpbmVudEZvY3VzT2ZmIiwibGVnZW5kIiwiZGF0YVR5cGUiLCJ1cGRhdGVBeGlzTGFiZWwiLCJ0eXBlIiwibGFiZWwiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtEQUEwQyxnQ0FBZ0M7QUFDMUU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnRUFBd0Qsa0JBQWtCO0FBQzFFO0FBQ0EseURBQWlELGNBQWM7QUFDL0Q7O0FBRUE7QUFDQTtBQUNB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QUFSO0FBQ0QsT0FGTSxNQUVBLElBQUlELElBQUksS0FBSyxpQkFBYixFQUFnQztBQUNyQ0MsYUFBSyxHQUFHLFlBQVI7QUFDRCxPQUZNLE1BRUEsSUFBSUQsSUFBSSxLQUFLLHFCQUFiLEVBQW9DO0FBQ3pDQyxhQUFLLEdBQUcsaUJBQVI7QUFDRCxPQUZNLE1BRUEsSUFBSUQsSUFBSSxLQUFLLFVBQWIsRUFBeUI7QUFDOUJDLGFBQUssR0FBRyxvQkFBUjtBQUNEOztBQUNELFdBQUs3RyxLQUFMLENBQVdMLE1BQVgsQ0FBa0IsZUFBbEIsRUFBbUNzQixJQUFuQyxXQUEyQzRGLEtBQTNDO0FBQ0Q7Ozs7RUExUHNCM0gsOEM7O0FBNlBWMkMseUVBQWYsRSIsImZpbGUiOiJtYWluLmpzIiwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZ2V0dGVyIH0pO1xuIFx0XHR9XG4gXHR9O1xuXG4gXHQvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XG4gXHRcdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuIFx0XHR9XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG4gXHR9O1xuXG4gXHQvLyBjcmVhdGUgYSBmYWtlIG5hbWVzcGFjZSBvYmplY3RcbiBcdC8vIG1vZGUgJiAxOiB2YWx1ZSBpcyBhIG1vZHVsZSBpZCwgcmVxdWlyZSBpdFxuIFx0Ly8gbW9kZSAmIDI6IG1lcmdlIGFsbCBwcm9wZXJ0aWVzIG9mIHZhbHVlIGludG8gdGhlIG5zXG4gXHQvLyBtb2RlICYgNDogcmV0dXJuIHZhbHVlIHdoZW4gYWxyZWFkeSBucyBvYmplY3RcbiBcdC8vIG1vZGUgJiA4fDE6IGJlaGF2ZSBsaWtlIHJlcXVpcmVcbiBcdF9fd2VicGFja19yZXF1aXJlX18udCA9IGZ1bmN0aW9uKHZhbHVlLCBtb2RlKSB7XG4gXHRcdGlmKG1vZGUgJiAxKSB2YWx1ZSA9IF9fd2VicGFja19yZXF1aXJlX18odmFsdWUpO1xuIFx0XHRpZihtb2RlICYgOCkgcmV0dXJuIHZhbHVlO1xuIFx0XHRpZigobW9kZSAmIDQpICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgJiYgdmFsdWUuX19lc01vZHVsZSkgcmV0dXJuIHZhbHVlO1xuIFx0XHR2YXIgbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIobnMpO1xuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobnMsICdkZWZhdWx0JywgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdmFsdWUgfSk7XG4gXHRcdGlmKG1vZGUgJiAyICYmIHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgZm9yKHZhciBrZXkgaW4gdmFsdWUpIF9fd2VicGFja19yZXF1aXJlX18uZChucywga2V5LCBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHZhbHVlW2tleV07IH0uYmluZChudWxsLCBrZXkpKTtcbiBcdFx0cmV0dXJuIG5zO1xuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IFwiLi9zcmMvaW5kZXguanNcIik7XG4iLCJpbXBvcnQge1xuICBIRUlHSFQsXG4gIE1BUkdJTlMsXG4gIFdJRFRILFxuICBBTklNQVRJT05fRFVSQVRJT04sXG4gIEFOSU1BVElPTl9ERUxBWSxcbiAgQU5JTUFUSU9OX0VBU0lOR1xufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuY2xhc3MgQ2hhcnQge1xuICBjb25zdHJ1Y3RvcihzZWxlY3Rvciwgb3B0aW9ucykge1xuICAgIHRoaXMuc2V0Q2hhcnQoc2VsZWN0b3IsIG9wdGlvbnMpO1xuICAgIHRoaXMuc2V0TGFiZWxzKCk7XG4gIH1cblxuICBzZXRDaGFydChzZWxlY3Rvciwgb3B0aW9ucyA9IHsgdG9wT2Zmc2V0OiAwLCBsZWZ0T2Zmc2V0OiAwIH0pIHtcbiAgICBjb25zdCBzdmcgPSBkM1xuICAgICAgLnNlbGVjdChzZWxlY3RvcilcbiAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIEhFSUdIVCArIE1BUkdJTlMgKiAyKVxuICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBXSURUSCArIE1BUkdJTlMgKiAyKTtcbiAgICB0aGlzLmNoYXJ0ID0gc3ZnXG4gICAgICAuYXBwZW5kKFwiZ1wiKVxuICAgICAgLmF0dHIoXCJwb3NpdGlvblwiLCBcInJlbGF0aXZlXCIpXG4gICAgICAuYXR0cihcImNsYXNzXCIsIFwibWFpbl9fc3ZnXCIpXG4gICAgICAuYXR0cihcbiAgICAgICAgXCJ0cmFuc2Zvcm1cIixcbiAgICAgICAgYHRyYW5zbGF0ZSgke01BUkdJTlMgKyBvcHRpb25zLmxlZnRPZmZzZXR9LCAke01BUkdJTlMgLyAyICtcbiAgICAgICAgICBvcHRpb25zLnRvcE9mZnNldH0pYFxuICAgICAgKTtcbiAgfVxuXG4gIHNldERhdGEoZGF0YSkge1xuICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gIH1cblxuICB4QXhpcyh0aWNrcyA9IDIwLCB0aWNrRm9ybWF0ID0gKCkgPT4ge30pIHtcbiAgICB0aGlzLnhTY2FsZSA9IGQzXG4gICAgICAuc2NhbGVMaW5lYXIoKVxuICAgICAgLnJhbmdlKFswLCBXSURUSF0pXG4gICAgICAvLyAuZG9tYWluKFswLCAxXSk7XG4gICAgbGV0IHhBeGlzQ2FsbCA9IGQzXG4gICAgICAuYXhpc0JvdHRvbSh0aGlzLnhTY2FsZSlcbiAgICAgIC50aWNrcyh0aWNrcylcbiAgICAgIC50aWNrRm9ybWF0KGQzLmZvcm1hdChcIi4wJVwiKSk7XG4gICAgdGhpcy5jaGFydFxuICAgICAgLmFwcGVuZChcImdcIilcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIGB0cmFuc2xhdGUoMCwgJHtIRUlHSFR9KWApXG4gICAgICAuY2FsbCh4QXhpc0NhbGwpO1xuICB9XG5cbiAgeUF4aXMoZG9tYWluLCB5U2NhbGUsIHRpY2tzID0gNSwgdGlja0Zvcm1hdCA9ICgpID0+IHt9KSB7XG4gICAgaWYgKHlTY2FsZSA9PT0gXCJzY2FsZUJhbmRcIikge1xuICAgICAgdGhpcy55U2NhbGUgPSBkM1t5U2NhbGVdKClcbiAgICAgICAgLmRvbWFpbihkb21haW4pXG4gICAgICAgIC5yYW5nZShbMCwgSEVJR0hUXSlcbiAgICAgICAgLnBhZGRpbmcoMC44KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy55U2NhbGUgPSBkM1t5U2NhbGVdKClcbiAgICAgICAgLmRvbWFpbihkb21haW4pXG4gICAgICAgIC5yYW5nZShbMCwgSEVJR0hUXSk7XG4gICAgfVxuXG4gICAgdGhpcy5jaGFydC5hcHBlbmQoXCJnXCIpLmNhbGwoXG4gICAgICBkM1xuICAgICAgICAuYXhpc0xlZnQodGhpcy55U2NhbGUpXG4gICAgICAgIC50aWNrcyh0aWNrcylcbiAgICAgICAgLnRpY2tGb3JtYXQodGlja0Zvcm1hdCgpKVxuICAgICk7XG4gIH1cblxuICBzZXRMYWJlbHMoKSB7XG4gICAgLy8gTGFiZWxzXG4gICAgdmFyIHhMYWJlbCA9IHRoaXMuY2hhcnRcbiAgICAgIC5hcHBlbmQoXCJnXCIpXG4gICAgICAuYXBwZW5kKFwidGV4dFwiKVxuICAgICAgLmF0dHIoXCJjbGFzc1wiLCBcIngtYXhpcy1sYWJlbFwiKVxuICAgICAgLmF0dHIoXCJ5XCIsIEhFSUdIVCArIDUwKVxuICAgICAgLmF0dHIoXCJ4XCIsIFdJRFRIIC8gMilcbiAgICAgIC5hdHRyKFwiZm9udC1zaXplXCIsIFwiMThweFwiKVxuICAgICAgLmF0dHIoXCJmb250LXdlaWdodFwiLCBcIjYwMFwiKVxuICAgICAgLmF0dHIoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxuICAgICAgLnRleHQoXCJHRFAgUGVyIENhcGl0YSAoJClcIik7XG4gICAgdmFyIHlMYWJlbCA9IHRoaXMuY2hhcnRcbiAgICAgIC5hcHBlbmQoXCJnXCIpXG4gICAgICAuYXR0cihcImNsYXNzXCIsIFwieUF4aXNHcm91cFwiKVxuICAgICAgLmFwcGVuZChcInRleHRcIilcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwicm90YXRlKC05MClcIilcbiAgICAgIC8vIC5hdHRyKFwicG9zaXRpb25cIiwgJ3JlbGF0aXZlJylcbiAgICAgIC5hdHRyKFwieFwiLCAtKEhFSUdIVCAvIDIpKVxuICAgICAgLmF0dHIoXCJ5XCIsIC01MClcbiAgICAgIC5hdHRyKFwiZm9udC1zaXplXCIsIFwiMThweFwiKVxuICAgICAgLmF0dHIoXCJmb250LXdlaWdodFwiLCBcIjYwMFwiKVxuICAgICAgLmF0dHIoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxuICAgICAgLnRleHQoXCJIYXBwaW5lc3MgSW5kZXggKCUpXCIpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoYXJ0O1xuIiwiZXhwb3J0IGNvbnN0IEFOSU1BVElPTl9EVVJBVElPTiA9IDEwMDA7XG5leHBvcnQgY29uc3QgQU5JTUFUSU9OX0RFTEFZID0gMDtcbmV4cG9ydCBjb25zdCBBTklNQVRJT05fRUFTSU5HID0gZDMuZWFzZVBvbHk7XG5cbmV4cG9ydCBjb25zdCBXSURUSCA9IHdpbmRvdy5pbm5lcldpZHRoIC0gMjUwO1xuZXhwb3J0IGNvbnN0IEhFSUdIVCA9IHdpbmRvdy5pbm5lckhlaWdodCAtIDMwMDtcbmV4cG9ydCBjb25zdCBNQVJHSU5TID0gMTAwO1xuIiwiaW1wb3J0IFdvcmxkR3JhcGggZnJvbSBcIi4vd29ybGRfZ3JhcGhcIjtcblxubGV0IHdvcmxkR3JhcGg7XG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCAoKSA9PiB7XG4gIC8vIGluaXRpYWxpemUgZGF0YSB2aXN1YWx6YXRpb25cbiAgd29ybGRHcmFwaCA9IG5ldyBXb3JsZEdyYXBoKFwic3ZnLmdyYXBoXCIpO1xuXG4gIC8vIGJ1dHRvbiBncm91cCBldmVudCBsaXN0ZW5lclxuICBsZXQgYnRuR3JvdXAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmJ0bi1ncm91cFwiKTtcbiAgYnRuR3JvdXAuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlZG93blwiLCBlID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgbGV0IGN1cnJlbnRCdG4gPSBlLnRhcmdldDtcbiAgICBsZXQgY3VycmVudEJ0blR5cGUgPSBjdXJyZW50QnRuLmNsYXNzTGlzdFsxXTtcbiAgICBsZXQgY3VycmVudEJ0bkNsYXNzO1xuICAgIGlmIChjdXJyZW50QnRuVHlwZSA9PT0gXCJoZWFkZXItZ3JhcGhfX2J0blwiKSB7XG4gICAgICBjdXJyZW50QnRuQ2xhc3MgPSBjdXJyZW50QnRuLmNsYXNzTGlzdFswXS5zcGxpdChcIi1cIilbMV07XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnRCdG5UeXBlID09PSBcImhlYWRlci1ncmFwaF9fYnRuXCIpIHtcbiAgICAgIHdvcmxkR3JhcGgudXBkYXRlRGF0YShjdXJyZW50QnRuQ2xhc3MpO1xuICAgICAgbGV0IGFsbEJ0bnMgPSBidG5Hcm91cC5xdWVyeVNlbGVjdG9yQWxsKFwiYVwiKTtcbiAgICAgIGFsbEJ0bnMuZm9yRWFjaChidG4gPT4ge1xuICAgICAgICBidG4uY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKTtcbiAgICAgIH0pO1xuICAgICAgY3VycmVudEJ0bi5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gbW9kYWwgYWN0aW9uc1xuICBjb25zdCBtb2RhbEJnID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vZGFsLWJnJyk7XG4gIG1vZGFsQmcuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBoYW5kbGVNb2RhbEJnQ2xpY2spO1xufSk7XG5cbi8vIG1vZGFsIGNsb3NlIFxuZnVuY3Rpb24gaGFuZGxlTW9kYWxCZ0NsaWNrKGUpIHtcbiAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgbGV0IG1vZGFsQmcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLm1vZGFsLWJnXCIpO1xuICBsZXQgbW9kYWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kYWwnKTtcblxuICBpZiAoXG4gICAgZS50YXJnZXQuY2xhc3NMaXN0WzBdID09PSBcIm1vZGFsLWJnXCIgfHxcbiAgICBlLnRhcmdldC5jbGFzc0xpc3RbMF0gPT09IFwibW9kYWwtY2xvc2VfX2J0bi1zaW5nbGVcIiApIHtcbiAgICBtb2RhbC5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCBcIm9wYWNpdHk6IDA7IHZpc2liaWxpdHk6IGhpZGRlblwiKTtcbiAgICBtb2RhbEJnLnNldEF0dHJpYnV0ZShcInN0eWxlXCIsIFwib3BhY2l0eTogMDsgdmlzaWJpbGl0eTogaGlkZGVuXCIpO1xuICB9ICBcbn1cbiIsImltcG9ydCB7XG4gIFdJRFRILFxuICBIRUlHSFQsXG4gIE1BUkdJTlMsXG4gIEFOSU1BVElPTl9ERUxBWSxcbiAgQU5JTUFUSU9OX0VBU0lORyxcbiAgQU5JTUFUSU9OX0RVUkFUSU9OXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG5pbXBvcnQgQ2hhcnQgZnJvbSBcIi4vY2hhcnRcIjtcblxuY2xhc3MgV29ybGRHcmFwaCBleHRlbmRzIENoYXJ0IHtcbiAgY29uc3RydWN0b3Ioc2VsZWN0b3IpIHtcbiAgICBzdXBlcihzZWxlY3Rvcik7XG4gICAgdGhpcy5zdmcgPSBkMy5zZWxlY3Qoc2VsZWN0b3IpO1xuICAgIHRoaXMueEF4aXMoKTtcbiAgICB0aGlzLnlBeGlzKFsxLCAwXSwgXCJzY2FsZUxpbmVhclwiLCAyMCwgKCkgPT4gZDMuZm9ybWF0KFwiLjAlXCIpKTtcbiAgICB0aGlzLmdldERhdGEoXCJncmFwaEdkcFwiKTtcbiAgfVxuXG4gIGdldERhdGEobWV0cmljKSB7XG4gICAgbGV0IHRoYXQgPSB0aGlzO1xuICAgIGQzLmpzb24oXCJkaXN0L2RhdGEvY291bnRyaWVzLmpzb25cIikudGhlbihkYXRhID0+IHtcbiAgICAgIHRoYXQuc2V0RGF0YShkYXRhKTtcbiAgICAgIHRoYXQuY2lyY2xlcyhtZXRyaWMpO1xuICAgIH0pO1xuICB9XG5cbiAgZm9ybWF0T3JkaW5hbChudW0pIHtcbiAgICBjb25zdCBpbnQgPSBwYXJzZUludChudW0pLFxuICAgICAgZGlnaXRzID0gW2ludCAlIDEwLCBpbnQgJSAxMDBdLFxuICAgICAgb3JkaW5hbHMgPSBbJ3N0JywgJ25kJywgJ3JkJywgJ3RoJ10sXG4gICAgICBvUGF0dGVybiA9IFsxLCAyLCAzLCA0XSxcbiAgICAgIHRQYXR0ZXJuID0gWzExLCAxMiwgMTMsIDE0LCAxNSwgMTYsIDE3LCAxOCwgMTldO1xuICAgIHJldHVybiBvUGF0dGVybi5pbmNsdWRlcyhkaWdpdHNbMF0pICYmICF0UGF0dGVybi5pbmNsdWRlcyhkaWdpdHNbMV0pXG4gICAgICA/IGludCArIG9yZGluYWxzW2RpZ2l0c1swXSAtIDFdXG4gICAgICA6IGludCArIG9yZGluYWxzWzNdO1xuICB9O1xuXG4gIGNpcmNsZXMobWV0cmljKSB7XG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gdG9vbHRpcFxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIGxldCB0b29sdGlwID0gZDNcbiAgICAgIC5zZWxlY3QoXCJib2R5XCIpXG4gICAgICAuYXBwZW5kKFwiZGl2XCIpXG4gICAgICAuc3R5bGUoXCJ2aXNpYmlsaXR5XCIsIFwiaGlkZGVuXCIpXG4gICAgICAuYXR0cihcImNsYXNzXCIsIFwidG9vbHRpcFwiKVxuICAgICAgLnN0eWxlKFwiYmFja2dyb3VuZC1jb2xvclwiLCBcImJsYWNrXCIpXG4gICAgICAuc3R5bGUoXCJib3JkZXItcmFkaXVzXCIsIFwiNXB4XCIpXG4gICAgICAuc3R5bGUoXCJwYWRkaW5nXCIsIFwiMTBweFwiKVxuICAgICAgLnN0eWxlKFwiY29sb3JcIiwgXCJ3aGl0ZVwiKVxuICAgICAgLnN0eWxlKFwiei1pbmRleFwiLCBcIjk5OTk5OTk5OVwiKVxuICAgICAgLnN0eWxlKFwicG9zaXRpb25cIiwgXCJhYnNvbHV0ZVwiKVxuICAgICAgLnN0eWxlKFwiZGlzcGxheVwiLCBcImJsb2NrXCIpO1xuXG4gICAgbGV0IHRoYXQgPSB0aGlzO1xuICAgIGxldCBzaG93VG9vbHRpcCA9IGZ1bmN0aW9uKGQpIHtcbiAgICAgIHRvb2x0aXAudHJhbnNpdGlvbigpLmR1cmF0aW9uKDIwMCk7XG4gICAgICB0b29sdGlwXG4gICAgICAgIC5zdHlsZShcInZpc2liaWxpdHlcIiwgXCJ2aXNpYmxlXCIpXG4gICAgICAgIC5odG1sKFxuICAgICAgICAgIGBcbiAgPHN0cm9uZz5Db3VudHJ5Ojwvc3Ryb25nPiAke2QuY291bnRyeX0gKCR7ZC5jb250aW5lbnR9KTxici8+XG4gIDxzdHJvbmc+SGFwcGluZXNzIFJhbmtpbmc6PC9zdHJvbmc+ICR7dGhhdC5mb3JtYXRPcmRpbmFsKGQucmFua2luZyl9XG5gXG4gICAgICAgIClcbiAgICAgICAgLnN0eWxlKFwidG9wXCIsIGQzLmV2ZW50LmNsaWVudFkgLSAxMDAgKyBcInB4XCIpXG4gICAgICAgIC5zdHlsZShcImxlZnRcIiwgZDMuZXZlbnQuY2xpZW50WCAtIDE2MCArIFwicHhcIik7XG4gICAgfTtcblxuICAgIGxldCBtb3ZlVG9vbHRpcCA9IGZ1bmN0aW9uKGQpIHtcbiAgICAgIHNob3dUb29sdGlwKGQpO1xuICAgICAgdG9vbHRpcFxuICAgICAgICAuc3R5bGUoXCJ0b3BcIiwgZDMuZXZlbnQuY2xpZW50WSAtIDEwMCArIFwicHhcIilcbiAgICAgICAgLnN0eWxlKFwibGVmdFwiLCBkMy5ldmVudC5jbGllbnRYIC0gMTYwICsgXCJweFwiKTtcbiAgICB9O1xuXG4gICAgbGV0IGhpZGVUb29sdGlwID0gZnVuY3Rpb24oZCkge1xuICAgICAgdG9vbHRpcFxuICAgICAgICAudHJhbnNpdGlvbigpXG4gICAgICAgIC5kdXJhdGlvbigyMDApXG4gICAgICAgIC5zdHlsZShcInZpc2liaWxpdHlcIiwgXCJoaWRkZW5cIik7XG4gICAgfTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIGNoYXJ0IHJlbmRlcmluZ1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIHRoaXMuY2hhcnRcbiAgICAgIC5zZWxlY3RBbGwoXCJjaXJjbGVcIilcbiAgICAgIC5kYXRhKE9iamVjdC52YWx1ZXModGhpcy5kYXRhKSlcbiAgICAgIC5lbnRlcigpXG4gICAgICAuYXBwZW5kKFwiY2lyY2xlXCIpXG4gICAgICAuYXR0cihcbiAgICAgICAgXCJjbGFzc1wiLFxuICAgICAgICBkID0+XG4gICAgICAgICAgYGNvdW50cnkgJHtkLmNsYXNzfSBjb250aW5lbnQtJHtkLmNvbnRpbmVudFxuICAgICAgICAgICAgLnNwbGl0KFwiIFwiKVxuICAgICAgICAgICAgLmpvaW4oXCItXCIpfSBjb3VudHJ5LWJ1YmJsZWBcbiAgICAgIClcbiAgICAgIC5hdHRyKFwiZmlsbFwiLCBkID0+IHtcbiAgICAgICAgaWYgKGQuY29udGluZW50ID09PSBcIkFmcmljYVwiKSB7XG4gICAgICAgICAgcmV0dXJuIFwiIzdjYmQxZVwiO1xuICAgICAgICB9IGVsc2UgaWYgKGQuY29udGluZW50ID09PSBcIkFzaWFcIikge1xuICAgICAgICAgIHJldHVybiBcIiNmZjFmNWFcIjtcbiAgICAgICAgfSBlbHNlIGlmIChkLmNvbnRpbmVudCA9PT0gXCJOb3J0aCBBbWVyaWNhXCIpIHtcbiAgICAgICAgICByZXR1cm4gXCIjMzAzNDgxXCI7XG4gICAgICAgIH0gZWxzZSBpZiAoZC5jb250aW5lbnQgPT09IFwiU291dGggQW1lcmljYVwiKSB7XG4gICAgICAgICAgcmV0dXJuIFwiI2ZmNWI0NFwiO1xuICAgICAgICB9IGVsc2UgaWYgKGQuY29udGluZW50ID09PSBcIkV1cm9wZVwiKSB7XG4gICAgICAgICAgcmV0dXJuIFwiIzJmYzVjY1wiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBcInJlZFwiO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmF0dHIoXCJvcGFjaXR5XCIsIFwiLjdcIilcbiAgICAgIC5hdHRyKFwic3Ryb2tlXCIsIFwiI0NEQ0RDRFwiKVxuICAgICAgLmF0dHIoXCJzdHJva2Utd2lkdGhcIiwgXCIycHhcIilcbiAgICAgIC5hdHRyKFwiY3hcIiwgZCA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnhTY2FsZShkW21ldHJpY10gLyAxNTYpICsgMjU7XG4gICAgICB9KVxuICAgICAgLm9uKFwibW91c2VvdmVyXCIsIHNob3dUb29sdGlwKVxuICAgICAgLm9uKFwibW91c2Vtb3ZlXCIsIG1vdmVUb29sdGlwKVxuICAgICAgLm9uKFwibW91c2VsZWF2ZVwiLCBoaWRlVG9vbHRpcClcbiAgICAgIC50cmFuc2l0aW9uKClcbiAgICAgIC5kZWxheSgoZCwgaSkgPT4gaSAqIEFOSU1BVElPTl9ERUxBWSlcbiAgICAgIC5kdXJhdGlvbihBTklNQVRJT05fRFVSQVRJT04pXG4gICAgICAuZWFzZShBTklNQVRJT05fRUFTSU5HKVxuICAgICAgLmF0dHIoXCJyXCIsIGQgPT4ge1xuICAgICAgICBpZiAoZC5wb3B1bGF0aW9uID4gODAwMDAwMDAwKSB7XG4gICAgICAgICAgcmV0dXJuIGQucG9wdWxhdGlvbiAvIDI1MDAwMDAwO1xuICAgICAgICB9IGVsc2UgaWYgKGQucG9wdWxhdGlvbiA+IDUwMDAwMDAwKSB7XG4gICAgICAgICAgcmV0dXJuIGQucG9wdWxhdGlvbiAvIDEwMDAwMDAwO1xuICAgICAgICB9IGVsc2UgaWYgKGQucG9wdWxhdGlvbiA+IDEwMDAwMDApIHtcbiAgICAgICAgICByZXR1cm4gZC5wb3B1bGF0aW9uIC8gMTUwMDAwMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZC5wb3B1bGF0aW9uIC8gMTAwMDAwO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmF0dHIoXCJjeVwiLCBkID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMueVNjYWxlKGQuZ3JhcGhSYW5raW5nIC8gMTU2KTtcbiAgICAgIH0pO1xuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gbGVnZW5kXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgbGV0IGNvbnRpbmVudHMgPSB7XG4gICAgICBBRlJJQ0E6IHsgY29udGluZW50OiBcIkFmcmljYVwiIH0sXG4gICAgICBBU0lBOiB7IGNvbnRpbmVudDogXCJBc2lhXCIgfSxcbiAgICAgIE5PUlRIX0FNRVJJQ0E6IHsgY29udGluZW50OiBcIk5vcnRoIEFtZXJpY2FcIiB9LFxuICAgICAgU09VVEhfQU1FUklDQTogeyBjb250aW5lbnQ6IFwiU291dGggQW1lcmljYVwiIH0sXG4gICAgICBFVVJPUEU6IHsgY29udGluZW50OiBcIkV1cm9wZVwiIH1cbiAgICB9O1xuXG4gICAgbGV0IGNvbnRpbmVudEZvY3VzT24gPSBjb250aW5lbnROYW1lID0+IHtcbiAgICAgIHRoaXMuY2hhcnRcbiAgICAgICAgLnNlbGVjdEFsbChcbiAgICAgICAgICBgY2lyY2xlOm5vdCguY29udGluZW50LSR7Y29udGluZW50TmFtZS5zcGxpdChcIiBcIikuam9pbihcIi1cIil9KWBcbiAgICAgICAgKVxuICAgICAgICAuYXR0cihcIm9wYWNpdHlcIiwgXCIwLjA1XCIpO1xuICAgIH07XG5cbiAgICBsZXQgY29udGluZW50Rm9jdXNPZmYgPSBjb250aW5lbnROYW1lID0+IHtcbiAgICAgIHRoaXMuY2hhcnRcbiAgICAgICAgLnNlbGVjdEFsbChcbiAgICAgICAgICBgY2lyY2xlOm5vdCguY29udGluZW50LSR7Y29udGluZW50TmFtZS5zcGxpdChcIiBcIikuam9pbihcIi1cIil9KWBcbiAgICAgICAgKVxuICAgICAgICAuYXR0cihcIm9wYWNpdHlcIiwgXCIwLjdcIik7XG4gICAgfTtcblxuICAgIGxldCBsZWdlbmQgPSB0aGlzLmNoYXJ0XG4gICAgICAuc2VsZWN0QWxsKFwiLmxlZ2VuZFwiKVxuICAgICAgLmRhdGEoT2JqZWN0LnZhbHVlcyhjb250aW5lbnRzKSlcbiAgICAgIC5lbnRlcigpXG4gICAgICAuYXBwZW5kKFwiZ1wiKVxuICAgICAgLmF0dHIoXCJjbGFzc1wiLCBcImxlZ2VuZFwiKVxuICAgICAgLmF0dHIoXCJwb3NpdGlvblwiLCBcImFic29sdXRlXCIpXG4gICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBgdHJhbnNsYXRlKCR7V0lEVEggLSAxMzB9LCAke0hFSUdIVCAtIDEyMH0pYCk7XG5cbiAgICBsZWdlbmRcbiAgICAgIC5hcHBlbmQoXCJyZWN0XCIpXG4gICAgICAuYXR0cihcInhcIiwgMClcbiAgICAgIC5hdHRyKFwieVwiLCBmdW5jdGlvbihkLCBpKSB7XG4gICAgICAgIHJldHVybiAyMCAqIGk7XG4gICAgICB9KVxuICAgICAgLmF0dHIoXCJ3aWR0aFwiLCAyMClcbiAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIDIwKVxuICAgICAgLnN0eWxlKFwiZmlsbFwiLCBmdW5jdGlvbihkKSB7XG4gICAgICAgIGlmIChkLmNvbnRpbmVudCA9PT0gXCJBZnJpY2FcIikge1xuICAgICAgICAgIHJldHVybiBcIiM3Y2JkMWVcIjtcbiAgICAgICAgfSBlbHNlIGlmIChkLmNvbnRpbmVudCA9PT0gXCJBc2lhXCIpIHtcbiAgICAgICAgICByZXR1cm4gXCIjZmYxZjVhXCI7XG4gICAgICAgIH0gZWxzZSBpZiAoZC5jb250aW5lbnQgPT09IFwiTm9ydGggQW1lcmljYVwiKSB7XG4gICAgICAgICAgcmV0dXJuIFwiIzMwMzQ4MVwiO1xuICAgICAgICB9IGVsc2UgaWYgKGQuY29udGluZW50ID09PSBcIlNvdXRoIEFtZXJpY2FcIikge1xuICAgICAgICAgIHJldHVybiBcIiNmZjViNDRcIjtcbiAgICAgICAgfSBlbHNlIGlmIChkLmNvbnRpbmVudCA9PT0gXCJFdXJvcGVcIikge1xuICAgICAgICAgIHJldHVybiBcIiMyZmM1Y2NcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gXCJyZWRcIjtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5vbihcIm1vdXNlb3ZlclwiLCBkID0+IGNvbnRpbmVudEZvY3VzT24oZC5jb250aW5lbnQpKVxuICAgICAgLm9uKFwibW91c2VsZWF2ZVwiLCBkID0+IGNvbnRpbmVudEZvY3VzT2ZmKGQuY29udGluZW50KSk7XG5cbiAgICBsZWdlbmRcbiAgICAgIC5hcHBlbmQoXCJ0ZXh0XCIpXG4gICAgICAuYXR0cihcInhcIiwgMjUpXG4gICAgICAuYXR0cihcInRleHQtYW5jaG9yXCIsIFwic3RhcnRcIilcbiAgICAgIC5hdHRyKFwiZHlcIiwgXCIxZW1cIilcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgZCA9PiBgbGVnZW5kLSR7ZC5jb250aW5lbnQuc3BsaXQoXCIgXCIpLmpvaW4oXCItXCIpfWApXG4gICAgICAuYXR0cihcInlcIiwgZnVuY3Rpb24oZCwgaSkge1xuICAgICAgICByZXR1cm4gMjAgKiBpO1xuICAgICAgfSlcbiAgICAgIC50ZXh0KGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgcmV0dXJuIGQuY29udGluZW50O1xuICAgICAgfSlcbiAgICAgIC5hdHRyKFwiZm9udC1zaXplXCIsIFwiMTJweFwiKVxuICAgICAgLm9uKFwibW91c2VvdmVyXCIsIGQgPT4gY29udGluZW50Rm9jdXNPbihkLmNvbnRpbmVudCkpXG4gICAgICAub24oXCJtb3VzZWxlYXZlXCIsIGQgPT4gY29udGluZW50Rm9jdXNPZmYoZC5jb250aW5lbnQpKTtcblxuICAgIGxlZ2VuZFxuICAgICAgLmFwcGVuZChcInRleHRcIilcbiAgICAgIC5hdHRyKFwieFwiLCAzMSlcbiAgICAgIC5hdHRyKFwiZHlcIiwgXCItLjJlbVwiKVxuICAgICAgLmF0dHIoXCJ5XCIsIC0xMClcbiAgICAgIC50ZXh0KFwiQ29udGluZW50XCIpXG4gICAgICAuYXR0cihcImZvbnQtc2l6ZVwiLCBcIjE3cHhcIilcbiAgICAgIC5zdHlsZShcInRleHQtYWxpZ25cIiwgXCJsZWZ0XCIpO1xuICB9XG5cbiAgdXBkYXRlRGF0YShkYXRhVHlwZSkge1xuICAgIGQzLmpzb24oXCJkaXN0L2RhdGEvY291bnRyaWVzLmpzb25cIikudGhlbihkYXRhID0+IHtcbiAgICAgIHRoaXMuY2hhcnRcbiAgICAgICAgLnNlbGVjdEFsbChcIi5jb3VudHJ5LWJ1YmJsZVwiKVxuICAgICAgICAudHJhbnNpdGlvbigpXG4gICAgICAgIC5kdXJhdGlvbig1MDApXG4gICAgICAgIC5lYXNlKEFOSU1BVElPTl9FQVNJTkcpXG4gICAgICAgIC5hdHRyKFwiY3hcIiwgZCA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMueFNjYWxlKGRbZGF0YVR5cGVdIC8gMTU2KSArIDI1O1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnVwZGF0ZUF4aXNMYWJlbChkYXRhVHlwZSk7XG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVBeGlzTGFiZWwodHlwZSkge1xuICAgIC8vIHhMYWJlbFxuICAgIGxldCBsYWJlbDtcbiAgICBpZiAodHlwZSA9PT0gJ2dyYXBoU29jaWFsU3VwcG9ydCcpIHtcbiAgICAgIGxhYmVsID0gJ1NvY2lhbCBTdXBwb3J0JztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwiZ3JhcGhGcmVlZG9tXCIpIHtcbiAgICAgIGxhYmVsID0gJ0ZyZWVkb20nO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gXCJncmFwaEdlbmVyb3NpdHlcIikge1xuICAgICAgbGFiZWwgPSAnR2VuZXJvc2l0eSc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBcImdyYXBoTGlmZUV4cGVjdGFuY3lcIikge1xuICAgICAgbGFiZWwgPSAnTGlmZSBFeHBlY3RhbmN5JztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdncmFwaEdkcCcpIHtcbiAgICAgIGxhYmVsID0gJ0dEUCBQZXIgQ2FwaXRhICgkKSc7XG4gICAgfVxuICAgIHRoaXMuY2hhcnQuc2VsZWN0KFwiLngtYXhpcy1sYWJlbFwiKS50ZXh0KGAke2xhYmVsfWApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFdvcmxkR3JhcGg7XG4iXSwic291cmNlUm9vdCI6IiJ9 -------------------------------------------------------------------------------- /dist/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | /* global */ 2 | body { 3 | font-family: "Work Sans", sans-serif; 4 | font-size: 16px; 5 | /* background-color: #fcfdef; */ 6 | position: relative; 7 | } 8 | 9 | h1, h2, h3, h4, h5, h6 { 10 | font-family: "Darker Grotesque", sans-serif; 11 | } 12 | 13 | 14 | /* main */ 15 | .main__container--inner { 16 | width: 1200px; 17 | margin: 0 auto; 18 | padding: 1rem; 19 | } 20 | 21 | .header__container { 22 | display: flex; 23 | justify-content: space-between; 24 | align-items: center; 25 | padding: 1.2rem 2rem; 26 | /* box-shadow: 0px 0px 15px rgba(0,0,0,.08); */ 27 | } 28 | .header__content { 29 | flex: 1; 30 | padding-right: 3rem; 31 | max-width: 650px; 32 | } 33 | .header__tooltop { 34 | min-width: 320px; 35 | } 36 | .main__header { 37 | font-size: 1.8rem; 38 | line-height: 1.5rem; 39 | color: initial; 40 | transition: all 100ms ease-in; 41 | text-transform: uppercase; 42 | font-weight: 900; 43 | } 44 | 45 | .header { 46 | display: flex; 47 | justify-content: space-between; 48 | align-items: center; 49 | } 50 | 51 | .header__btn-group { 52 | margin-right: 2rem; 53 | } 54 | 55 | .header-graph__btn { 56 | color: #000; 57 | text-transform: uppercase; 58 | text-decoration: none; 59 | transition: all 100ms ease-in; 60 | border-bottom: 2px solid transparent; 61 | position: relative; 62 | 63 | } 64 | 65 | .header-graph__btn:hover { 66 | border-bottom: 2px solid #b62840; 67 | text-decoration: none; 68 | color: #000; 69 | } 70 | 71 | .header-graph__btn.active { 72 | border-bottom: 2px solid #b62840; 73 | text-decoration: none; 74 | text-shadow: 0 0 .65px #333, 0 0 .65px #333; 75 | color: #000; 76 | } 77 | 78 | .header-graph__btn:hover .nav__dropdown { 79 | opacity: 1; 80 | visibility: visible; 81 | } 82 | 83 | /* nav dropdown */ 84 | .nav__dropdown { 85 | opacity: 0; 86 | visibility: hidden; 87 | position: absolute; 88 | left: 0; 89 | top: 30px; 90 | background-color: black; 91 | border-radius: 5px; 92 | padding: 10px; 93 | color: white; 94 | z-index: 9999; 95 | text-transform: initial; 96 | min-width: 150px; 97 | transition: all 150ms ease-in; 98 | /* font-size: .8rem; */ 99 | } 100 | 101 | .nav__dropdown:before { 102 | content: ''; 103 | display: block; 104 | width: 0; 105 | height: 0; 106 | position: absolute; 107 | border-right: 12px solid transparent; 108 | border-left: 12px solid transparent; 109 | border-bottom: 12px solid black; 110 | left: 2%; 111 | top: -8px; 112 | } 113 | 114 | 115 | 116 | 117 | .header__img { 118 | width: 21px; 119 | } 120 | 121 | .main__description { 122 | /* font-family: "Work Sans", sans-serif; */ 123 | font-family: "Lora", sans-serif; 124 | margin-bottom: 3rem; 125 | font-size: 1.4rem; 126 | line-height: 2.4rem; 127 | } 128 | 129 | .graph__container { 130 | /* position: relative; 131 | top: 24px; 132 | width: 100%; 133 | height: 100%; */ 134 | 135 | 136 | height: calc(100vh - 100px); 137 | width: calc(100vw); 138 | display: block; 139 | /* border: 1px solid red; */ 140 | display: flex; 141 | justify-content: center; 142 | /* align-items: center; */ 143 | } 144 | 145 | /* svg */ 146 | .graph__container svg { 147 | position: absolute; 148 | cursor: pointer; 149 | } 150 | 151 | .graph__background { 152 | width: 100%; 153 | } 154 | 155 | /* text { 156 | fill: #777; 157 | font-size: 12px; 158 | } */ 159 | 160 | .map-city-label { 161 | cursor: pointer; 162 | font-weight: 700; 163 | } 164 | 165 | .label-text { 166 | font-size: 12px; 167 | font-weight: 700; 168 | fill: white; 169 | } 170 | 171 | .city { 172 | cursor: pointer; 173 | z-index: 100; 174 | transition: all 100ms ease-in; 175 | } 176 | 177 | text.city { 178 | z-index: 10; 179 | } 180 | 181 | @keyframes bounce { 182 | from { transform: translateY(0) } 183 | to { transform: translateY(-3px) } 184 | } 185 | 186 | /* .city-pinpoint { 187 | animation: bounce 0.5s infinite; 188 | animation-direction: alternate; 189 | transform-origin: 50% 50% 0; 190 | } */ 191 | 192 | .country-bubble { 193 | transition: all 100ms ease-in; 194 | /* animation: bounce 0.5s infinite; 195 | animation-direction: alternate; 196 | transform-origin: 50% 50% 0; */ 197 | } 198 | 199 | .country-bubble:hover { 200 | stroke: black; 201 | } 202 | 203 | /* filter */ 204 | .filter { 205 | opacity: 0.1; 206 | } 207 | 208 | 209 | /* tooltip */ 210 | p.tooltip__detail { 211 | margin-bottom: 5px; 212 | } 213 | 214 | /* sources */ 215 | .sources { 216 | z-index: 99999; 217 | position: relative; 218 | } 219 | 220 | /* header */ 221 | .header { 222 | z-index: 99999; 223 | position: relative; 224 | } 225 | .header__link { 226 | color: black; 227 | transition: all 100ms ease-in; 228 | } 229 | 230 | .header__link:hover { 231 | color: #777; 232 | } 233 | .header__link i { 234 | font-size: 2rem; 235 | } 236 | 237 | i.fab.fa-angellist { 238 | font-size: 1.9rem; 239 | } 240 | 241 | 242 | /* modal */ 243 | 244 | .modal-bg { 245 | position: fixed; 246 | top: 0; 247 | bottom: 0; 248 | left: 0; 249 | right: 0; 250 | background-color: rgba(255,255,255,.8); 251 | z-index: 9999999; 252 | transition: all 150ms ease-in; 253 | } 254 | 255 | .modal { 256 | position: absolute; 257 | top: 50%; 258 | left: 50%; 259 | transform: translate(-50%, -50%); 260 | background-color: white; 261 | padding: 2rem 4rem; 262 | border-radius: 5px; 263 | box-shadow: 0 5px 15px rgba(0,0,0,.2); 264 | display: flex; 265 | flex-direction: column; 266 | justify-content: space-between; 267 | /* text-align: center; */ 268 | transition: all 150ms ease-in; 269 | } 270 | 271 | .modal-close__btn { 272 | position: absolute; 273 | right: 3rem; 274 | top: 3rem; 275 | font-size: 1.6rem; 276 | cursor: pointer; 277 | padding: 1rem; 278 | transition: all 200ms ease-in; 279 | } 280 | 281 | .modal-close__btn:hover { 282 | color: #b62840; 283 | transform: rotate(-90deg); 284 | } 285 | 286 | .modal .main__header { 287 | margin-bottom: 4rem; 288 | } 289 | 290 | .modal .text { 291 | margin-bottom: 4rem; 292 | } 293 | 294 | .main__description { 295 | font-size: 1.4rem; 296 | } 297 | 298 | .source__link { 299 | color: #000; 300 | font-weight: bold; 301 | text-decoration: none; 302 | transition: all 100ms ease-in; 303 | border-bottom: 2px solid transparent; 304 | 305 | } 306 | 307 | .source__link:hover { 308 | border-bottom: 2px solid #b62840; 309 | text-decoration: none; 310 | color: #000; 311 | font-weight: bold; 312 | } -------------------------------------------------------------------------------- /gitignore: -------------------------------------------------------------------------------- 1 | /node_modules -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | World Happiness Report | Data Visualization 17 | 18 | 19 | 50 |
51 |
52 |
53 |

World
Happiness
Report whr logo heart

54 |
55 | 91 |
92 | 93 |
94 | 95 |
96 |
97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js_project", 3 | "version": "1.0.0", 4 | "description": "visualizes notable sorting algorithms, written in JS & D3.js", 5 | "private": true, 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "webpack": "npx webpack --watch --mode=development" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/mrkchoi/sort-visualizer.git" 14 | }, 15 | "keywords": [ 16 | "sorting", 17 | "algorithms", 18 | "visualizer", 19 | "data", 20 | "visualization" 21 | ], 22 | "author": "Kenneth Choi", 23 | "license": "ISC", 24 | "bugs": { 25 | "url": "https://github.com/mrkchoi/sort-visualizer/issues" 26 | }, 27 | "homepage": "https://github.com/mrkchoi/sort-visualizer#readme", 28 | "dependencies": { 29 | "@babel/core": "^7.5.5", 30 | "@babel/preset-env": "^7.5.5", 31 | "babel-loader": "^8.0.6", 32 | "d3-scale": "^3.0.0", 33 | "d3-scale-chromatic": "^1.3.3", 34 | "lodash": "^4.17.14", 35 | "normalize.css": "^8.0.1", 36 | "topojson": "^3.0.2", 37 | "webpack": "^4.36.1", 38 | "webpack-cli": "^3.3.6" 39 | }, 40 | "devDependencies": { 41 | "webpack-dev-server": "^3.7.2" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/chart.js: -------------------------------------------------------------------------------- 1 | import { 2 | HEIGHT, 3 | MARGINS, 4 | WIDTH, 5 | ANIMATION_DURATION, 6 | ANIMATION_DELAY, 7 | ANIMATION_EASING 8 | } from "./constants"; 9 | 10 | class Chart { 11 | constructor(selector, options) { 12 | this.setChart(selector, options); 13 | this.setLabels(); 14 | } 15 | 16 | setChart(selector, options = { topOffset: 0, leftOffset: 0 }) { 17 | const svg = d3 18 | .select(selector) 19 | .attr("height", HEIGHT + MARGINS * 2) 20 | .attr("width", WIDTH + MARGINS * 2); 21 | this.chart = svg 22 | .append("g") 23 | .attr("position", "relative") 24 | .attr("class", "main__svg") 25 | .attr( 26 | "transform", 27 | `translate(${MARGINS + options.leftOffset}, ${MARGINS / 2 + 28 | options.topOffset})` 29 | ); 30 | } 31 | 32 | setData(data) { 33 | this.data = data; 34 | } 35 | 36 | xAxis(ticks = 20, tickFormat = () => {}) { 37 | this.xScale = d3 38 | .scaleLinear() 39 | .range([0, WIDTH]) 40 | // .domain([0, 1]); 41 | let xAxisCall = d3 42 | .axisBottom(this.xScale) 43 | .ticks(ticks) 44 | .tickFormat(d3.format(".0%")); 45 | this.chart 46 | .append("g") 47 | .attr("transform", `translate(0, ${HEIGHT})`) 48 | .call(xAxisCall); 49 | } 50 | 51 | yAxis(domain, yScale, ticks = 5, tickFormat = () => {}) { 52 | if (yScale === "scaleBand") { 53 | this.yScale = d3[yScale]() 54 | .domain(domain) 55 | .range([0, HEIGHT]) 56 | .padding(0.8); 57 | } else { 58 | this.yScale = d3[yScale]() 59 | .domain(domain) 60 | .range([0, HEIGHT]); 61 | } 62 | 63 | this.chart.append("g").call( 64 | d3 65 | .axisLeft(this.yScale) 66 | .ticks(ticks) 67 | .tickFormat(tickFormat()) 68 | ); 69 | } 70 | 71 | setLabels() { 72 | // Labels 73 | var xLabel = this.chart 74 | .append("g") 75 | .append("text") 76 | .attr("class", "x-axis-label") 77 | .attr("y", HEIGHT + 50) 78 | .attr("x", WIDTH / 2) 79 | .attr("font-size", "18px") 80 | .attr("font-weight", "600") 81 | .attr("text-anchor", "middle") 82 | .text("GDP Per Capita ($)"); 83 | var yLabel = this.chart 84 | .append("g") 85 | .attr("class", "yAxisGroup") 86 | .append("text") 87 | .attr("transform", "rotate(-90)") 88 | // .attr("position", 'relative') 89 | .attr("x", -(HEIGHT / 2)) 90 | .attr("y", -50) 91 | .attr("font-size", "18px") 92 | .attr("font-weight", "600") 93 | .attr("text-anchor", "middle") 94 | .text("Happiness Index (%)"); 95 | } 96 | } 97 | 98 | export default Chart; 99 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | export const ANIMATION_DURATION = 1000; 2 | export const ANIMATION_DELAY = 0; 3 | export const ANIMATION_EASING = d3.easePoly; 4 | 5 | export const WIDTH = window.innerWidth - 250; 6 | export const HEIGHT = window.innerHeight - 300; 7 | export const MARGINS = 100; 8 | -------------------------------------------------------------------------------- /src/filter.js: -------------------------------------------------------------------------------- 1 | class Filter { 2 | constructor() { 3 | this.filterData(); 4 | } 5 | 6 | filterData() { 7 | const tooltip = d3 8 | .select(`.header__tooltip`) 9 | .append("div") 10 | .style("opacity", 0) 11 | .attr("class", "tooltip") 12 | .style("background-color", "white") 13 | .style("border", "solid") 14 | .style("border-width", "2px") 15 | .style("border-radius", "5px") 16 | .style("padding", "1rem"); 17 | 18 | d3.selectAll('.city') 19 | .on('mouseover', (d, i) => { 20 | let className; 21 | if (typeof d === 'string') { 22 | className = `city-${d.split(' ').join('-')}`; 23 | } else if (d.data) { 24 | className = d.data.class; 25 | } else { 26 | className = d.class; 27 | } 28 | const allOtherCityData = document.querySelectorAll(`.city:not(.${className})`); 29 | allOtherCityData.forEach(data => { 30 | data.classList.add('filter'); 31 | }) 32 | 33 | // tooltip 34 | tooltip 35 | .style("opacity", 1) 36 | .style("stroke", "black") 37 | .html( 38 | ` 39 |
40 |

City: ${ 41 | d.city 42 | }

43 |

Overall Rank: ${ 44 | d.ranking 45 | }

46 |

Total Happiness Score: ${ 47 | d.happinessScore 48 | }/100

49 |

Emotional & Physical Well-Being: ${ 50 | d.emotionalWellbeing 51 | }

52 |

Income & Employment: ${ 53 | d.incomeEmployment 54 | }

55 |

Community & Environment: ${ 56 | d.communityEnvironment 57 | }

58 |
59 | ` 60 | ); 61 | const mainHeader = document.querySelector('.main__header'); 62 | mainHeader.setAttribute('style', `color: ${d.color}` ); 63 | }) 64 | .on('mouseleave', () => { 65 | const allCityData = document.querySelectorAll('.city'); 66 | allCityData.forEach(data => { 67 | data.classList.remove('filter'); 68 | }) 69 | 70 | const mainHeader = document.querySelector(".main__header"); 71 | mainHeader.setAttribute("style", `color: initial`); 72 | }) 73 | } 74 | } 75 | 76 | export default Filter; -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import WorldGraph from "./world_graph"; 2 | 3 | let worldGraph; 4 | document.addEventListener("DOMContentLoaded", () => { 5 | // initialize data visualzation 6 | worldGraph = new WorldGraph("svg.graph"); 7 | 8 | // button group event listener 9 | let btnGroup = document.querySelector(".btn-group"); 10 | btnGroup.addEventListener("mousedown", e => { 11 | e.preventDefault(); 12 | let currentBtn = e.target; 13 | let currentBtnType = currentBtn.classList[1]; 14 | let currentBtnClass; 15 | if (currentBtnType === "header-graph__btn") { 16 | currentBtnClass = currentBtn.classList[0].split("-")[1]; 17 | } 18 | 19 | if (currentBtnType === "header-graph__btn") { 20 | worldGraph.updateData(currentBtnClass); 21 | let allBtns = btnGroup.querySelectorAll("a"); 22 | allBtns.forEach(btn => { 23 | btn.classList.remove("active"); 24 | }); 25 | currentBtn.classList.add("active"); 26 | } 27 | }); 28 | 29 | // modal actions 30 | const modalBg = document.querySelector('.modal-bg'); 31 | modalBg.addEventListener('click', handleModalBgClick); 32 | }); 33 | 34 | // modal close 35 | function handleModalBgClick(e) { 36 | e.stopPropagation(); 37 | let modalBg = document.querySelector(".modal-bg"); 38 | let modal = document.querySelector('.modal'); 39 | 40 | if ( 41 | e.target.classList[0] === "modal-bg" || 42 | e.target.classList[0] === "modal-close__btn-single" ) { 43 | modal.setAttribute("style", "opacity: 0; visibility: hidden"); 44 | modalBg.setAttribute("style", "opacity: 0; visibility: hidden"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/world_graph.js: -------------------------------------------------------------------------------- 1 | import { 2 | WIDTH, 3 | HEIGHT, 4 | MARGINS, 5 | ANIMATION_DELAY, 6 | ANIMATION_EASING, 7 | ANIMATION_DURATION 8 | } from "./constants"; 9 | 10 | import Chart from "./chart"; 11 | 12 | class WorldGraph extends Chart { 13 | constructor(selector) { 14 | super(selector); 15 | this.svg = d3.select(selector); 16 | this.xAxis(); 17 | this.yAxis([1, 0], "scaleLinear", 20, () => d3.format(".0%")); 18 | this.getData("graphGdp"); 19 | } 20 | 21 | getData(metric) { 22 | let that = this; 23 | d3.json("dist/data/countries.json").then(data => { 24 | that.setData(data); 25 | that.circles(metric); 26 | }); 27 | } 28 | 29 | formatOrdinal(num) { 30 | const int = parseInt(num), 31 | digits = [int % 10, int % 100], 32 | ordinals = ['st', 'nd', 'rd', 'th'], 33 | oPattern = [1, 2, 3, 4], 34 | tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; 35 | return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) 36 | ? int + ordinals[digits[0] - 1] 37 | : int + ordinals[3]; 38 | }; 39 | 40 | circles(metric) { 41 | //////////////////////// 42 | // tooltip 43 | //////////////////////// 44 | let tooltip = d3 45 | .select("body") 46 | .append("div") 47 | .style("visibility", "hidden") 48 | .attr("class", "tooltip") 49 | .style("background-color", "black") 50 | .style("border-radius", "5px") 51 | .style("padding", "10px") 52 | .style("color", "white") 53 | .style("z-index", "999999999") 54 | .style("position", "absolute") 55 | .style("display", "block"); 56 | 57 | let that = this; 58 | let showTooltip = function(d) { 59 | tooltip.transition().duration(200); 60 | tooltip 61 | .style("visibility", "visible") 62 | .html( 63 | ` 64 | Country: ${d.country} (${d.continent})
65 | Happiness Ranking: ${that.formatOrdinal(d.ranking)} 66 | ` 67 | ) 68 | .style("top", d3.event.clientY - 100 + "px") 69 | .style("left", d3.event.clientX - 160 + "px"); 70 | }; 71 | 72 | let moveTooltip = function(d) { 73 | showTooltip(d); 74 | tooltip 75 | .style("top", d3.event.clientY - 100 + "px") 76 | .style("left", d3.event.clientX - 160 + "px"); 77 | }; 78 | 79 | let hideTooltip = function(d) { 80 | tooltip 81 | .transition() 82 | .duration(200) 83 | .style("visibility", "hidden"); 84 | }; 85 | 86 | //////////////////////// 87 | // chart rendering 88 | //////////////////////// 89 | this.chart 90 | .selectAll("circle") 91 | .data(Object.values(this.data)) 92 | .enter() 93 | .append("circle") 94 | .attr( 95 | "class", 96 | d => 97 | `country ${d.class} continent-${d.continent 98 | .split(" ") 99 | .join("-")} country-bubble` 100 | ) 101 | .attr("fill", d => { 102 | if (d.continent === "Africa") { 103 | return "#7cbd1e"; 104 | } else if (d.continent === "Asia") { 105 | return "#ff1f5a"; 106 | } else if (d.continent === "North America") { 107 | return "#303481"; 108 | } else if (d.continent === "South America") { 109 | return "#ff5b44"; 110 | } else if (d.continent === "Europe") { 111 | return "#2fc5cc"; 112 | } else { 113 | return "red"; 114 | } 115 | }) 116 | .attr("opacity", ".7") 117 | .attr("stroke", "#CDCDCD") 118 | .attr("stroke-width", "2px") 119 | .attr("cx", d => { 120 | return this.xScale(d[metric] / 156) + 25; 121 | }) 122 | .on("mouseover", showTooltip) 123 | .on("mousemove", moveTooltip) 124 | .on("mouseleave", hideTooltip) 125 | .transition() 126 | .delay((d, i) => i * ANIMATION_DELAY) 127 | .duration(ANIMATION_DURATION) 128 | .ease(ANIMATION_EASING) 129 | .attr("r", d => { 130 | if (d.population > 800000000) { 131 | return d.population / 25000000; 132 | } else if (d.population > 50000000) { 133 | return d.population / 10000000; 134 | } else if (d.population > 1000000) { 135 | return d.population / 1500000; 136 | } else { 137 | return d.population / 100000; 138 | } 139 | }) 140 | .attr("cy", d => { 141 | return this.yScale(d.graphRanking / 156); 142 | }); 143 | 144 | //////////////////////// 145 | // legend 146 | //////////////////////// 147 | let continents = { 148 | AFRICA: { continent: "Africa" }, 149 | ASIA: { continent: "Asia" }, 150 | NORTH_AMERICA: { continent: "North America" }, 151 | SOUTH_AMERICA: { continent: "South America" }, 152 | EUROPE: { continent: "Europe" } 153 | }; 154 | 155 | let continentFocusOn = continentName => { 156 | this.chart 157 | .selectAll( 158 | `circle:not(.continent-${continentName.split(" ").join("-")})` 159 | ) 160 | .attr("opacity", "0.05"); 161 | }; 162 | 163 | let continentFocusOff = continentName => { 164 | this.chart 165 | .selectAll( 166 | `circle:not(.continent-${continentName.split(" ").join("-")})` 167 | ) 168 | .attr("opacity", "0.7"); 169 | }; 170 | 171 | let legend = this.chart 172 | .selectAll(".legend") 173 | .data(Object.values(continents)) 174 | .enter() 175 | .append("g") 176 | .attr("class", "legend") 177 | .attr("position", "absolute") 178 | .attr("transform", `translate(${WIDTH - 130}, ${HEIGHT - 120})`); 179 | 180 | legend 181 | .append("rect") 182 | .attr("x", 0) 183 | .attr("y", function(d, i) { 184 | return 20 * i; 185 | }) 186 | .attr("width", 20) 187 | .attr("height", 20) 188 | .style("fill", function(d) { 189 | if (d.continent === "Africa") { 190 | return "#7cbd1e"; 191 | } else if (d.continent === "Asia") { 192 | return "#ff1f5a"; 193 | } else if (d.continent === "North America") { 194 | return "#303481"; 195 | } else if (d.continent === "South America") { 196 | return "#ff5b44"; 197 | } else if (d.continent === "Europe") { 198 | return "#2fc5cc"; 199 | } else { 200 | return "red"; 201 | } 202 | }) 203 | .on("mouseover", d => continentFocusOn(d.continent)) 204 | .on("mouseleave", d => continentFocusOff(d.continent)); 205 | 206 | legend 207 | .append("text") 208 | .attr("x", 25) 209 | .attr("text-anchor", "start") 210 | .attr("dy", "1em") 211 | .attr("class", d => `legend-${d.continent.split(" ").join("-")}`) 212 | .attr("y", function(d, i) { 213 | return 20 * i; 214 | }) 215 | .text(function(d) { 216 | return d.continent; 217 | }) 218 | .attr("font-size", "12px") 219 | .on("mouseover", d => continentFocusOn(d.continent)) 220 | .on("mouseleave", d => continentFocusOff(d.continent)); 221 | 222 | legend 223 | .append("text") 224 | .attr("x", 31) 225 | .attr("dy", "-.2em") 226 | .attr("y", -10) 227 | .text("Continent") 228 | .attr("font-size", "17px") 229 | .style("text-align", "left"); 230 | } 231 | 232 | updateData(dataType) { 233 | d3.json("dist/data/countries.json").then(data => { 234 | this.chart 235 | .selectAll(".country-bubble") 236 | .transition() 237 | .duration(500) 238 | .ease(ANIMATION_EASING) 239 | .attr("cx", d => { 240 | return this.xScale(d[dataType] / 156) + 25; 241 | }); 242 | 243 | this.updateAxisLabel(dataType); 244 | }); 245 | } 246 | 247 | updateAxisLabel(type) { 248 | // xLabel 249 | let label; 250 | if (type === 'graphSocialSupport') { 251 | label = 'Social Support'; 252 | } else if (type === "graphFreedom") { 253 | label = 'Freedom'; 254 | } else if (type === "graphGenerosity") { 255 | label = 'Generosity'; 256 | } else if (type === "graphLifeExpectancy") { 257 | label = 'Life Expectancy'; 258 | } else if (type === 'graphGdp') { 259 | label = 'GDP Per Capita ($)'; 260 | } 261 | this.chart.select(".x-axis-label").text(`${label}`); 262 | } 263 | } 264 | 265 | export default WorldGraph; 266 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: './src/index.js', // We wants our entry point to this path 5 | output: { 6 | path: path.join(__dirname, 'dist'), 7 | filename: 'main.js' 8 | }, 9 | module: { 10 | rules: [{ 11 | loader: 'babel-loader', 12 | test: /\.js?$/, // This will match either .js or .jsx 13 | exclude: /node_modules/, 14 | options: { 15 | presets: ["@babel/preset-env"] 16 | }, 17 | }] 18 | }, 19 | resolve: { 20 | extensions: ['.js', '.jsx'] 21 | }, 22 | devtool: 'inline-source-map', 23 | devServer: { 24 | contentBase: path.join(__dirname, 'public') 25 | }, 26 | watch: true 27 | }; 28 | --------------------------------------------------------------------------------