Project

General

Profile

1 58825 stefania.m
import { MapCountryData } from '../../domain/map-country-data';;
2
3
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
4
import { CountryOverview } from '../../domain/overview-data';
5
6
import { DataService } from '../../services/data.service';
7
import { Router } from '@angular/router';
8
import {CountryMapData, JoinedMapData, OverviewMapData, SelectedCountry} from '../../domain/overview-map-data';
9
import { latlong } from '../../domain/countries-lat-lon';
10
import { DataHandlerService } from '../../services/data-handler.service';
11
12
import * as echarts from 'echarts';
13 60835 stefania.m
import {
14
  datasetColor, datasetBackgroundColor,
15
  datasetTooltipColor, journalsColor, journalsTooltipColor, journalsBackgroundColor, policiesColor, policiesTooltipColor,
16
  publicationColor, publicationBackgroundColor,
17
  publicationTooltipColor,
18
  repositoriesColor, repositoriesBackgroundColor,
19
  repositoriesTooltipColor,
20
} from '../../chart-palettes';
21 58825 stefania.m
22
declare var require: any;
23
24
const mapWorld = require('echarts/map/json/world.json');
25
26
@Component({
27
  selector: 'app-europe-map-overview',
28
  templateUrl: './europe-map-overview.component.html',
29
})
30
31
export class EuropeMapOverviewComponent implements OnInit {
32
33
  countries: CountryOverview[];
34
35
  @Output() emitSelectedCountry: EventEmitter<any> = new EventEmitter();
36
37
  activeView: string = 'publications';
38 60835 stefania.m
  seriesColor: string = publicationColor;
39 58825 stefania.m
  seriesName: string = 'OA publications';
40
41
  // tooltipBackgroundColor: string = '#EC4386';
42 60835 stefania.m
  tooltipBackgroundColor: string = publicationTooltipColor;
43 58825 stefania.m
  tooltipBorderColor: string = '#000';
44
45
  options = {};
46
47
  overviewMapData: OverviewMapData;
48
49
  countriesLatLong = latlong;
50
51
  joinedPublicationsMap: Map<string, JoinedMapData>;
52
  joinedDatasetsMap: Map<string, JoinedMapData>;
53 58853 stefania.m
  joinedRepositoriesMap: Map<string, JoinedMapData>;
54
  joinedJournalsMap: Map<string, JoinedMapData>;
55 58825 stefania.m
56
  constructor(private dataService: DataService,
57
              private dataHandlerService: DataHandlerService,
58
              private router: Router) {}
59
60
  ngOnInit(): void {
61
62
    echarts.registerMap('world', mapWorld);
63
64
    if (this.isEmbedRoute()) {
65
      const body = document.getElementsByTagName('body')[0];
66
      body.classList.remove('header_sticky');
67
    }
68
69
    this.dataService.getOverviewMapData().subscribe(
70
      rawData => {
71
        // console.log('==== Map RawData ====', rawData);
72
        this.overviewMapData = this.dataHandlerService.convertRawMapDataToMapData(rawData);
73
        this.joinedPublicationsMap = this.dataHandlerService.createJoinedPublicationsCountryMap(rawData);
74
        this.joinedDatasetsMap = this.dataHandlerService.createJoinedDatasetsCountryMap(rawData);
75 58853 stefania.m
        this.joinedRepositoriesMap = this.dataHandlerService.createJoinedRepositoriesCountryMap(rawData);
76
        this.joinedJournalsMap = this.dataHandlerService.createJoinedJournalsCountryMap(rawData);
77 58825 stefania.m
78
        // console.log('Country map data', this.overviewMapData[this.activeView]);
79
        this.loadMap(this.overviewMapData[this.activeView], this.seriesColor, this.seriesColor);
80
      },
81
      error => {
82
        console.log(error);
83
      }
84
    );
85
  }
86
87
  changeView(view: string) {
88
    this.activeView = view;
89
90
    if (this.activeView === 'publications') {
91 60835 stefania.m
      this.seriesColor = publicationColor;
92 58825 stefania.m
      this.seriesName = 'OA publications';
93 60835 stefania.m
      this.tooltipBackgroundColor = publicationTooltipColor;
94 58825 stefania.m
      this.tooltipBorderColor = '#000';
95
    } else if (this.activeView === 'datasets') {
96 60835 stefania.m
      this.seriesColor = datasetColor;
97 58825 stefania.m
      this.seriesName = 'OA datasets';
98 60835 stefania.m
      this.tooltipBackgroundColor = datasetTooltipColor;
99 58825 stefania.m
      this.tooltipBorderColor = '#000';
100
    } else if (this.activeView === 'repositories') {
101 60835 stefania.m
      this.seriesColor = repositoriesColor;
102 58825 stefania.m
      this.seriesName = 'OA repositories';
103 60835 stefania.m
      this.tooltipBackgroundColor = repositoriesTooltipColor;
104 58825 stefania.m
      this.tooltipBorderColor = '#000';
105
    } else if (this.activeView === 'journals') {
106 60835 stefania.m
      this.seriesColor = journalsColor;
107 58825 stefania.m
      this.seriesName = 'OA journals';
108 60835 stefania.m
      this.tooltipBackgroundColor = journalsTooltipColor;
109 58825 stefania.m
      this.tooltipBorderColor = '#000';
110
    } else {
111 60835 stefania.m
      this.seriesColor = policiesColor;
112 58825 stefania.m
      this.seriesName = 'OA policies';
113 60835 stefania.m
      this.tooltipBackgroundColor = policiesTooltipColor;
114 58825 stefania.m
      this.tooltipBorderColor = '#000';
115
    }
116
    this.loadMap(this.overviewMapData[view], this.seriesColor, this.seriesName);
117
  }
118
119
  loadMap(countryMapData: CountryMapData[], seriesColor: string, seriesName: string) {
120
121
    this.options = {
122
      title : {
123
        // text: 'World Population (2011)',
124
        // subtext: 'From Gapminder',
125
        left: 'center',
126
        top: 'top',
127
        textStyle: {
128
          color:  '#fff'
129
        }
130
      },
131
      responsive: true,
132
      tooltip : {
133
        trigger: 'item',
134
        // position: 'top',
135
        // formatter: '<strong>{b}</strong><br> {c2} {a}',
136
        // backgroundColor: '#f6c4d8',
137
        // borderColor: '#bf1d5e',
138
        // borderWidth: 0.2
139
      },
140
      visualMap: {
141
        show: false,
142
        min: 0,
143
        // max: max,
144
        max: 80000,
145
        inRange: {
146
          // symbolSize: [6, 60]
147
          // symbolSize: [0, 6]
148
        }
149
      },
150
      geo: {
151
        // name:  'World Population (2010)',
152
        type: 'map',
153
        map: 'world',
154
        // center: [15.2551, 54.5260],
155
        center: [14, 51],
156 60855 stefania.m
        // zoom: 4.7,
157 60861 stefania.m
        // zoom: 4.3,
158
        zoom: 6,
159 58825 stefania.m
        // roam: true,
160
        label: {
161
          emphasis: {
162
            show: false
163
          }
164
        },
165
        itemStyle: {
166
          normal: {
167
            // color: 'rgba(139,151,167,0.4)',
168
            // borderColor: '#000',
169
            borderColor: '#fff',
170
            borderWidth: 0.5,
171
            areaColor: 'rgba(139,151,167,0.6)',
172
            // areaStyle: {
173
            //   color: 'rgba(139,151,167,0.2)'
174
            // }
175
          },
176
          emphasis: {
177
            // color: 'rgba(139,151,167,0.4)',
178
            // borderColor: '#000',
179
            borderColor: '#fff',
180
            borderWidth: 0.5,
181
            areaColor: 'rgba(139,151,167,0.8)',
182
            // areaStyle: {
183
            //   color: 'rgba(139,151,167,0.2)'
184
            // }
185
          }
186
        }
187
        // itemStyle: {
188
        //   // areacolor: '#ffffff',
189
        //   // bordercolor: '#111',
190
        //   // borderWidth: 1,
191
        //   // normal: {
192
        //   //   // areacolor: '#323c48',
193
        //   //   areacolor: '#ffffff',
194
        //   //   bordercolor: '#111'
195
        //   // },
196
        //   // emphasis: {
197
        //   //   areacolor: '#2a333d'
198
        //   // }
199
        // }
200
      },
201
      series : [
202
        {
203
          type: 'scatter',
204
          coordinateSystem: 'geo',
205
          name: seriesName,
206
          label: {
207
            show: true,
208
            position: 'inside',
209
            color: '#fff',
210
            opacity: 1,
211
            // formatter: '{@[2]}',
212
            formatter: (params => {
213
              return params.data.value[2].toLocaleString();
214
            }),
215
            textBorderColor: '#000',
216
            textBorderWidth: '2',
217
            fontSize: 15
218
            // formatter: '{b}: {@score}'
219
          },
220
          // activeOpacity: 0.6,
221
          data: countryMapData.map((itemOpt) => {
222
            // console.log('itemOpt.code', itemOpt.code);
223
            return {
224
              name: itemOpt.name,
225
              value: [
226
                this.countriesLatLong.get(itemOpt.code).longitude,
227
                this.countriesLatLong.get(itemOpt.code).latitude,
228
                itemOpt.value
229
              ],
230
              // label: {
231
              //   emphasis: {
232
              //     position: 'right',
233
              //     show: true
234
              //   }
235
              // },
236
              itemStyle: {
237
                normal: {
238
                  color:  seriesColor,
239 60861 stefania.m
                  // color:  {
240
                  //   type: 'linear',
241
                  //   x: 0,
242
                  //   y: 0,
243
                  //   x2: 0,
244
                  //   y2: 1,
245
                  //   colorStops: [{
246
                  //     offset: 0, color: '#A1AAB8' // color at 0% position
247
                  //   }, {
248
                  //     offset: 1, color: seriesColor // color at 100% position
249
                  //   }],
250
                  //   global: false // false by default
251
                  // },
252 58825 stefania.m
                  // color:  '#f8d5e3',
253 60861 stefania.m
                  // opacity: 0.5,
254 58825 stefania.m
                  borderColor: seriesColor,
255
                  borderWidth: 2
256
                }
257
              }
258
            };
259
          }),
260
          symbolSize: value => {
261
            // console.log('Math.sqrt(value[2]) / 1000: ' + (Math.sqrt(value[2]) / 1000) );
262
            // return Math.sqrt(value[2]) / 10;
263
            return Math.sqrt(value[2]) / 10 * this.resizeFactor(countryMapData);
264
            // return Math.sqrt(value[2]) / 10;
265
          },
266
          tooltip : {
267
            trigger: 'item',
268
            position: 'top',
269
            formatter: (params => {
270
              // console.log('params: ', params);
271
              // let bla = '<strong>' + params.data.name + '</strong><br>';
272
              // bla += params.data.value[2].toLocaleString() + ' ' + params.seriesName;
273
              // return bla;
274
              return this.createTooltip(params);
275
            }),
276
            backgroundColor: this.tooltipBackgroundColor,
277
            borderColor: this.tooltipBorderColor,
278
            borderWidth: 0.2
279
          },
280
        }
281
      ]
282
    };
283
  }
284
285
  onChartClick(event: any, type: string) {
286
    // console.log('chart event:', type, event);
287
    // console.log('country:', event.name);
288
289
    const selectedCountry: SelectedCountry = new SelectedCountry();
290
    selectedCountry.name = event.name;
291
    selectedCountry.code = this.joinedPublicationsMap.get(event.name).countryCode;
292
293
    // console.log('Selected country', selectedCountry);
294
    this.emitSelectedCountry.emit(selectedCountry);
295
  }
296
297
  // selectedCountry(countryName: string) {
298
  //   this.emitSelectedCountry.emit(countryName);
299
  // }
300
301
  isEmbedRoute() {
302
    return (this.router.url === '/overview-map-embed');
303
  }
304
305
  resizeFactor(countryMapData: CountryMapData[]) {
306
307
    let max = 0;
308
    for (const countryData of countryMapData) {
309
      if (countryData.value > max) {
310
        max = countryData.value;
311
      }
312
    }
313
    // console.log('resizeFactor', 100 / (Math.sqrt(max) / 10));
314
    return 100 / (Math.sqrt(max) / 10);
315
  }
316
317
  createTooltip(params: any) {
318
319
    // console.log('params: ', params);
320
    // console.log('params.name: ', params.name);
321
322
    let tooltip = '<div style="padding:10px">';
323
324
    tooltip += '<div class="uk-margin-small" style="font-weight: 600;">' + params.name + '</div>';
325
326
    if (this.activeView === 'publications') {
327
328
      tooltip += '<div class="numbers">';
329
      tooltip += '<div class="indicator">' +
330
        '<span class="number">' + params.data.value[2].toLocaleString() + '</span>' +
331
        '<span><i>OA publications</i> affiliated <br>to an organization in the country</span></div>';
332
333
      tooltip += '<div class="indicator uk-margin-small-top">' +
334
        '<span class="number">' + this.joinedPublicationsMap.get(params.name).deposited.toLocaleString() + '</span>' +
335
        '<span><i>OA publications</i> from <br>institutional repositories</span></div>';
336
337
      tooltip += '</div>';
338
339
    } else if (this.activeView === 'datasets') {
340
341
      tooltip += '<div class="numbers">';
342
      tooltip += '<div class="indicator">' +
343
        '<span class="number">' + params.data.value[2].toLocaleString() + '</span>' +
344
        '<span><i>OA datasets</i> affiliated <br>to an organization in the country</span></div>';
345
346
      tooltip += '<div class="indicator uk-margin-small-top">' +
347
        '<span class="number">' + this.joinedDatasetsMap.get(params.name).deposited.toLocaleString() + '</span>' +
348
        '<span><i>OA datasets</i> from <br>institutional repositories</span></div>';
349
350
      tooltip += '</div>';
351
352
    } else if (this.activeView === 'repositories') {
353
354
      tooltip += '<div class="numbers">';
355
      tooltip += '<div class="indicator">' +
356
        '<span class="number">' + params.data.value[2].toLocaleString() + '</span>' +
357
        '<span><i>repositories</i> from <br>openDOAR & re3data</span></div>';
358
359 58853 stefania.m
      tooltip += '<div class="indicator uk-margin-small-top">' +
360
        '<span class="number">' + this.joinedRepositoriesMap.get(params.name).simple.toLocaleString() + '</span>' +
361
        '<span><i>repositories</i></span></div>';
362
363 58825 stefania.m
      tooltip += '</div>';
364
365
    } else if (this.activeView === 'journals') {
366
367
      tooltip += '<div class="numbers">';
368
      tooltip += '<div class="indicator">' +
369
        '<span class="number">' + params.data.value[2].toLocaleString() + '</span>' +
370 58853 stefania.m
        '<span><i>journals</i> from DOAJ</span></div>';
371 58825 stefania.m
372 58853 stefania.m
      tooltip += '<div class="indicator uk-margin-small-top">' +
373
        '<span class="number">' + this.joinedJournalsMap.get(params.name).simple.toLocaleString() + '</span>' +
374
        '<span><i>journals</i></span></div>';
375
376 58825 stefania.m
      tooltip += '</div>';
377
378
    } else {
379
380
      tooltip += '<div class="numbers">';
381
      tooltip += '<div class="indicator">' +
382
        '<span class="number">' + params.data.value[2].toLocaleString() + '</span>' +
383
        '<span>organizations with <br><i>OA policies</i></span></div>';
384
385
      tooltip += '</div>';
386
    }
387
388
    tooltip += '</div>';
389
    return tooltip;
390
  }
391
}