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,
|
15
|
datasetTooltipColor, journalsColor, journalsTooltipColor, journalsBackgroundColor, policiesColor, policiesTooltipColor,
|
16
|
publicationColor,
|
17
|
publicationTooltipColor,
|
18
|
repositoriesColor,
|
19
|
repositoriesTooltipColor,
|
20
|
gradientStartColor
|
21
|
} from '../../chart-palettes';
|
22
|
|
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
|
private gradientStartColor = gradientStartColor;
|
35
|
|
36
|
countries: CountryOverview[];
|
37
|
|
38
|
@Output() emitSelectedCountry: EventEmitter<any> = new EventEmitter();
|
39
|
|
40
|
activeView: string = 'publications';
|
41
|
seriesColor: string = publicationColor;
|
42
|
seriesName: string = 'OA publications';
|
43
|
|
44
|
// tooltipBackgroundColor: string = '#EC4386';
|
45
|
tooltipBackgroundColor: string = publicationTooltipColor;
|
46
|
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
|
joinedRepositoriesMap: Map<string, JoinedMapData>;
|
57
|
joinedJournalsMap: Map<string, JoinedMapData>;
|
58
|
|
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
|
this.joinedRepositoriesMap = this.dataHandlerService.createJoinedRepositoriesCountryMap(rawData);
|
79
|
this.joinedJournalsMap = this.dataHandlerService.createJoinedJournalsCountryMap(rawData);
|
80
|
|
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
|
this.seriesColor = publicationColor;
|
95
|
this.seriesName = 'OA publications';
|
96
|
this.tooltipBackgroundColor = publicationTooltipColor;
|
97
|
this.tooltipBorderColor = '#000';
|
98
|
} else if (this.activeView === 'datasets') {
|
99
|
this.seriesColor = datasetColor;
|
100
|
this.seriesName = 'OA datasets';
|
101
|
this.tooltipBackgroundColor = datasetTooltipColor;
|
102
|
this.tooltipBorderColor = '#000';
|
103
|
} else if (this.activeView === 'repositories') {
|
104
|
this.seriesColor = repositoriesColor;
|
105
|
this.seriesName = 'OA repositories';
|
106
|
this.tooltipBackgroundColor = repositoriesTooltipColor;
|
107
|
this.tooltipBorderColor = '#000';
|
108
|
} else if (this.activeView === 'journals') {
|
109
|
this.seriesColor = journalsColor;
|
110
|
this.seriesName = 'OA journals';
|
111
|
this.tooltipBackgroundColor = journalsTooltipColor;
|
112
|
this.tooltipBorderColor = '#000';
|
113
|
} else {
|
114
|
this.seriesColor = policiesColor;
|
115
|
this.seriesName = 'OA policies';
|
116
|
this.tooltipBackgroundColor = policiesTooltipColor;
|
117
|
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
|
// zoom: 4.7,
|
160
|
zoom: 4.3,
|
161
|
// zoom: 6,
|
162
|
// 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
|
// color: {
|
243
|
// type: 'linear',
|
244
|
// x: 0,
|
245
|
// y: 0,
|
246
|
// x2: 0,
|
247
|
// y2: 1,
|
248
|
// colorStops: [{
|
249
|
// offset: 0, color: gradientStartColor // color at 0% position
|
250
|
// }, {
|
251
|
// offset: 1, color: seriesColor // color at 100% position
|
252
|
// }],
|
253
|
// global: false // false by default
|
254
|
// },
|
255
|
// color: '#f8d5e3',
|
256
|
// opacity: 0.5,
|
257
|
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
|
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
|
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
|
'<span><i>journals</i> from DOAJ</span></div>';
|
374
|
|
375
|
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
|
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
|
}
|