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

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

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

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

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

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

    
290
  resizeFactor(countryMapData: CountryMapData[]) {
291

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

    
302
  createTooltip(params: any) {
303

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
363
    } else {
364

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

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

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