Project

General

Profile

1
import { MapCountryData } from '../../domain/map-country-data';
2

    
3
declare var require: any;
4

    
5
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
6
import { CountryOverview, OverviewData } from '../../domain/overview-data';
7

    
8
import * as Highcharts from 'highcharts';
9
import MapModule from 'highcharts/modules/map';
10
import { DataService } from '../../services/data.service';
11
import { Router } from '@angular/router';
12

    
13
const mapWorld = require('@highcharts/map-collection/custom/world.geo.json');
14
const mapEurope = require('@highcharts/map-collection/custom/europe.geo.json');
15

    
16
MapModule(Highcharts);
17

    
18
@Component({
19
  selector: 'app-map-overview',
20
  templateUrl: './countries-map-overview.component.html',
21
  // styleUrls: ['./top-menu.component.css'],
22
  encapsulation: ViewEncapsulation.None
23
})
24

    
25
export class CountriesMapOverviewComponent implements OnInit {
26
  // @Input() countries: CountryOverview[];
27

    
28
  countries: CountryOverview[];
29

    
30
  @Output() emitSelectedCountry: EventEmitter<any> = new EventEmitter();
31

    
32
  activeView: string = 'publications';
33

    
34
  Highcharts: typeof Highcharts = Highcharts;
35

    
36
  chartMapOptions: Highcharts.Options;
37

    
38
  mapCountryData: MapCountryData[] = [];
39
  seriesColor: string = '#ff9800';
40
  seriesName: string = 'OA publications';
41

    
42
  europe: string[] = [];
43

    
44
  constructor(private dataService: DataService,
45
              private router: Router) {}
46

    
47
  ngOnInit(): void {
48

    
49
    if (this.isEmbedRoute()) {
50
      const body = document.getElementsByTagName('body')[0];
51
      body.classList.remove('header_sticky');
52
    }
53

    
54
    this.dataService.getOverviewData().subscribe(
55
      overviewData => {
56
        this.countries = overviewData.countries;
57
        this.europe = ['al', 'at', 'ba', 'be', 'by', 'bg', 'hr', 'cz', 'dk', 'ee', 'fi', 'fr', 'de', 'gr', 'hu', 'is', 'ie', 'it',
58
          'lv', 'lt', 'lu', 'mk', 'mt', 'md', 'me', 'nl', 'no', 'pl',  'pt', 'ro', 'rs', 'si',  'sk', 'es', 'se', 'ch', 'tr', 'ua', 'gb'];
59
        Highcharts.setOptions({
60
          lang: {
61
            // printChart: 'Aaaa',
62
            thousandsSep: ','
63
          }
64
        });
65
        this.loadMapCountryData();
66
        this.loadMap(this.mapCountryData, this.seriesColor, this.seriesName, this.europe);
67
      },
68
      error => {
69
        console.log(error);
70
      }
71
    );
72

    
73
    // this.Highcharts.chart.get('DE').zoomTo();
74
    // this.Highcharts.chart.mapZoom(0.2);
75
    // this.Highcharts.get('DE').zoomTo();
76
  }
77

    
78
  changeView(view: string) {
79
    this.activeView = view;
80
    this.loadMapCountryData();
81
    this.loadMap(this.mapCountryData, this.seriesColor, this.seriesName, this.europe);
82
    // this.updateMapData();
83
  }
84

    
85
  loadMapCountryData() {
86
    this.mapCountryData = [];
87
    for(let index in this.countries) {
88
      this.mapCountryData.push(this.overviewToMapData(this.countries[index]));
89
    }
90

    
91
    console.log(this.mapCountryData);
92
  }
93

    
94
  overviewToMapData(countryOverview: CountryOverview): MapCountryData {
95
    if (this.activeView === 'publications') {
96
      this.seriesColor = '#5086BA';
97
      this.seriesName = 'OA publications';
98
      return {
99
        id: countryOverview.country,
100
        country: countryOverview.country,
101
        z: countryOverview.publications.oa
102
      };
103
    } else if (this.activeView === 'datasets') {
104
      this.seriesColor = '#44653D';
105
      this.seriesName = 'OA datasets';
106
      return {
107
        id: countryOverview.country,
108
        country: countryOverview.country,
109
        z: countryOverview.datasets.oa
110
      };
111
    } else if (this.activeView === 'repositories') {
112
      this.seriesColor = '#A33C3C';
113
      this.seriesName = 'OA repositories';
114
      return {
115
        id: countryOverview.country,
116
        country: countryOverview.country,
117
        z: countryOverview.repositories.oa
118
      };
119
    } else if (this.activeView === 'journals') {
120
      this.seriesColor = '#7056AF';
121
      this.seriesName = 'OA journals';
122
      return {
123
        id: countryOverview.country,
124
        country: countryOverview.country,
125
        z: countryOverview.journals.oa
126
      };
127
    } else {
128
      this.seriesColor = '#A26C0A';
129
      this.seriesName = 'OA policies';
130
      return {
131
        id: countryOverview.country,
132
        country: countryOverview.country,
133
        z: countryOverview.policies.oa
134
      };
135
    }
136
  }
137

    
138
  loadMap(mapCountryData: MapCountryData[], seriesColor: string, seriesName: string, countryCodes: string[]) {
139
    this.chartMapOptions = {
140
      chart: {
141
        map: mapWorld,
142
        // map: mapEurope,
143
        events: {
144
          load: function() {
145
            this.series[0].data = this.series[0].data.map((el) => {
146
              if (countryCodes.includes(el['hc-key'])) {
147
                el.color = 'rgba(139,151,167,0.6)';
148
                return el;
149
              }
150
              return el;
151
            });
152
            this.update({
153
              series: [{
154
                data: this.series[0].data as Highcharts.SeriesMapbubbleDataOptions,
155
              } as Highcharts.SeriesMapbubbleOptions]
156
            });
157
            // this.mapZoom(0.24, 4518.24, -8188.36);
158
            this.mapZoom(0.24, this.get('Germany')['x'], this.get('Germany')['y']);
159
          },
160
          click: event => {
161
            if (event.target.hasOwnProperty('point')) {
162
              console.log(event.target['point']['name']);
163
              // this.countrySelected(event.target['point']['name']);
164
            }
165
          }
166
        }
167
      },
168
      lang: {
169
        thousandsSep: ',',
170
        decimalPoint: '.'
171
      },
172
      title: {
173
        text: ''
174
      },
175
      plotOptions: {
176
        series: {
177
          cursor: 'pointer',
178
          events: {
179
            click: event => {
180
              this.countrySelected(event.point.name);
181
            }
182
          }
183
        }
184
      },
185
      // subtitle: {
186
      //   text: 'Source map: <a href="http://code.highcharts.com/mapdata/custom/world.js">World, Miller projection, medium resolution</a>'
187
      // },
188
      // mapNavigation: {
189
      //   enabled: true,
190
      //   buttonOptions: {
191
      //     alignTo: 'spacingBox'
192
      //   }
193
      // },
194
      legend: {
195
        enabled: false
196
      },
197
      // colorAxis: {
198
      //   min: 0
199
      // },
200
      series: [{
201
        name: 'Countries',
202
        borderColor: '#fff',
203
        negativeColor: 'rgba(139,151,167,0.2)',
204
        enableMouseTracking: false,
205
        type: 'map'
206
        }, {
207
        name: seriesName,
208
        type: 'mapbubble',
209
        color: seriesColor,
210
        marker: {
211
          fillOpacity: 0.6,
212
          // states: {
213
          //   hover: {
214
          //     fillOpacity: 0.9
215
          //   }
216
          // }
217
        },
218
        joinBy: ['name', 'country'],
219
        states: {
220
          hover: {
221
            brightness: 0.7,
222
            borderWidth: 7
223
            // color: '#a4edba',
224
            // borderColor: 'gray'
225
          }
226
        },
227
        data : mapCountryData as Highcharts.SeriesMapbubbleDataOptions,
228
        dataLabels: {
229
          enabled: true,
230
          style: {
231
            color: '#fff',
232
            fontSize: '13px',
233
            fontWeight: 'bold',
234
            // textOutline: '1px #a1a1a1'
235
            textOutline: '1px #000'
236
          },
237
          allowOverlap: true,
238
          formatter: function() {
239
            // return this.point.z.toFixed(1) + '%';
240
            return this.point['z'].toLocaleString();
241
          }
242
        },
243
        // minSize: 4,
244
        // maxSize: '12%',
245
        tooltip: {
246
          headerFormat: '<span style="font-size: 120%; font-weight: bold; margin-bottom: 15px">{point.key}</span><br>',
247
          // pointFormat: '{point.properties.name}: {point.z:.1f}%'
248
          pointFormat: '{point.z} {series.name}',
249
        }
250
      } as Highcharts.SeriesMapbubbleOptions]
251
    };
252
  }
253

    
254
  countrySelected(countryName: string) {
255
    this.emitSelectedCountry.emit(countryName);
256
  }
257

    
258
  isEmbedRoute() {
259
    return (this.router.url === '/overview-map-embed');
260
  }
261
}
(2-2/8)