Project

General

Profile

1
import {
2
  ChartHelper, FilterType,
3
  Indicator, IndicatorFilterUtils,
4
  IndicatorPath, IndicatorPathType, IndicatorType,
5
  SourceType,
6
  Stakeholder,
7
  SubCategory,
8
  Topic
9
} from "../openaireLibrary/monitor/entities/stakeholder";
10
import {AbstractControl, ValidatorFn, Validators} from "@angular/forms";
11
import {Option} from "../openaireLibrary/dashboard/sharedComponents/input/input.component";
12

    
13
export class StakeholderUtils {
14
  defaultProfiles = {"funder":{
15
      index_id:"ec__________::EC",
16
  index_name:     "European Commission", index_shortName:"EC"}};
17
  
18
  
19
  types: Option[] = [
20
    {value: 'funder', label: 'Funder'},
21
    {value: 'ri', label: 'Reasearch Initiative'},
22
    {value: 'project', label: 'Project'},
23
    {value: 'organization', label: 'Organization'}
24
  ];
25

    
26
  isPublic: Option[] = [
27
    {icon: 'public', value: true, label: 'Public'},
28
    {icon: 'lock', value: false, label: 'Private'},
29
  ];
30

    
31
  isActive: Option[] = [
32
    {icon: 'brightness_1', iconClass: '', value: true, label: 'Active'},
33
    {icon: 'brightness_1', value: false, label: 'Inactive'},
34
  ];
35

    
36
  isPublicIcon: Map<boolean, string> = new Map([
37
    [true, 'public'],
38
    [false, 'lock']
39
  ]);
40

    
41
  isActiveIcon: string = 'brightness_1';
42

    
43
  public createFunderFromDefaultProfile(funder: Stakeholder, defaultTopics: Topic[]): Stakeholder {
44
    funder.topics = defaultTopics;
45
    for (let topic of funder.topics) {
46
      // console.log('id:' + topic._id);
47
      topic.defaultId = topic._id;
48
      topic._id = null;
49
      // console.log('defaultId:' + topic.defaultId);
50
      for (let category of topic.categories) {
51
        category.defaultId = category._id;
52
        category._id = null;
53
        let subTokeep: SubCategory[] = [];
54
        for (let subCategory of category.subCategories) {
55
          subCategory.defaultId = subCategory._id;
56
          subCategory._id = null;
57
          if (!subCategory.recommendedFor || subCategory.recommendedFor.length == 0 || subCategory.recommendedFor.indexOf(funder.index_id) != -1) {
58
            subTokeep.push(subCategory);
59
          }
60
          for (let section of subCategory.charts) {
61
            let chartsTokeep: Indicator[] = [];
62
            section.defaultId = section._id;
63
            section.stakeholderAlias = funder.alias;
64
            section._id = null;
65
            for (let indicator of section.indicators) {
66
              indicator.defaultId = indicator._id;
67
              indicator._id = null;
68
              if (!indicator.recommendedFor || indicator.recommendedFor.length == 0 || indicator.recommendedFor.indexOf(funder.index_id) != -1) {
69
                chartsTokeep.push(indicator);
70
              }
71
              for (let indicatorPath of indicator.indicatorPaths) {
72
                if (indicatorPath.parameters) {
73
                  Object.keys(indicatorPath.parameters).forEach(key => {
74
                    //TODO check before delete
75
                    /*if (indicatorPath.parameters[key].indexOf("_funder_name_") != -1) {
76
                      indicatorPath.parameters[key] = indicatorPath.parameters[key].replace("_funder_name_", funder.index_name);
77
                    } else if (indicatorPath.parameters[key].indexOf("_funder_id_") != -1) {
78
                      indicatorPath.parameters[key] = indicatorPath.parameters[key].replace("_funder_id_", funder.index_id);
79
                    } else if (indicatorPath.parameters[key].indexOf("_fsn_") != -1) {
80
                      indicatorPath.parameters[key] = indicatorPath.parameters[key].toString().replace("_fsn_", funder.index_shortName.toLowerCase());
81
                    }*/
82
                    if (key == "index_name") {
83
                      indicatorPath.parameters[key] = funder.index_name;
84
                    } else if (key == "index_id" ) {
85
                      indicatorPath.parameters[key] = funder.index_id;
86
                    }  else if (key == "index_shortName" ) {
87
                      indicatorPath.parameters[key] =  funder.index_shortName.toLowerCase();
88
                    }
89
                  });
90
                }
91
              }
92
            }
93
            section.indicators = chartsTokeep;
94
          }
95
          for (let section of subCategory.numbers) {
96
            section.defaultId = section._id;
97
            section.stakeholderAlias = funder.alias;
98
            section._id = null;
99
            for(let indicator of section.indicators) {
100
              indicator.defaultId = indicator._id;
101
              indicator._id = null;
102
              for (let indicatorPath of indicator.indicatorPaths) {
103
               /* indicatorPath.url = indicatorPath.url.replace("index_id", encodeURIComponent(funder.index_id));
104
                indicatorPath.url = indicatorPath.url.replace("index_name",  encodeURIComponent(funder.index_name));
105
                indicatorPath.url = indicatorPath.url.replace("index_shortName", encodeURIComponent(funder.index_shortName));*/
106
                // if(indicatorPath.parameters) {
107
                //   indicatorPath.parameters.forEach((value: string, key: string) => {
108
                //     if (value.indexOf("_funder_name_")!=-1) {
109
                //       indicatorPath.parameters.set(key,value.toString().replace("_funder_name_", funder.index_name));
110
                //     }else if (value.indexOf("_fsn_")!=-1) {
111
                //       indicatorPath.parameters.set(key,value.toString().replace("_fsn_", funder.index_shortName.toLowerCase()));
112
                //     }
113
                //   });
114
                // }
115
              }
116
            }
117
          }
118

    
119
        }
120
        category.subCategories = subTokeep;
121
      }
122
    }
123
    console.log (funder)
124
    return funder;
125
  }
126

    
127
  aliasValidator(elements: any[]): ValidatorFn {
128
    return (control: AbstractControl): { [key: string]: boolean } | null => {
129
      if (control.value && elements.find(element =>
130
        element.alias === control.value
131
      )) {
132
        return {'alias': true};
133
      }
134
      return null;
135
    }
136
  }
137
  
138
  generateAlias(name: string): string {
139
    let alias = name.toLowerCase();
140
    while (alias.includes('/') || alias.includes(' ')) {
141
      alias = alias.replace(' / ', '-');
142
      alias = alias.replace('/', '-');
143
      alias = alias.replace(' ', '-');
144
    }
145
    return alias;
146
  }
147
}
148

    
149
export class IndicatorUtils {
150

    
151
  allChartTypes: Option[] = [
152
    {value: 'pie', label: 'Pie'},
153
    {value: 'table', label: 'Table'},
154
    {value: 'line', label: 'Line'},
155
    {value: 'column', label: 'Column'},
156
    {value: 'bar', label: 'Bar'},
157
    {value: 'other', label: 'Other'}
158
  ];
159
  basicChartTypes:IndicatorPathType[] =["pie", "line", "column", "bar"];
160
  defaultChartType:IndicatorPathType = "other";
161
  indicatorSizes: Option[] = [
162
    {value: 'small', label: 'Small'},
163
    {value: 'medium', label: 'Medium'},
164
    {value: 'large', label: 'Large'}
165
  ];
166

    
167
  sourceTypes: Option[]  = [
168
    {value: 'search', label: 'Search'},
169
    {value: 'statistics', label: 'Statistics'},
170
    {value: 'metrics', label: 'Metrics'},
171
    {value: 'stats-tool', label: 'Statistics tool'}
172
  ];
173
  
174
  isPublic: Option[] = [
175
    {icon: 'public', value: true, label: 'Public'},
176
    {icon: 'lock', value: false, label: 'Private'},
177
  ];
178

    
179
  isActive: Option[] = [
180
    {icon: 'brightness_1', iconClass: '', value: true, label: 'Active'},
181
    {icon: 'brightness_1', value: false, label: 'Inactive'},
182
  ];
183

    
184
  chartTypesIcons: Map<string, string> = new Map([
185
    ['pie', 'pie_chart'],
186
    ['table', 'table_chart'],
187
    ['line', 'show_chart'],
188
    ['column', 'bar_chart'],
189
    ['bar', 'notes'],
190
    ['other', 'perm_media']
191
  ]);
192
  getChartTypes(initialType){
193
    let types: Option[]= [];
194
    if(this.basicChartTypes.indexOf(initialType) != -1){
195
      (this.allChartTypes).forEach(option => {
196
        if(this.basicChartTypes.indexOf(option.value)!=-1){
197
          types.push(option);
198
        }
199
      });
200
      return types;
201
    }else if(initialType == "table") {
202
      (this.allChartTypes).forEach(option => {
203
        if (initialType == option.value) {
204
          types.push(option);
205
        }
206
      });
207
      return types;
208
    }else {
209
      return this.allChartTypes;
210
    }
211
  }
212
  isPublicIcon: Map<boolean, string> = new Map([
213
    [true, 'public'],
214
    [false, 'lock']
215
  ]);
216

    
217
  isActiveIcon: string = 'brightness_1';
218

    
219
  ignoredParameters = ['index_name','index_id','index_shortName'];
220

    
221
  parametersValidators: Map<string, any> = new Map<string, any>([
222
    ['start_year', [Validators.required, Validators.pattern('^\\d+$')]],
223
    ['end_year', [Validators.required, Validators.pattern('^\\d+$')]]
224
  ]);
225

    
226
  public getFullUrl(stakeholder:Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null): string {
227
    let replacedUrl = indicatorPath.chartObject;
228
    if (indicatorPath.parameters) {
229
      Object.keys(indicatorPath.parameters).forEach(key => {
230
        let replacedValue = indicatorPath.parameters[key];
231
        if (startYear && key == "start_year" && indicatorPath.filters["start_year"]) {
232
          replacedValue = (replacedValue < startYear) ? startYear : replacedValue;
233
        }
234
        if (endYear && key == "end_year" && indicatorPath.filters["end_year"]) {
235
          replacedValue = (replacedValue > endYear) ? endYear : replacedValue;
236
        }
237
        if (key == "index_id") {
238
          replacedValue = stakeholder.index_id;
239
        }
240
        if (key == "index_name") {
241
          replacedValue = stakeholder.index_name;
242
        }
243
        if (key == "index_shortName") {
244
          replacedValue = stakeholder.index_shortName.toLowerCase();
245
        }
246

    
247
        replacedUrl = replacedUrl.split(ChartHelper.prefix + key + ChartHelper.suffix).join(replacedValue)
248
      });
249
    }
250
    if (indicatorPath.chartObject) {
251
      if (fundingL0 && indicatorPath.filters["fundingL0"]) {
252
        let newJsonObject = JSON.parse(replacedUrl);
253
        for (let queries of this.getQueryObjectName(newJsonObject)?newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)]:newJsonObject[this.getDescriptionObjectName(newJsonObject)]) {
254
          if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) {
255
            queries["query"]["filters"] = [];
256
          }
257
          //TODO check how it works if the query already has a filter
258
          queries["query"]["filters"].push(JSON.parse(indicatorPath.filters["fundingL0"].replace(ChartHelper.prefix + "fundingL0" + ChartHelper.suffix, fundingL0)));
259
        }
260
        replacedUrl = JSON.stringify(newJsonObject);
261
      }
262
      if (startYear && indicatorPath.filters["start_year"]) {
263
        let newJsonObject = JSON.parse(replacedUrl);
264

    
265
        for (let queries of this.getQueryObjectName(newJsonObject)?newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)]:newJsonObject[this.getDescriptionObjectName(newJsonObject)]) {
266
          if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) {
267
            queries["query"]["filters"] = [];
268
          }
269
          //TODO check how it works if the query already has a filter
270
          queries["query"]["filters"].push(JSON.parse(indicatorPath.filters["start_year"].replace(ChartHelper.prefix + "start_year" + ChartHelper.suffix, startYear)));
271
        }
272
        replacedUrl = JSON.stringify(newJsonObject);
273
      }
274
      if (endYear && indicatorPath.filters["end_year"]) {
275
        let newJsonObject = JSON.parse(replacedUrl);
276
        for (let queries of this.getQueryObjectName(newJsonObject)?newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)]:newJsonObject[this.getDescriptionObjectName(newJsonObject)]) {
277
          if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) {
278
            queries["query"]["filters"] = [];
279
          }
280
          //TODO check how it works if the query already has a filter
281
          queries["query"]["filters"].push(JSON.parse(indicatorPath.filters["end_year"].replace(ChartHelper.prefix + "end_year" + ChartHelper.suffix, endYear)));
282
        }
283
        replacedUrl = JSON.stringify(newJsonObject);
284
      }
285

    
286
    }
287
    //For numbers
288
    if(indicatorPath.url.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) !=- 1){
289
      indicatorPath.url = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_id))
290
    }
291
    if(indicatorPath.url.indexOf(ChartHelper.prefix + 'index_name' + ChartHelper.suffix) !=- 1){
292
      indicatorPath.url = replacedUrl.split(ChartHelper.prefix + 'index_name' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_name))
293
    }
294
    if(indicatorPath.url.indexOf(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix) !=- 1){
295
      indicatorPath.url = replacedUrl.split(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_shortName))
296
    }
297
    return indicatorPath.url + encodeURIComponent(replacedUrl);
298
  }
299
  public getFullUrlWithFilters(stakeholder:Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null, isNumber:boolean=false): string {
300
    indicatorPath.filtersApplied = 0;
301
    let replacedUrl = indicatorPath.chartObject?indicatorPath.chartObject:indicatorPath.url;
302
    if (indicatorPath.parameters) {
303
      Object.keys(indicatorPath.parameters).forEach(key => {
304
        let replacedValue = indicatorPath.parameters[key];
305
        if (startYear && key == "start_year") {
306
          replacedValue = (replacedValue < startYear) ? startYear : replacedValue;
307
        }
308
        if (endYear && key == "end_year") {
309
          replacedValue = (replacedValue > endYear) ? endYear : replacedValue;
310
        }
311
        if (key == "index_id") {
312
          replacedValue = stakeholder.index_id;
313
        }
314
        if (key == "index_name") {
315
          replacedValue = stakeholder.index_name;
316
        }
317
        if (key == "index_shortName") {
318
          replacedValue = stakeholder.index_shortName.toLowerCase();
319
        }
320

    
321
        replacedUrl = replacedUrl.split(ChartHelper.prefix + key + ChartHelper.suffix).join(replacedValue)
322
      });
323
    }
324
    if (fundingL0) {
325
      if(indicatorPath.source == "stats-tool" && indicatorPath.chartObject) {
326
        let filterResults = this.addFilter(replacedUrl, 'fundingL0', fundingL0);
327
        replacedUrl = filterResults.url;
328
        indicatorPath.filtersApplied += filterResults.filtersApplied;
329
      }
330
    }
331
    if (startYear) {
332
      if(indicatorPath.source == "stats-tool" && indicatorPath.chartObject) {
333
        let filterResults =  this.addFilter(replacedUrl, 'start_year', startYear);
334
        replacedUrl = filterResults.url;
335
        indicatorPath.filtersApplied += filterResults.filtersApplied;
336
      }
337
    }
338
    if (endYear ) {
339
      if(indicatorPath.source == "stats-tool" && indicatorPath.chartObject) {
340
        let filterResults = this.addFilter(replacedUrl, 'end_year', endYear);
341
        replacedUrl = filterResults.url;
342
        indicatorPath.filtersApplied += filterResults.filtersApplied;
343
      }
344
    }
345

    
346
    //For numbers
347
    if (replacedUrl.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) {
348
      replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_id))
349
    }
350
    if (replacedUrl.indexOf(ChartHelper.prefix + 'index_name' + ChartHelper.suffix) != -1) {
351
      replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_name' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_name))
352
    }
353
    if (replacedUrl.indexOf(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix) != -1) {
354
      replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_shortName))
355
    }
356

    
357
    return (indicatorPath.chartObject?indicatorPath.url + encodeURIComponent(replacedUrl):replacedUrl);
358

    
359
  }
360
  private  addFilter(replacedUrl, filterType:FilterType, filterValue){
361
    let newJsonObject = JSON.parse(replacedUrl);
362
    let filterApplied:boolean = false;
363
    let queryIndex = 0;
364
    for (let queries of this.getQueryObjectName(newJsonObject)?newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)]:newJsonObject[this.getDescriptionObjectName(newJsonObject)]) {
365

    
366
      if(queries["query"]["name"] && !queries["query"]["select"]){
367

    
368
        if(queries["query"]["name"].indexOf("monitor.")==-1 || !queries["query"]["parameters"]){
369
          continue;
370
        }
371
        filterApplied = true;
372
        if(filterType == 'fundingL0') {
373
          let paramFields = queries["query"]["name"].split(".").slice(3);
374
                    let filterPosition = queries["query"]["name"].split(".").indexOf(filterType == "fundingL0" ? 'fl0' : filterType) ;
375
          if (filterPosition != -1) {
376
            //TODO double check if we need to override if the fl0 is already filtered
377
            filterPosition -=3;
378
            if(paramFields.length == queries["query"]["parameters"].length ){
379
              //ok
380
              queries["query"]["parameters"][filterPosition] = filterValue;
381
            }else if((paramFields.length + 2) == queries["query"]["parameters"].length || (paramFields.length*2 + 4) == queries["query"]["parameters"].length){
382
              queries["query"]["parameters"][filterPosition + 2]=filterValue;
383
              filterApplied = true;
384
            }
385
            if((paramFields.length*2 + 4) == queries["query"]["parameters"].length){
386
                 queries["query"]["parameters"][(2* filterPosition) + 5]=filterValue;
387
            }
388
          } else {
389
            if((paramFields.length*2 + 4) == queries["query"]["parameters"].length){
390
              queries["query"]["parameters"].splice(paramFields.length + 1, 0, filterValue);
391
            }
392
            queries["query"]["name"] = queries["query"]["name"] + ".fl0";
393
            queries["query"]["parameters"].push(filterValue);
394
          }
395
        }else{
396
          let paramFields = queries["query"]["name"].split(".").slice(3);
397
          // console.debug("Field Params length:" + paramFields.length)
398
          // console.debug(paramFields)
399
          // console.debug("Parameters length:" + queries["query"]["parameters"].length)
400
          console.debug("Parameters length:" + queries["query"]["parameters"].length)
401

    
402
          if((paramFields.length + 2) == queries["query"]["parameters"].length || (paramFields.length*2 + 4) == queries["query"]["parameters"].length){
403
            console.debug("update param position 0,1" )
404
           if(filterType == "start_year"){
405
             queries["query"]["parameters"][0]=filterValue;
406
           }else if(filterType == "end_year"){
407
             queries["query"]["parameters"][1]=filterValue;
408
           }
409
          }
410
          if((paramFields.length*2 + 4) == queries["query"]["parameters"].length){
411
            console.debug("update param position "+(paramFields.length + 2) + "," +(paramFields.length + 3) )
412
            if(filterType == "start_year"){
413
              queries["query"]["parameters"][paramFields.length + 2]=filterValue;
414
            }else if(filterType == "end_year"){
415
              queries["query"]["parameters"][paramFields.length + 3]=filterValue;
416
            }
417
          }
418
        }
419
        // console.debug(queries["query"])
420
        // it is a name query
421
        continue;
422
      }
423
      if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) {
424
        queries["query"]["filters"] = [];
425
      }
426
      let field = queries["query"]["select"][0]["field"];
427
      let filterString =  IndicatorFilterUtils.getFilter(field,filterType);
428
      if(filterString){
429
        let filter = JSON.parse(filterString);
430
        let filterposition = IndicatorFilterUtils.filterIndexOf(filter,queries["query"]["filters"])
431
        if(filterposition){
432
          if(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] != filter['groupFilters'][0]["values"][0].replace(ChartHelper.prefix + filterType + ChartHelper.suffix, filterValue)){
433
            //change filter value
434
            // queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filter['groupFilters'][0]["values"][0].replace(ChartHelper.prefix + filterType + ChartHelper.suffix, filterValue);
435
            //add user filter value
436
            // queries["query"]["filters"].push(JSON.parse(filterString.replace(ChartHelper.prefix + filterType + ChartHelper.suffix, filterValue)));
437
            // update colors
438
            //if noit a pie, map and chart has more than one query
439
            //
440
            if(!newJsonObject.hasOwnProperty("mapDescription") && queries["type"]!="pie" && (this.getQueryObjectName(newJsonObject)?newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)].length:newJsonObject[this.getDescriptionObjectName(newJsonObject)].length) >1) {
441
              let activeColors = ["#7CB5EC", "#434348", "#8bbc21", "#910000", "#1aadce", "#492970", "#f28f43", "#77a1e5", "#c42525", "#a6c96a"];
442
              let inActiveColors = ["#E4EFFB", "#D8D8D9", "#8bbc21", "#910000", "#1aadce", "#492970", "#f28f43", "#77a1e5", "#c42525", "#a6c96a"];
443
              if (!newJsonObject[this.getDescriptionObjectName(newJsonObject)]["colors"]) {
444
                newJsonObject[this.getDescriptionObjectName(newJsonObject)]["colors"] = activeColors;
445
              }
446
              newJsonObject[this.getDescriptionObjectName(newJsonObject)]["colors"][queryIndex] = inActiveColors[queryIndex];
447
              filterApplied = true;
448
            }
449
          }else{
450
            filterApplied = true;
451
          }
452
        }else {
453
          queries["query"]["filters"].push(JSON.parse(filterString.replace(ChartHelper.prefix + filterType + ChartHelper.suffix, filterValue)));
454
          filterApplied = true;
455
        }
456
      }
457
      queryIndex++;
458
    }
459
    return  { "url":JSON.stringify(newJsonObject), "filtersApplied":(filterApplied)?1:0};
460
  }
461

    
462
  generateIndicatorByForm(form: any, indicatorPaths: IndicatorPath[], type:IndicatorType, addParameters:boolean = true ): Indicator {
463
    let indicator: Indicator = new Indicator(form.name, form.description, type,
464
      form.width, form.isActive, form.isPublic, indicatorPaths, form.defaultId);
465
    indicator._id = form._id;
466
    form.indicatorPaths.forEach((indicatorPath, index) => {
467
      indicator.indicatorPaths[index].type = indicatorPath.type;
468
      if(addParameters) {
469
        indicatorPath.parameters.forEach(parameter => {
470
          indicator.indicatorPaths[index].parameters[parameter.key] = parameter.value;
471
          if (parameter.key === 'type') {
472
            indicator.indicatorPaths[index].type = parameter.value;
473
          }
474
        });
475
      }
476
    });
477
    return indicator;
478
  }
479
  generateIndicatorByNumberUrl(source: SourceType, url: string, stakeholder:Stakeholder, jsonPath = []): IndicatorPath {
480
    let indicatorPath = new IndicatorPath(null, source, url, null, jsonPath);
481
    if (source === 'stats-tool') {
482
      indicatorPath.url = url.split("json=")[0] + "json=";
483
      indicatorPath.url = indicatorPath.url.split("/")[indicatorPath.url.split("/").length - 1];
484
      indicatorPath.chartObject = decodeURIComponent(url.indexOf("json=")!=-1?url.split("json=")[1]:"");
485
      let chart = JSON.parse(indicatorPath.chartObject);
486
      this.extractStakeHolders(chart, indicatorPath, stakeholder);
487
      // this.addResultFilters(chart, indicatorPath);
488
    }else {
489
      try {
490
        if (url.indexOf(encodeURIComponent(stakeholder.index_id)) !== -1) {
491
          url = url.split(encodeURIComponent(stakeholder.index_id)).join(ChartHelper.prefix + "index_id" + ChartHelper.suffix);
492
        }
493
        if (url.indexOf(encodeURIComponent(stakeholder.index_name)) !== -1) {
494
          url = url.split(encodeURIComponent(stakeholder.index_name)).join(ChartHelper.prefix + "index_name" + ChartHelper.suffix);
495
        }
496
        if (url.indexOf(encodeURIComponent(stakeholder.index_shortName)) !== -1) {
497
          url = url.split(encodeURIComponent(stakeholder.index_shortName)).join(ChartHelper.prefix + "index_shortName" + ChartHelper.suffix);
498
        }
499
        indicatorPath.url = url;
500
      } catch (e) {
501
        console.error(e);
502
      }
503
    }
504
    return indicatorPath;
505
  }
506
  generateIndicatorByChartUrl(source: SourceType, url: string, type: IndicatorPathType = null, stakeholder:Stakeholder): IndicatorPath {
507
    let indicatorPath = new IndicatorPath(type, source, "", "", []);
508
    try {
509
      if (source === 'stats-tool') {
510
        indicatorPath.url = url.split("json=")[0] + "json=";
511
        indicatorPath.url = indicatorPath.url.split("/")[indicatorPath.url.split("/").length - 1];
512
        indicatorPath.chartObject = decodeURIComponent(url.split("json=")[1]);
513
        let chart = JSON.parse(indicatorPath.chartObject);
514
        // console.debug(indicatorPath);
515
        if (indicatorPath.url == "chart?json=") {
516

    
517
          if (chart["library"] && (chart["library"] == "HighCharts" || chart["library"] == "eCharts" || chart["library"] == "HighMaps" )) {
518
            indicatorPath.type = this.extractType(chart, indicatorPath);
519
          } else {
520
            indicatorPath.type = this.defaultChartType;
521
          }
522

    
523
          this.extractTitle(chart, indicatorPath);
524
          this.extractSubTitle(chart, indicatorPath);
525
          this.extractXTitle(chart, indicatorPath);
526
          this.extractYTitle(chart, indicatorPath);
527
        }else if(indicatorPath.url == "table?json="){
528
          indicatorPath.type = "table";
529
        }
530
        if (indicatorPath.url == "chart?json=" || indicatorPath.url == "table?json=") {
531
          // common for tables and other chart types
532
          this.extractDataTitle(chart, indicatorPath);
533
          this.parameterizeDefaultQuery(chart, indicatorPath, stakeholder);
534
          this.extractStakeHolders(chart, indicatorPath, stakeholder);
535
          this.extractStartYear(chart, indicatorPath);
536
          this.extractEndYear(chart, indicatorPath);
537
          indicatorPath.chartObject = JSON.stringify(chart);
538
        }
539
      } else if (source === 'old') {
540
        indicatorPath.url = url.split("data=")[0].split("/stats/")[1] + "data=";
541
        indicatorPath.chartObject = decodeURIComponent(url.split("data=")[1].split("&")[0]);
542
        indicatorPath.type = type;
543
        let chart = JSON.parse(indicatorPath.chartObject);
544
        this.extractOldToolTitle(chart, indicatorPath);
545
        this.extractOldToolXTitle(chart, indicatorPath);
546
        this.extractOldToolYTitle(chart, indicatorPath);
547
        indicatorPath.chartObject = JSON.stringify(chart);
548
      } else {
549
        indicatorPath.url = url;
550
        indicatorPath.type = type;
551
      }
552
    }catch(e){
553
      console.error(e);
554
      indicatorPath.url = url;
555
      indicatorPath.type = type;
556
    }
557
    // console.debug(indicatorPath.parameters);
558
    // console.debug(indicatorPath.chartObject);
559
    if(indicatorPath.type == null){
560
      indicatorPath.type = this.defaultChartType;
561
    }
562
    return indicatorPath;
563
  }
564
  private getQueryObjectName(obj){
565
    if((obj[this.getDescriptionObjectName(obj)]).hasOwnProperty("queriesInfo")){
566
        return "queriesInfo";
567
    }else if((obj[this.getDescriptionObjectName(obj)]).hasOwnProperty("queries")) {
568
      return "queries";
569
    }
570
  }
571
  private getDescriptionObjectName(obj){
572
    if(obj.hasOwnProperty("mapDescription")){
573
      return "mapDescription";
574
    }else if(obj.hasOwnProperty("chartDescription")) {
575
      return "chartDescription";
576
    }else if(obj.hasOwnProperty("tableDescription") ){
577
      return "tableDescription";
578
    }else if(obj.hasOwnProperty("series") ){
579
      return "series";
580
    }
581
    }
582
  private extractType(obj, indicatorPath: IndicatorPath): IndicatorPathType {
583
    let type = (obj[this.getDescriptionObjectName(obj)] && obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)][0]["type"])?obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)][0]["type"]:"";
584
    if (this.basicChartTypes.indexOf(type) == -1) {
585
      type = this.defaultChartType;
586
    } else {
587
      obj[this.getDescriptionObjectName(obj)]["queries"][0]["type"] = ChartHelper.prefix + "type" + ChartHelper.suffix;
588
      indicatorPath.parameters['type'] = type;
589
    }
590
    return type;
591
  }
592
  private extractStakeHolders(obj, indicatorPath: IndicatorPath, stakeholder:Stakeholder) {
593
    this.extractFunder(obj, indicatorPath, stakeholder);
594
    this.extractRI(obj, indicatorPath, stakeholder);
595
    this.extractOrganization(obj, indicatorPath, stakeholder);
596
  }
597
  private extractFunder(obj, indicatorPath: IndicatorPath, stakeholder:Stakeholder) {
598
    if(stakeholder.type != "funder"){
599
      return;
600
    }
601
    for (let query of this.getQueryObjectName(obj)?obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]:obj[this.getDescriptionObjectName(obj)]) {
602
      if (!query["query"]["filters"]) {
603
        return;
604
      }
605
      for (let filter of query["query"]["filters"]) {
606
        if (filter["groupFilters"][0]["field"].indexOf(".funder") != -1) {
607
          filter["groupFilters"][0]["values"][0] = ChartHelper.prefix + "index_name" + ChartHelper.suffix;
608
          indicatorPath.parameters["index_name"] = stakeholder.index_name;
609
        }else  if (filter["groupFilters"][0]["field"].indexOf(".funder.id") != -1) {
610
          filter["groupFilters"][0]["values"][0] = ChartHelper.prefix + "index_shortName" + ChartHelper.suffix;
611
          indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName;
612
        }
613
      }
614
    }
615
  }
616

    
617
  private extractRI(obj, indicatorPath: IndicatorPath, stakeholder:Stakeholder) {
618
    if(stakeholder.type != "ri"){
619
      return;
620
    }
621
    for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) {
622
      if (!query["query"]["filters"]) {
623
        return;
624
      }
625
      for (let filter of query["query"]["filters"]) {
626
        if (filter["groupFilters"][0]["field"].indexOf(".context.name") != -1) {
627
          filter["groupFilters"][0]["values"][0] = ChartHelper.prefix + "index_name" + ChartHelper.suffix;
628
          indicatorPath.parameters["index_name"] = stakeholder.index_name;
629
        }else  if (filter["groupFilters"][0]["field"].indexOf(".context.id") != -1) {
630
          filter["groupFilters"][0]["values"][0] = ChartHelper.prefix + "index_shortName" + ChartHelper.suffix;
631
          indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName;
632
        }
633
      }
634
    }
635
  }
636

    
637
  private extractOrganization(obj, indicatorPath: IndicatorPath, stakeholder:Stakeholder) {
638
    // works for publication.project.organization.name
639
    // and publication.organization.name
640
    if(stakeholder.type != "organization"){
641
      return;
642
    }
643
    for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) {
644
      if (!query["query"]["filters"]) {
645
        return;
646
      }
647
      for (let filter of query["query"]["filters"]) {
648
        if (filter["groupFilters"][0]["field"].indexOf(".organization.name") != -1) {
649
          filter["groupFilters"][0]["values"][0] = ChartHelper.prefix + "index_name" + ChartHelper.suffix;
650
          indicatorPath.parameters["index_name"] = stakeholder.index_name;
651
        }else  if (filter["groupFilters"][0]["field"].indexOf(".organization.id") != -1) {
652
          filter["groupFilters"][0]["values"][0] = ChartHelper.prefix + "index_shortName" + ChartHelper.suffix;
653
          indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName;
654
        }
655
      }
656
    }
657
  }
658
  private extractStartYear(obj, indicatorPath: IndicatorPath) {
659
    let start_year;
660
    for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) {
661
      if (!query["query"]["filters"]) {
662
        return;
663
      }
664
      for (let filter of query["query"]["filters"]) {
665
        for (let gfilter of filter["groupFilters"]) {
666
          if (gfilter["field"].indexOf(".year") != -1 && gfilter["type"].indexOf(">") != -1) {
667
            start_year = gfilter["values"][0];
668
            gfilter["values"][0] = ChartHelper.prefix + "start_year" + ChartHelper.suffix;
669
            indicatorPath.parameters["start_year"] = start_year;
670
          }
671
        }
672
      }
673
    }
674
  }
675

    
676
  private extractEndYear(obj, indicatorPath: IndicatorPath) {
677
    let end_year;
678
    for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) {
679
      if (!query["query"]["filters"]) {
680
        return;
681
      }
682
      for (let filter of query["query"]["filters"]) {
683
        for (let gfilter of filter["groupFilters"]) {
684
          if (gfilter["field"].indexOf(".year") != -1 && gfilter["type"].indexOf("<") != -1) {
685
            end_year = gfilter["values"][0];
686
            gfilter["values"][0] = ChartHelper.prefix + "end_year" + ChartHelper.suffix;
687
            indicatorPath.parameters["end_year"] = end_year;
688
          }
689
        }
690
      }
691
    }
692
  }
693

    
694
  private parameterizeDefaultQuery(obj, indicatorPath: IndicatorPath, stakeholder:Stakeholder) {
695
    let name = "";
696
    for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) {
697
      //monitor.{{stakeholderType}}.{{queryname}}
698
      //parameters: stakeholderId*, type
699
      if (query["query"]["name"]) {
700
        name = query["query"]["name"];
701
        let parameters = (query["query"]["parameters"])?query["query"]["parameters"]:[];
702
        if(name.split('.')[0] == "rcd" && parameters.length > 0  && stakeholder.type=="ri") {
703
          //rcd.{{queryname}}
704
          parameters[0] = ChartHelper.prefix + "index_id" + ChartHelper.suffix;
705
          indicatorPath.parameters["index_id"] = stakeholder.index_id;
706
        }else if(name.split('.')[0] == "monitor" && parameters.length == 0 && stakeholder.type=="funder"){
707
          // old saved queries without params
708
          //monitor.{{funder_shortName}}.{{type}}.{{queryname}}
709
          let stakeholderSN = name.split('.')[1];
710
          query["query"]["name"] = name.split('.' + stakeholderSN + ".")[0] + "." + ChartHelper.prefix + "index_shortName" + ChartHelper.suffix +"." + name.split('.' + stakeholderSN + ".")[1];
711
          indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName.toLowerCase();
712
        }else if(name.split('.')[0] == "monitor" && parameters.length > 0 && name.split('.')[1]  == stakeholder.type) {
713
          // new parameterized queries
714
          //monitor.{{type}}.{{queryname}}.{{param1 - id }}.{{param2 result-type}}.{{fl0}} --> params [start year, end year, id, result type, fl0]
715

    
716
          let index = (name.split('.').slice(3).length +2 == parameters.length)?[2]:((name.split('.').slice(3).length * 2 + 4 == parameters.length)?[2,name.split('.').slice(3).length+4]:[0]);
717
          for(let i of index) {
718
            if (name.split('.').length > 3 && name.split('.')[3] == "id") {
719
              parameters[i] = ChartHelper.prefix + "index_id" + ChartHelper.suffix;
720
              indicatorPath.parameters["index_id"] = stakeholder.index_id;
721
            } else if (name.split('.').length > 3 && name.split('.')[3] == "shortname") {
722
              parameters[i] = ChartHelper.prefix + "index_shortName" + ChartHelper.suffix;
723
              indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName.toLowerCase();
724
            } else if (name.split('.').length > 3 && name.split('.')[3] == "name") {
725
              parameters[i] = ChartHelper.prefix + "index_name" + ChartHelper.suffix;
726
              indicatorPath.parameters["index_name"] = stakeholder.index_name;
727
            }
728
          }
729
        }
730
      }
731
    }
732
  }
733
  private extractDataTitle(obj, indicatorPath: IndicatorPath) {
734
    let index = 0;
735
    if(!obj[this.getDescriptionObjectName(obj)] || !obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]){
736
      return;
737
    }
738
    for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) {
739
      if (query["name"]) {
740
        let name = query["name"];
741
        query["name"] =  ChartHelper.prefix + "data_title_"+index + ChartHelper.suffix;
742
        indicatorPath.parameters["data_title_"+index] = name;
743
      }
744
      index++;
745
    }
746
  }
747
  private extractTitle(obj, indicatorPath: IndicatorPath) {
748
    let title = "";
749
    if (obj[this.getDescriptionObjectName(obj)]["title"]) {
750
      title = obj[this.getDescriptionObjectName(obj)]["title"]["text"];
751
      obj[this.getDescriptionObjectName(obj)]["title"]["text"] = ChartHelper.prefix + "title" + ChartHelper.suffix;
752
    }else if (obj[this.getDescriptionObjectName(obj)]["options"] && obj[this.getDescriptionObjectName(obj)]["options"]["title"]) {
753
      title = obj[this.getDescriptionObjectName(obj)]["options"]["title"];
754
      obj[this.getDescriptionObjectName(obj)]["options"]["title"] = ChartHelper.prefix + "title" + ChartHelper.suffix;
755
    }
756
    indicatorPath.parameters["title"] = title ? title : "";
757
  }
758

    
759
  private extractSubTitle(obj, indicatorPath: IndicatorPath) {
760
    let subtitle = "";
761
    if (obj[this.getDescriptionObjectName(obj)]["subtitle"]) {
762
      subtitle = obj[this.getDescriptionObjectName(obj)]["subtitle"]["text"];
763
      obj[this.getDescriptionObjectName(obj)]["subtitle"]["text"] = ChartHelper.prefix + "subtitle" + ChartHelper.suffix;
764
      indicatorPath.parameters["subtitle"] = subtitle ? subtitle : "";
765
    }else if (obj[this.getDescriptionObjectName(obj)]["title"] && obj[this.getDescriptionObjectName(obj)]["title"] && obj[this.getDescriptionObjectName(obj)]["title"]["subtext"]) {
766
      subtitle = obj[this.getDescriptionObjectName(obj)]["title"]["subtext"];
767
      obj[this.getDescriptionObjectName(obj)]["title"]["subtext"] = ChartHelper.prefix + "subtitle" + ChartHelper.suffix;
768
      indicatorPath.parameters["subtitle"] = subtitle ? subtitle : "";
769
    }
770
  }
771

    
772
  private extractXTitle(obj, indicatorPath: IndicatorPath) {
773
    let title = "";
774
    if (obj[this.getDescriptionObjectName(obj)]["xAxis"] && obj[this.getDescriptionObjectName(obj)]["xAxis"]["title"]) {
775
      title = obj[this.getDescriptionObjectName(obj)]["xAxis"]["title"]["text"];
776
      obj[this.getDescriptionObjectName(obj)]["xAxis"]["title"]["text"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix;
777
    }else if (obj[this.getDescriptionObjectName(obj)]["options"] && obj[this.getDescriptionObjectName(obj)]["options"]["hAxis"] && obj[this.getDescriptionObjectName(obj)]["options"]["hAxis"]["title"]) {
778
      title = obj[this.getDescriptionObjectName(obj)]["options"]["hAxis"]["title"];
779
      obj[this.getDescriptionObjectName(obj)]["options"]["hAxis"]["title"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix;
780
    }else if (obj[this.getDescriptionObjectName(obj)]["xAxis"] && obj[this.getDescriptionObjectName(obj)]["xAxis"]["name"]) {
781
      title = obj[this.getDescriptionObjectName(obj)]["xAxis"]["name"];
782
      obj[this.getDescriptionObjectName(obj)]["xAxis"]["name"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix;
783
    }
784
    indicatorPath.parameters["xAxisTitle"] = title ? title : "";
785
  }
786

    
787
  private extractYTitle(obj, indicatorPath: IndicatorPath) {
788
    let title = "";
789
    if (obj[this.getDescriptionObjectName(obj)]["yAxis"] && obj[this.getDescriptionObjectName(obj)]["yAxis"]["title"] ) {
790
      title = obj[this.getDescriptionObjectName(obj)]["yAxis"]["title"]["text"];
791
      obj[this.getDescriptionObjectName(obj)]["yAxis"]["title"]["text"] = ChartHelper.prefix + "yAxisTitle" + ChartHelper.suffix;
792
    }else if (obj[this.getDescriptionObjectName(obj)]["options"]&& obj[this.getDescriptionObjectName(obj)]["options"]["vAxis"] && obj[this.getDescriptionObjectName(obj)]["options"]["vAxis"]["title"]) {
793
      title = obj[this.getDescriptionObjectName(obj)]["options"]["vAxis"]["title"];
794
      obj[this.getDescriptionObjectName(obj)]["options"]["vAxis"]["title"] = ChartHelper.prefix + "yAxisTitle" + ChartHelper.suffix;
795
    }else if (obj[this.getDescriptionObjectName(obj)]["yAxis"] && obj[this.getDescriptionObjectName(obj)]["yAxis"]["name"]) {
796
      title = obj[this.getDescriptionObjectName(obj)]["yAxis"]["name"];
797
      obj[this.getDescriptionObjectName(obj)]["yAxis"]["name"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix;
798
    }
799
    indicatorPath.parameters["yAxisTitle"] = title ? title : "";
800
  }
801

    
802
  private extractOldToolTitle(obj, indicatorPath: IndicatorPath) {
803
    let title = "";
804
    if (obj["title"]) {
805
      title = obj["title"];
806
      obj["title"] = ChartHelper.prefix + "title" + ChartHelper.suffix;
807
      indicatorPath.parameters["title"] = title;
808

    
809
    }
810
  }
811

    
812
  private extractOldToolXTitle(obj, indicatorPath: IndicatorPath) {
813
    let title = "";
814
    if (obj["xaxistitle"]) {
815
      title = obj["xaxistitle"];
816
      obj["xaxistitle"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix;
817
      indicatorPath.parameters["xAxisTitle"] = title;
818
    }
819
  }
820

    
821
  private extractOldToolYTitle(obj, indicatorPath: IndicatorPath) {
822
    let title = "";
823
    if (obj["fieldsheaders"]) {
824
      title = Array.isArray(obj["fieldsheaders"]) ? obj["fieldsheaders"][0] : obj["fieldsheaders"];
825
      if (Array.isArray(obj["fieldsheaders"])) {
826
        obj["fieldsheaders"][0] = ChartHelper.prefix + "yAxisTitle" + ChartHelper.suffix;
827
      } else {
828
        obj["fieldsheaders"] = ChartHelper.prefix + "yAxisTitle" + ChartHelper.suffix;
829
      }
830
      indicatorPath.parameters["yAxisTitle"] = title;
831
    }
832
  }
833

    
834
}
(2-2/3)