├── .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 | 
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 |
20 |
21 |
22 |
World Happiness Report
24 |
25 |
26 |
27 | The World Happiness Report is a landmark survey of the state of global happiness that ranks 156 countries by how happy their citizens perceive themselves to be.
28 |
29 |
30 | This year’s World Happiness Report focuses on happiness and the community : how happiness has evolved over the past
31 | dozen years, with a focus on the technologies, social norms, conflicts and government policies that have driven
32 | those changes.
33 |
34 |
35 | This tool allows you to explore the study, customize the statistics, and share the facts.
36 |
37 |
38 |
39 |
47 |
48 |
49 |
50 |
51 |
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 |
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 |
--------------------------------------------------------------------------------