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