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