fdaudens commited on
Commit
ea08229
·
verified ·
1 Parent(s): 6ee084c

Add 1 files

Browse files
Files changed (1) hide show
  1. index.html +57 -13
index.html CHANGED
@@ -181,6 +181,13 @@
181
  font-size: 12px;
182
  }
183
 
 
 
 
 
 
 
 
184
  @media (max-width: 768px) {
185
  .controls {
186
  flex-direction: column;
@@ -206,7 +213,7 @@
206
  <body>
207
  <div class="container">
208
  <h1>World Development Indicators</h1>
209
- <p class="subtitle">Life Expectancy vs. GDP per capita</p>
210
 
211
  <div class="controls">
212
  <div class="filter-buttons" id="region-buttons">
@@ -230,6 +237,7 @@
230
  </div>
231
 
232
  <div class="tooltip" id="tooltip"></div>
 
233
  </div>
234
 
235
  <script>
@@ -255,6 +263,7 @@
255
  let state = {
256
  data: null,
257
  filteredData: null,
 
258
  minYear: 1950,
259
  maxYear: 2023,
260
  currentYear: 1990,
@@ -300,18 +309,52 @@
300
  async function loadData() {
301
  try {
302
  // Load the CSV data
303
- const rawData = await d3.csv("https://huggingface.co/spaces/fdaudens/world-indicators/resolve/main/world-data.csv");
 
 
 
 
 
 
304
 
305
- // Process the data
306
- state.data = rawData.map(d => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  return {
308
  entity: d.Entity,
309
  code: d.Code,
310
  year: +d.Year,
311
- lifeExpectancy: d['Life expectancy - Sex: all - Age: 0 - Variant: estimates'] ? +d['Life expectancy - Sex: all - Age: 0 - Variant: estimates'] : null,
312
- gdpPerCapita: d['GDP per capita, PPP (constant 2021 international $)'] ? +d['GDP per capita, PPP (constant 2021 international $)'] : null,
313
- population: d['Population (historical)'] ? +d['Population (historical)'] : null,
314
- region: d['World regions according to OWID'] || 'Unknown'
 
 
 
315
  };
316
  }).filter(d =>
317
  d.lifeExpectancy !== null &&
@@ -320,7 +363,7 @@
320
  );
321
 
322
  // Filter out any invalid data points
323
- state.data = state.data.filter(d =>
324
  !isNaN(d.year) &&
325
  !isNaN(d.lifeExpectancy) &&
326
  !isNaN(d.gdpPerCapita) &&
@@ -529,7 +572,7 @@
529
  ]);
530
 
531
  // Update axes
532
- const xAxis = d3.axisBottom(state.x).ticks(5, ".0f");
533
  const yAxis = d3.axisLeft(state.y);
534
 
535
  state.svg.select(".x-axis")
@@ -574,8 +617,9 @@
574
  .html(`
575
  <strong>${d.entity}</strong><br>
576
  Year: ${d.year}<br>
 
577
  Life Expectancy: ${d.lifeExpectancy.toFixed(1)} years<br>
578
- GDP per capita: $${d.gdpPerCapita.toFixed(2)}<br>
579
  Population: ${d3.format(",.0f")(d.population)}
580
  `)
581
  .style("left", (event.pageX + 10) + "px")
@@ -587,7 +631,7 @@
587
 
588
  newCircles.append("circle")
589
  .attr("r", 0)
590
- .attr("fill", d => config.regions[d.region].color)
591
  .attr("opacity", 0.7)
592
  .transition(t)
593
  .attr("r", d => state.size(d.population))
@@ -603,7 +647,7 @@
603
  })
604
  .select("circle")
605
  .attr("r", d => state.size(d.population))
606
- .attr("fill", d => config.regions[d.region].color);
607
 
608
  // Add country labels for larger bubbles
609
  circles.selectAll("text").remove();
 
181
  font-size: 12px;
182
  }
183
 
184
+ .disclaimer {
185
+ text-align: center;
186
+ font-size: 12px;
187
+ color: #7f8c8d;
188
+ margin-top: 15px;
189
+ }
190
+
191
  @media (max-width: 768px) {
192
  .controls {
193
  flex-direction: column;
 
213
  <body>
214
  <div class="container">
215
  <h1>World Development Indicators</h1>
216
+ <p class="subtitle">Life Expectancy vs. GDP per capita (1950-2023)</p>
217
 
218
  <div class="controls">
219
  <div class="filter-buttons" id="region-buttons">
 
237
  </div>
238
 
239
  <div class="tooltip" id="tooltip"></div>
240
+ <p class="disclaimer">Note: For countries missing region data in their year, we use the region from their latest available data</p>
241
  </div>
242
 
243
  <script>
 
263
  let state = {
264
  data: null,
265
  filteredData: null,
266
+ countryRegions: {}, // Store the most recent region for each country
267
  minYear: 1950,
268
  maxYear: 2023,
269
  currentYear: 1990,
 
309
  async function loadData() {
310
  try {
311
  // Load the CSV data
312
+ const rawData = await d3.csv("world-data.csv");
313
+
314
+ // First pass: Create a lookup table for country regions from the most recent data
315
+ const latestYearData = {};
316
+
317
+ // Find all unique entities
318
+ const entities = new Set(rawData.map(d => d.Entity));
319
 
320
+ // For each entity, find the most recent year that has region data
321
+ entities.forEach(entity => {
322
+ // Get all records for this entity, sorted by year (descending)
323
+ const entityData = rawData
324
+ .filter(d => d.Entity === entity)
325
+ .sort((a, b) => b.Year - a.Year);
326
+
327
+ // Find the first record with region data
328
+ const latestDataWithRegion = entityData.find(d =>
329
+ d['World regions according to OWID'] && d['World regions according to OWID'] !== ""
330
+ );
331
+
332
+ if (latestDataWithRegion) {
333
+ latestYearData[entity] = latestDataWithRegion['World regions according to OWID'];
334
+ } else {
335
+ // Fallback if no region data exists at all
336
+ latestYearData[entity] = 'Unknown';
337
+ }
338
+ });
339
+
340
+ // Process the data with region fallback
341
+ const processedData = rawData.map(d => {
342
+ // Use the region from our lookup table as fallback
343
+ const region = d['World regions according to OWID'] ||
344
+ latestYearData[d.Entity] ||
345
+ 'Unknown';
346
+
347
  return {
348
  entity: d.Entity,
349
  code: d.Code,
350
  year: +d.Year,
351
+ lifeExpectancy: d['Life expectancy - Sex: all - Age: 0 - Variant: estimates'] ?
352
+ +d['Life expectancy - Sex: all - Age: 0 - Variant: estimates'] : null,
353
+ gdpPerCapita: d['GDP per capita, PPP (constant 2021 international $)'] ?
354
+ +d['GDP per capita, PPP (constant 2021 international $)'] : null,
355
+ population: d['Population (historical)'] ?
356
+ +d['Population (historical)'] : null,
357
+ region: region
358
  };
359
  }).filter(d =>
360
  d.lifeExpectancy !== null &&
 
363
  );
364
 
365
  // Filter out any invalid data points
366
+ state.data = processedData.filter(d =>
367
  !isNaN(d.year) &&
368
  !isNaN(d.lifeExpectancy) &&
369
  !isNaN(d.gdpPerCapita) &&
 
572
  ]);
573
 
574
  // Update axes
575
+ const xAxis = d3.axisBottom(state.x).ticks(5, "$,.0f");
576
  const yAxis = d3.axisLeft(state.y);
577
 
578
  state.svg.select(".x-axis")
 
617
  .html(`
618
  <strong>${d.entity}</strong><br>
619
  Year: ${d.year}<br>
620
+ Region: ${d.region}<br>
621
  Life Expectancy: ${d.lifeExpectancy.toFixed(1)} years<br>
622
+ GDP per capita: $${d.gdpPerCapita.toLocaleString('en-US', {maximumFractionDigits: 0})}<br>
623
  Population: ${d3.format(",.0f")(d.population)}
624
  `)
625
  .style("left", (event.pageX + 10) + "px")
 
631
 
632
  newCircles.append("circle")
633
  .attr("r", 0)
634
+ .attr("fill", d => config.regions[d.region] ? config.regions[d.region].color : "#95a5a6")
635
  .attr("opacity", 0.7)
636
  .transition(t)
637
  .attr("r", d => state.size(d.population))
 
647
  })
648
  .select("circle")
649
  .attr("r", d => state.size(d.population))
650
+ .attr("fill", d => config.regions[d.region] ? config.regions[d.region].color : "#95a5a6");
651
 
652
  // Add country labels for larger bubbles
653
  circles.selectAll("text").remove();