Project

General

Profile

1
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
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

    
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
  seriesColor: string = publicationColor;
39
  seriesName: string = 'OA publications';
40

    
41
  // tooltipBackgroundColor: string = '#EC4386';
42
  tooltipBackgroundColor: string = publicationTooltipColor;
43
  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
  joinedRepositoriesMap: Map<string, JoinedMapData>;
54
  joinedJournalsMap: Map<string, JoinedMapData>;
55

    
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
        this.joinedRepositoriesMap = this.dataHandlerService.createJoinedRepositoriesCountryMap(rawData);
76
        this.joinedJournalsMap = this.dataHandlerService.createJoinedJournalsCountryMap(rawData);
77

    
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
      this.seriesColor = publicationColor;
92
      this.seriesName = 'OA publications';
93
      this.tooltipBackgroundColor = publicationTooltipColor;
94
      this.tooltipBorderColor = '#000';
95
    } else if (this.activeView === 'datasets') {
96
      this.seriesColor = datasetColor;
97
      this.seriesName = 'OA datasets';
98
      this.tooltipBackgroundColor = datasetTooltipColor;
99
      this.tooltipBorderColor = '#000';
100
    } else if (this.activeView === 'repositories') {
101
      this.seriesColor = repositoriesColor;
102
      this.seriesName = 'OA repositories';
103
      this.tooltipBackgroundColor = repositoriesTooltipColor;
104
      this.tooltipBorderColor = '#000';
105
    } else if (this.activeView === 'journals') {
106
      this.seriesColor = journalsColor;
107
      this.seriesName = 'OA journals';
108
      this.tooltipBackgroundColor = journalsTooltipColor;
109
      this.tooltipBorderColor = '#000';
110
    } else {
111
      this.seriesColor = policiesColor;
112
      this.seriesName = 'OA policies';
113
      this.tooltipBackgroundColor = policiesTooltipColor;
114
      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
        // zoom: 4.7,
157
        zoom: 4.3,
158
        // roam: true,
159
        label: {
160
          emphasis: {
161
            show: false
162
          }
163
        },
164
        itemStyle: {
165
          normal: {
166
            // color: 'rgba(139,151,167,0.4)',
167
            // borderColor: '#000',
168
            borderColor: '#fff',
169
            borderWidth: 0.5,
170
            areaColor: 'rgba(139,151,167,0.6)',
171
            // areaStyle: {
172
            //   color: 'rgba(139,151,167,0.2)'
173
            // }
174
          },
175
          emphasis: {
176
            // color: 'rgba(139,151,167,0.4)',
177
            // borderColor: '#000',
178
            borderColor: '#fff',
179
            borderWidth: 0.5,
180
            areaColor: 'rgba(139,151,167,0.8)',
181
            // areaStyle: {
182
            //   color: 'rgba(139,151,167,0.2)'
183
            // }
184
          }
185
        }
186
        // itemStyle: {
187
        //   // areacolor: '#ffffff',
188
        //   // bordercolor: '#111',
189
        //   // borderWidth: 1,
190
        //   // normal: {
191
        //   //   // areacolor: '#323c48',
192
        //   //   areacolor: '#ffffff',
193
        //   //   bordercolor: '#111'
194
        //   // },
195
        //   // emphasis: {
196
        //   //   areacolor: '#2a333d'
197
        //   // }
198
        // }
199
      },
200
      series : [
201
        {
202
          type: 'scatter',
203
          coordinateSystem: 'geo',
204
          name: seriesName,
205
          label: {
206
            show: true,
207
            position: 'inside',
208
            color: '#fff',
209
            opacity: 1,
210
            // formatter: '{@[2]}',
211
            formatter: (params => {
212
              return params.data.value[2].toLocaleString();
213
            }),
214
            textBorderColor: '#000',
215
            textBorderWidth: '2',
216
            fontSize: 15
217
            // formatter: '{b}: {@score}'
218
          },
219
          // activeOpacity: 0.6,
220
          data: countryMapData.map((itemOpt) => {
221
            // console.log('itemOpt.code', itemOpt.code);
222
            return {
223
              name: itemOpt.name,
224
              value: [
225
                this.countriesLatLong.get(itemOpt.code).longitude,
226
                this.countriesLatLong.get(itemOpt.code).latitude,
227
                itemOpt.value
228
              ],
229
              // label: {
230
              //   emphasis: {
231
              //     position: 'right',
232
              //     show: true
233
              //   }
234
              // },
235
              itemStyle: {
236
                normal: {
237
                  color:  seriesColor,
238
                  // color:  '#f8d5e3',
239
                  // opacity: 0.8,
240
                  borderColor: seriesColor,
241
                  borderWidth: 2
242
                }
243
              }
244
            };
245
          }),
246
          symbolSize: value => {
247
            // console.log('Math.sqrt(value[2]) / 1000: ' + (Math.sqrt(value[2]) / 1000) );
248
            // return Math.sqrt(value[2]) / 10;
249
            return Math.sqrt(value[2]) / 10 * this.resizeFactor(countryMapData);
250
            // return Math.sqrt(value[2]) / 10;
251
          },
252
          tooltip : {
253
            trigger: 'item',
254
            position: 'top',
255
            formatter: (params => {
256
              // console.log('params: ', params);
257
              // let bla = '<strong>' + params.data.name + '</strong><br>';
258
              // bla += params.data.value[2].toLocaleString() + ' ' + params.seriesName;
259
              // return bla;
260
              return this.createTooltip(params);
261
            }),
262
            backgroundColor: this.tooltipBackgroundColor,
263
            borderColor: this.tooltipBorderColor,
264
            borderWidth: 0.2
265
          },
266
        }
267
      ]
268
    };
269
  }
270

    
271
  onChartClick(event: any, type: string) {
272
    // console.log('chart event:', type, event);
273
    // console.log('country:', event.name);
274

    
275
    const selectedCountry: SelectedCountry = new SelectedCountry();
276
    selectedCountry.name = event.name;
277
    selectedCountry.code = this.joinedPublicationsMap.get(event.name).countryCode;
278

    
279
    // console.log('Selected country', selectedCountry);
280
    this.emitSelectedCountry.emit(selectedCountry);
281
  }
282

    
283
  // selectedCountry(countryName: string) {
284
  //   this.emitSelectedCountry.emit(countryName);
285
  // }
286

    
287
  isEmbedRoute() {
288
    return (this.router.url === '/overview-map-embed');
289
  }
290

    
291
  resizeFactor(countryMapData: CountryMapData[]) {
292

    
293
    let max = 0;
294
    for (const countryData of countryMapData) {
295
      if (countryData.value > max) {
296
        max = countryData.value;
297
      }
298
    }
299
    // console.log('resizeFactor', 100 / (Math.sqrt(max) / 10));
300
    return 100 / (Math.sqrt(max) / 10);
301
  }
302

    
303
  createTooltip(params: any) {
304

    
305
    // console.log('params: ', params);
306
    // console.log('params.name: ', params.name);
307

    
308
    let tooltip = '<div style="padding:10px">';
309

    
310
    tooltip += '<div class="uk-margin-small" style="font-weight: 600;">' + params.name + '</div>';
311

    
312
    if (this.activeView === 'publications') {
313

    
314
      tooltip += '<div class="numbers">';
315
      tooltip += '<div class="indicator">' +
316
        '<span class="number">' + params.data.value[2].toLocaleString() + '</span>' +
317
        '<span><i>OA publications</i> affiliated <br>to an organization in the country</span></div>';
318

    
319
      tooltip += '<div class="indicator uk-margin-small-top">' +
320
        '<span class="number">' + this.joinedPublicationsMap.get(params.name).deposited.toLocaleString() + '</span>' +
321
        '<span><i>OA publications</i> from <br>institutional repositories</span></div>';
322

    
323
      tooltip += '</div>';
324

    
325
    } else if (this.activeView === 'datasets') {
326

    
327
      tooltip += '<div class="numbers">';
328
      tooltip += '<div class="indicator">' +
329
        '<span class="number">' + params.data.value[2].toLocaleString() + '</span>' +
330
        '<span><i>OA datasets</i> affiliated <br>to an organization in the country</span></div>';
331

    
332
      tooltip += '<div class="indicator uk-margin-small-top">' +
333
        '<span class="number">' + this.joinedDatasetsMap.get(params.name).deposited.toLocaleString() + '</span>' +
334
        '<span><i>OA datasets</i> from <br>institutional repositories</span></div>';
335

    
336
      tooltip += '</div>';
337

    
338
    } else if (this.activeView === 'repositories') {
339

    
340
      tooltip += '<div class="numbers">';
341
      tooltip += '<div class="indicator">' +
342
        '<span class="number">' + params.data.value[2].toLocaleString() + '</span>' +
343
        '<span><i>repositories</i> from <br>openDOAR & re3data</span></div>';
344

    
345
      tooltip += '<div class="indicator uk-margin-small-top">' +
346
        '<span class="number">' + this.joinedRepositoriesMap.get(params.name).simple.toLocaleString() + '</span>' +
347
        '<span><i>repositories</i></span></div>';
348

    
349
      tooltip += '</div>';
350

    
351
    } else if (this.activeView === 'journals') {
352

    
353
      tooltip += '<div class="numbers">';
354
      tooltip += '<div class="indicator">' +
355
        '<span class="number">' + params.data.value[2].toLocaleString() + '</span>' +
356
        '<span><i>journals</i> from DOAJ</span></div>';
357

    
358
      tooltip += '<div class="indicator uk-margin-small-top">' +
359
        '<span class="number">' + this.joinedJournalsMap.get(params.name).simple.toLocaleString() + '</span>' +
360
        '<span><i>journals</i></span></div>';
361

    
362
      tooltip += '</div>';
363

    
364
    } else {
365

    
366
      tooltip += '<div class="numbers">';
367
      tooltip += '<div class="indicator">' +
368
        '<span class="number">' + params.data.value[2].toLocaleString() + '</span>' +
369
        '<span>organizations with <br><i>OA policies</i></span></div>';
370

    
371
      tooltip += '</div>';
372
    }
373

    
374
    tooltip += '</div>';
375
    return tooltip;
376
  }
377
}
(8-8/12)