Browse Source

🚧 really calculate the attractiveness index

also switch to flat mappings
jmacura 3 years ago
parent
commit
745cc551c2

+ 1 - 1
src/app/app.component.html

@@ -1,5 +1,5 @@
 <main>
-  <h1 class="pl-2">SMD - DIH integration bridge</h1>
+  <h1 class="pl-2">SDM - DIH integration bridge</h1>
   <div class="pl-2">
     <h3>About</h3>
     <p>...</p>

+ 80 - 20
src/app/graphs/sdm-dih.service.ts

@@ -3,45 +3,105 @@ import {Injectable} from '@angular/core';
 import {Subject} from 'rxjs';
 import {csv} from 'd3';
 
+import vars2facts from '../../assets/data/variables2factors.json';
+
 @Injectable({providedIn: 'root'})
 export class SdmDihService {
   readonly DATA_PATH = '../../assets/data/normalized_data.csv';
   sdmData = {};
-  aggregatedData = {};
+  //aggregatedData = {};
   dataLoads: Subject<void> = new Subject();
 
   constructor(private httpClient: HttpClient) {
-    this.loadData().then(() => this.calculateAggregation());
+    this.loadData().then(() => {
+      this.dataLoads.next();
+    });
   }
 
-  calculateAttractiveness(data) {
-    return data;
+  calcAggregatedIndex(regionData) {
+    let weightedSum = 0;
+    let sumWeight = 0;
+    for (const key of Object.keys(regionData) as any) {
+      if (key === 'MODEL' || key === 'TIME_STEP') {
+        continue;
+      }
+      const factorValues = regionData[key];
+      let sumValue = 0;
+      let n = 0;
+      for (const ds of factorValues.datasets) {
+        sumValue += ds.value;
+        n += 1;
+      }
+      weightedSum += sumValue * factorValues['weight'];
+      sumWeight += n * factorValues['weight'];
+    }
+    return weightedSum / sumWeight;
   }
 
-  calculateAggregation() {
-    console.log('aggregating...', this.sdmData);
-    for (const year of Object.keys(this.sdmData)) {
-      const yearData = this.sdmData[year];
-      const yearAggregated = this.calculateAttractiveness(yearData);
-      if (!this.aggregatedData[year]) {
-        this.aggregatedData[year] = yearAggregated;
-      } else {
-        this.aggregatedData[year].push(yearAggregated);
-      }
+  calcFactorIndex(factorData) {
+    let sumValue = 0;
+    let n = 0;
+    for (const ds of factorData.datasets) {
+      sumValue += ds.value;
+      n += 1;
     }
-    this.dataLoads.next();
+    return sumValue / n;
   }
 
   async loadData() {
-    const data = await csv(this.DATA_PATH);
+    const data = await csv(this.DATA_PATH); // Array of objects, each object represents a row, where key is a heading and value is the cell
     console.log(data);
     for (const row of data) {
-      if (!this.sdmData[row['TIME_STEP']]) {
-        this.sdmData[row['TIME_STEP']] = [row];
-      } else {
-        this.sdmData[row['TIME_STEP']].push(row);
+      const timeStep = row['TIME_STEP'];
+      const regionData = this.splitDataByFactor(row);
+      if (!this.sdmData[timeStep]) {
+        this.sdmData[timeStep] = [];
       }
+      this.sdmData[timeStep].push(regionData);
     }
     console.log(this.sdmData);
   }
+
+  /**
+   * Change format of each input row into a two-level structure where datasets are classified by factors
+   * @param inputRegionData - row as read by the CSV reader
+   * @returns data for one region in one point in time
+   */
+  splitDataByFactor(inputRegionData) {
+    const regionData = {};
+    for (const dataset of Object.keys(inputRegionData)) {
+      const datasetValue = inputRegionData[dataset];
+      if (['MODEL', 'TIME_STEP'].includes(dataset)) {
+        // just copy the MODEL and TIME_STEP
+        regionData[dataset] = datasetValue;
+        continue;
+      }
+      const factor = vars2facts[dataset];
+      // when no factor is defined for the dataset, then skip this dataset
+      if (!factor) {
+        continue;
+      }
+      if (!regionData[factor]) {
+        regionData[factor] = {
+          weight: 1,
+          datasets: [],
+        };
+      }
+      regionData[factor].datasets.push({
+        name: dataset,
+        value: parseFloat(datasetValue),
+      });
+    }
+    for (const key of Object.keys(regionData)) {
+      if (key === 'MODEL' || key === 'TIME_STEP') {
+        continue;
+      }
+      const values = regionData[key];
+      const index = this.calcFactorIndex(values);
+      values['index'] = index;
+    }
+    const aggregated = this.calcAggregatedIndex(regionData);
+    regionData['aggregated'] = aggregated;
+    return regionData;
+  }
 }

+ 4 - 4
src/app/graphs/year-graph/year-graph.component.ts

@@ -34,9 +34,9 @@ export class YearGraphComponent {
   }
 
   drawGraph(region: string) {
-    const regionData = this.sdmDihService.aggregatedData[
-      this.selectedYear
-    ].find((row) => row['MODEL'] === region);
+    const regionData = this.sdmDihService.sdmData[this.selectedYear].find(
+      (row) => row['MODEL'] === region
+    );
     const width = 200;
     const height = 200;
     //select("#year-graph-place").select("svg")?.remove();
@@ -58,7 +58,7 @@ export class YearGraphComponent {
       .attr('stroke', 'black')
       .attr('fill', (d) => {
         console.log(d);
-        return this.getColor(d['Natural_Capital']);
+        return this.getColor(d['aggregated']);
       });
     svg
       .append('text')

+ 9 - 19
src/assets/data/variables2factors.json

@@ -1,21 +1,11 @@
 {
-    "http://www.semanticweb.org/attractiveness/anthropic": [
-        "broadband_infrastructure_population_covered"
-    ],
-    "http://www.semanticweb.org/attractiveness/cultural": [],
-    "http://www.semanticweb.org/attractiveness/economic": [
-        "workforce_specialization",
-        "farms",
-        "tourist_visitors"
-    ],
-    "http://www.semanticweb.org/attractiveness/institutional": [],
-    "http://www.semanticweb.org/attractiveness/natural": [
-        "Natural_Capital"
-    ],
-    "http://www.semanticweb.org/attractiveness/social": [
-        "proportion_of_newcomers",
-        "shared_knowledge",
-        "social_innovation",
-        "WORKING_AGE_POPULATION"
-    ]
+  "broadband_infrastructure_population_covered": "http://www.semanticweb.org/attractiveness/anthropic",
+  "workforce_specialization": "http://www.semanticweb.org/attractiveness/economic",
+  "farms": "http://www.semanticweb.org/attractiveness/economic",
+  "tourist_visitors": "http://www.semanticweb.org/attractiveness/economic",
+  "Natural_Capital": "http://www.semanticweb.org/attractiveness/natural",
+  "proportion_of_newcomers": "http://www.semanticweb.org/attractiveness/social",
+  "shared_knowledge": "http://www.semanticweb.org/attractiveness/social",
+  "social_innovation": "http://www.semanticweb.org/attractiveness/social",
+  "WORKING_AGE_POPULATION": "http://www.semanticweb.org/attractiveness/social"
 }