1 /* Copyright (c) 2019 AT&T Intellectual Property. #
\r
3 # Licensed under the Apache License, Version 2.0 (the "License"); #
\r
4 # you may not use this file except in compliance with the License. #
\r
5 # You may obtain a copy of the License at #
\r
7 # http://www.apache.org/licenses/LICENSE-2.0 #
\r
9 # Unless required by applicable law or agreed to in writing, software #
\r
10 # distributed under the License is distributed on an "AS IS" BASIS, #
\r
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
\r
12 # See the License for the specific language governing permissions and #
\r
13 # limitations under the License. #
\r
14 ##############################################################################*/
\r
17 import { Injectable } from '@angular/core';
\r
18 import { FeathersService } from 'app/shared/services/feathers.service';
\r
19 import { TestExecutionService } from 'app/shared/services/test-execution.service';
\r
20 import { Observable, Subject, from } from 'rxjs';
\r
21 import { MatDialog } from '@angular/material';
\r
22 import { GroupService } from 'app/shared/services/group.service';
\r
23 import * as moment from 'moment';
\r
24 import { SchedulingService } from 'app/shared/services/scheduling.service';
\r
25 import { TestInstanceService } from 'app/shared/services/test-instance.service';
\r
26 import { string, number } from '@amcharts/amcharts4/core';
\r
27 import { group } from '@angular/animations';
\r
28 export interface StatsFilter {
\r
31 selectedTestDefinitions?: Array<any>,
\r
32 selectedTestInstances?: Array<any>
\r
39 //this service serves as the controller between the dashboard's data management and the components' UI.
\r
40 export class StatsService {
\r
42 //set default filters
\r
43 public filters: StatsFilter = {
\r
44 startDate: moment().subtract(1, 'weeks').toDate(),
\r
45 endDate: moment().toDate()
\r
48 public executionList: Array<any> = [];
\r
50 public testDefinitionData = {
\r
51 //Executions Array thats made of objects with date, test definition name, and count
\r
53 //Array of Results for the Pie Chart
\r
56 public testInstanceData = {
\r
57 //Executions for Each Test Instance
\r
59 //For multilinechart, objects made of test instance names, and execution count for each one.
\r
60 "Individual_Exec": []
\r
63 //list if test instance names
\r
64 public testInstances = [];
\r
65 //list of scheduled tests gotten from agenda in db.
\r
66 public scheduledTests = [];
\r
68 //these are filter objects attached to stats service that are updated whenever user confirms from filter modal.
\r
69 //They are updated in the filter functions below.
\r
70 // public tdFilters = {
\r
75 // public tiFilters = {
\r
80 // //this limit is for the amount of multiple series being displayed on the multiline chart according to default/filters.
\r
81 // multiLineLimit: 5,
\r
83 // public scheduleFilters = {
\r
86 // timeRangeStart: {},
\r
87 // timeRangeEnd: {},
\r
88 // selectedInstances: [],
\r
91 //these are for triggering the listeners located in the chart components.
\r
92 //executionsChange subjects are triggered when user filters.
\r
93 public tdExecutionsChange: Subject<Object> = new Subject<Object>();
\r
94 public tiExecutionsChange: Subject<Object> = new Subject<Object>();
\r
95 public scheduleChange: Subject<Object> = new Subject<Object>();
\r
96 public finishedDefaultData: Subject<Object> = new Subject<Object>();
\r
97 public startDefaultData: Subject<Object> = new Subject<Object>();
\r
98 public startTDExecutionCall: Subject<Object> = new Subject<Object>();
\r
99 public startTIExecutionCall: Subject<Object> = new Subject<Object>();
\r
100 public windowResized: Subject<Object> = new Subject<Object>();
\r
101 public startScheduleCall: Subject<Object> = new Subject<Object>();
\r
103 constructor(public feathers: FeathersService, public testExecution: TestExecutionService,
\r
104 public _groups: GroupService, public testInstanceService: TestInstanceService, public schedService: SchedulingService) {
\r
106 //listening for whether user changes group, if so, variables are reset (rest are inside defaultData, we can work on consistency).
\r
107 //and we get default data for the new group passed in.
\r
108 // this.getDefaultData(this._groups.getGroup());
\r
109 // this._groups.groupChange().subscribe(group => {
\r
110 // this.getDefaultData(group);
\r
117 //these are trigger functions that we call in the data manipulating functions below.
\r
118 //the purpose of these functions is to let the listeners set up in the chart components know that the data has been updated.
\r
119 //then the chart components recall the data using getData().
\r
121 return this.windowResized;
\r
124 onDefaultDataCallStarted() {
\r
125 return this.startDefaultData;
\r
128 onTDExecutionChangeStarted() {
\r
129 return this.startTDExecutionCall;
\r
132 onTIExecutionChangeStarted() {
\r
133 return this.startTIExecutionCall;
\r
136 onScheduleChangeStarted() {
\r
137 return this.startScheduleCall;
\r
140 onDefaultDataCallFinished() {
\r
141 return this.finishedDefaultData;
\r
144 onTDExecutionChangeFinished() {
\r
145 return this.tdExecutionsChange;
\r
148 onTIExecutionChangeFinished() {
\r
149 return this.tiExecutionsChange;
\r
152 onScheduleChangeFinished() {
\r
153 return this.scheduleChange;
\r
156 //one giant getter where we pass in the name of what we want and switch case it.
\r
158 //This function is called in the components and returns the relavent array for the component.
\r
159 getData(name: string) {
\r
160 let outputData = {};
\r
163 case "TD_Executions":
\r
164 return this.testDefinitionData.Executions;
\r
166 return this.testDefinitionData.Results;
\r
167 case "testInstances":
\r
168 return this.testInstanceData.Executions;
\r
170 return this.scheduledTests;
\r
171 // case "multiLineData":
\r
172 // //limitting the series being displayed.
\r
173 // return this.testInstanceData.Individual_Exec.slice(0, this.tiFilters.multiLineLimit);
\r
175 //console.log(outputData);
\r
179 //this gets called from the filter modal when the user confirms their filters.
\r
180 filterData(allFilters, tdFilters, tiFilters, schedFilters) {
\r
181 //this.filterAll(allFilters);
\r
182 this.filterTDs(tdFilters);
\r
183 this.filterTIs(tiFilters);
\r
184 this.filterSchedule(schedFilters)
\r
187 //this is still under the works, the purpose of this is to filter ALL the components of the dashboard if they have common filtering grounds.
\r
188 filterAll(allFilters) {
\r
189 //console.log('Filtering everything')
\r
190 //console.log(allFilters);
\r
191 if (allFilters.startDate != "" || allFilters.endDate != "") {
\r
192 if (allFilters.endDate == "") {
\r
193 this.testDefinitionData.Executions = this.testDefinitionData.Executions.filter(execution => (
\r
194 execution.startTime >= allFilters.startDate
\r
196 } else if (allFilters.startDate == "") {
\r
197 this.testDefinitionData.Executions = this.testDefinitionData.Executions.filter(execution => (
\r
198 execution.startTime <= allFilters.endDate
\r
201 this.testDefinitionData.Executions = this.testDefinitionData.Executions.filter(execution => (
\r
202 execution.startTime >= allFilters.startDate &&
\r
203 execution.date <= allFilters.endDate
\r
210 this function takes in test definition filters and queries data accordingly.
\r
211 improvement needed: if the filters provided do not require querying at all, the function should narrow the currently existing data. This
\r
212 will be faster than requerying in those cases and improve loading times.
\r
214 async filterTDs(tdFilters) {
\r
217 checking if the filters passed in are empty, if so do nothing, if not, trigger a start call that lets the components know querying is going to begin.
\r
218 these start..Call() functions are so chart components can turn on their loading indicators.
\r
220 // if (tdFilters.startDate == "" && tdFilters.endDate == "" && tdFilters.selected.length == 0) return;
\r
221 // else this.startTDExecutionCall.next(tdFilters);
\r
223 // //updating filter objects attached to stats service so we can use the service getters to get them where we want in the charts component code.
\r
224 // this.tdFilters = tdFilters;
\r
226 // //if no range is passed in we use the default range of past 2 months.
\r
227 // let startDate = tdFilters.startDate == "" ? new Date(moment().subtract(2, 'weeks').format('L')) : new Date(tdFilters.startDate);
\r
228 // let endDate = tdFilters.endDate == "" ? moment().toDate() : new Date(tdFilters.endDate);
\r
229 // //update service filters accordingly.
\r
230 // this.tdFilters.startDate = startDate;
\r
231 // this.tdFilters.endDate = endDate;
\r
232 //variable of id's of the test definitions selected in the filters.
\r
233 let selectedIDs = this.filters.selectedTestDefinitions.map(item => item.id);
\r
235 //Promise that queries the data according the filters. We use a promise so we wait for the data to query before the components render.
\r
236 await new Promise((resolve, reject) => {
\r
238 //feathers query time.
\r
239 this.testExecution.find({
\r
240 //get the data relevant to the group.
\r
241 groupId: this._groups.getGroup()["_id"],
\r
242 //thse are gonna go in the data objects.
\r
244 'historicTestDefinition.testName',
\r
248 //UNLIMITED DATA BABY.
\r
250 //sort according to ascending dates.
\r
254 //select the start and end dates from the filter dates.
\r
256 $gte: this.filters.startDate,
\r
257 $lte: this.filters.endDate,
\r
259 //select the test definitions according to the selected ones in the filters.
\r
260 'historicTestDefinition._id': {
\r
263 }).subscribe(result => {
\r
265 //console.log(result)
\r
267 //resetting real quick cuz why not.
\r
268 this.testDefinitionData = {
\r
273 //pretty self explanitory.
\r
274 let fetchedData = result as Array<any>;
\r
275 let currentExecutionsData = this.testDefinitionData.Executions;
\r
278 for each new fetched json we got with the selected stuff we specified in the feathers query,
\r
279 we need to organize and distribute them accordingly to our service's data objects. For example, the json objects consist of
\r
280 'historicTestDefinition.testName',
\r
283 test results belong in the results array, the rest needs to be organzied in the executions array,
\r
284 thats what the populate methods are for.
\r
286 for (let index in fetchedData) {
\r
287 let newItem = fetchedData[index];
\r
289 //for consistency we're supposed to pass current data to both we'll fix that later, but for now the piechart one just calls the current results data
\r
291 this.populateLineChartData(newItem, currentExecutionsData);
\r
292 this.populatePieChartData(newItem);
\r
297 //console.log(res);
\r
299 //trigger that querying is done and the test definition executions data has been changed. Line chart and pie chart listen for this.
\r
300 this.tdExecutionsChange.next(res);
\r
304 //similar stuffies. just small differences.
\r
305 async filterTIs(tiFilters) {
\r
307 // if (tiFilters.startDate == "" && tiFilters.endDate == "" && tiFilters.selectedTDs.length == 0 && tiFilters.selectedTIs.length == 0) return;
\r
308 // else this.startTIExecutionCall.next(tiFilters);
\r
310 // this.tiFilters = tiFilters;
\r
311 // if (tiFilters.selectedTIs.length > 0 && tiFilters.selectedTDs.length > 0) this.tiFilters.multiLineLimit = tiFilters.selectedTIs.length + tiFilters.selectedTDs.length;
\r
312 // else if (tiFilters.selectedTIs.length > 0) this.tiFilters.multiLineLimit = tiFilters.selectedTIs.length;
\r
313 // else if (tiFilters.selectedTDs.length > 0) this.tiFilters.multiLineLimit = tiFilters.selectedTDs.length;
\r
314 // else this.tiFilters.multiLineLimit = 5;
\r
316 // let startDate = tiFilters.startDate == "" ? new Date(moment().subtract(2, 'weeks').format('L')) : new Date(tiFilters.startDate);
\r
317 // let endDate = tiFilters.endDate == "" ? moment().toDate() : new Date(tiFilters.endDate);
\r
319 // this.tiFilters.startDate = startDate;
\r
320 // this.tiFilters.endDate = endDate;
\r
321 // console.log(tiFilters.selectedTDs)
\r
323 await new Promise((resolve, reject) => {
\r
324 this.testExecution.find({
\r
325 groupId: this._groups.getGroup()["_id"],
\r
328 $gte: this.filters.startDate,
\r
329 $lte: this.filters.endDate,
\r
334 'historicTestDefinition.testName',
\r
335 'historicTestInstance.testInstanceName',
\r
339 'historicTestDefinition._id': {
\r
340 $in: tiFilters.selectedTDs
\r
344 'historicTestInstance._id': {
\r
345 $in: tiFilters.selectedTIs
\r
350 }).subscribe(result => {
\r
351 this.testInstanceData = {
\r
353 "Individual_Exec": []
\r
355 //console.log(result)
\r
356 let fetchedData = result as Array<any>;
\r
357 for (let index in fetchedData) {
\r
358 let newItem = fetchedData[index];
\r
359 this.populateBarChartData(newItem);
\r
360 this.populateMultiLineChartData(newItem);
\r
362 this.testInstanceData.Executions.sort((a, b) => b.Count - a.Count);
\r
363 this.testInstanceData.Individual_Exec.sort((a, b) => b.total - a.total);
\r
368 this.tiExecutionsChange.next(res);
\r
369 //console.log(this.testInstanceData.Executions);
\r
374 //similar stuffies just smol differneces.
\r
375 async filterSchedule(schedFilters) {
\r
377 //console.log(schedFilters);
\r
378 // this.scheduleFilters = schedFilters;
\r
379 // //console.log(schedFilters.selectedInstances);
\r
381 // if (schedFilters.startDate == "" &&
\r
382 // schedFilters.endDate == "" &&
\r
383 // schedFilters.selectedInstances.length == 0) {
\r
385 // } else this.startScheduleCall.next(schedFilters);
\r
387 // let startDate = schedFilters.startDate == "" ? new Date(moment().toDate()) : new Date(schedFilters.startDate);
\r
388 // let endDate = schedFilters.endDate == "" ? new Date(moment().add(2, 'weeks').format('L')) : new Date(schedFilters.endDate);
\r
390 // this.scheduleFilters.startDate = startDate;
\r
391 // this.scheduleFilters.endDate = endDate;
\r
394 this.schedService.find({
\r
395 $select: ["data.testSchedule._testInstanceId", 'nextRunAt'],
\r
397 }).subscribe(result => {
\r
398 this.scheduledTests = [];
\r
399 //console.log(result);
\r
400 let fetchedData = result as Array<any>;
\r
401 let resultingData: Array<any> = fetchedData;
\r
402 if (schedFilters.selectedInstances.length !== 0) {
\r
403 resultingData = fetchedData.filter(el => {
\r
404 let fetchedID = el.data.testSchedule._testInstanceId;
\r
405 let selectedIDs = schedFilters.selectedInstances as Array<any>;
\r
406 let condition = selectedIDs.includes(fetchedID.toString());
\r
407 //console.log(condition);
\r
412 resultingData = resultingData.filter(el => {
\r
413 let schedDate = new Date(el.nextRunAt);
\r
414 return schedDate >= this.filters.startDate && schedDate <= this.filters.endDate;
\r
417 for (let index in resultingData) {
\r
418 let checkIfTestBelongsToUserGroup = this.testInstances.findIndex(testInstances => testInstances.id === resultingData[index].data.testSchedule._testInstanceId);
\r
419 if (checkIfTestBelongsToUserGroup >= 0) {
\r
420 if (resultingData[index].nextRunAt) {
\r
421 let d1 = new Date(resultingData[index].nextRunAt);
\r
422 this.scheduledTests.push({
\r
423 id: resultingData[index].data.testSchedule._testInstanceId,
\r
424 name: this.testInstances[checkIfTestBelongsToUserGroup].name,
\r
425 dateExec: d1.toDateString(),
\r
426 timeExec: d1.toLocaleTimeString()
\r
431 this.scheduleChange.next();
\r
438 //getters for the filter objects.
\r
439 // getTDFilters() {
\r
440 // return this.tdFilters;
\r
443 // getTIFilters() {
\r
444 // return this.tiFilters;
\r
447 // getSchedFilters() {
\r
448 // return this.scheduleFilters;
\r
451 calcTime(execution) {
\r
452 var end = new Date(execution.endTime);
\r
453 var start = new Date(execution.startTime);
\r
454 var executionTime = (end.getTime() - start.getTime()) / 1000;
\r
455 return executionTime;
\r
458 //This function takes an execution that was retrieved from the Database and takes the data it needs for the line chart.
\r
459 populateLineChartData(execution, currentData) {
\r
460 let executionDate = new Date(execution.startTime)
\r
462 // Looks to see if the date already has an execution./
\r
463 let indexOfItemFound = currentData.findIndex((element) => {
\r
466 executionDate.getFullYear() === element.date.getFullYear() &&
\r
467 executionDate.getMonth() === element.date.getMonth() &&
\r
468 executionDate.getDate() === element.date.getDate()
\r
472 //If the date is not found. Push a new date into the array with a count of one
\r
473 if (currentData[indexOfItemFound] == undefined) {
\r
475 date: new Date(executionDate.getFullYear(), executionDate.getMonth(), executionDate.getDate()),
\r
478 // else update the count
\r
479 } else currentData[indexOfItemFound].count += 1;
\r
483 //Takes an execution and pushes the result/count or updates the count. For the Pie Chart
\r
484 populatePieChartData(execution) {
\r
486 //Check if result is already present in the array.
\r
487 var checkIfPresent = this.testDefinitionData.Results.find(Results => Results.Name === execution.testResult);
\r
489 //If not present, add it to TOPSTATs with a default count of 1.
\r
490 if (!checkIfPresent) {
\r
493 //Set the color for the pie chart.
\r
494 if (execution.testResult == "COMPLETED"){
\r
496 }else if (execution.testResult == "FAILED")
\r
498 else if (execution.testResult == "UNKNOWN")
\r
500 else if (execution.testResult == "SUCCESS")
\r
502 else if (execution.testResult == "success")
\r
504 else if (execution.testResult == "STARTED")
\r
506 else if (execution.testResult == "FAILURE")
\r
508 else if (execution.testResult == "STOPPED")
\r
510 else if (execution.testResult == "TERMINATED")
\r
512 else if (execution.testResult == "UNAUTHORIZED")
\r
514 else if (execution.testResult == "DOES_NOT_EXIST")
\r
516 else if (execution.testResult == "ERROR")
\r
518 else if (execution.testResult == "WORKFLOW_ERROR")
\r
521 color = "#000000".replace(/0/g, function () { return (~~(Math.random() * 16)).toString(16); });
\r
523 //Push the execution with the count and color.
\r
524 this.testDefinitionData.Results.push({ Name: execution.testResult, Count: 1, color: color });
\r
527 //Find index of the testResult and update the count by 1.
\r
528 var position = this.testDefinitionData.Results.findIndex(Results => Results.Name === execution.testResult);
\r
529 this.testDefinitionData.Results[position].Count += 1;
\r
533 //Takes an execution and pushes result into the barchart.
\r
534 populateBarChartData(execution) {
\r
536 //check if test instance is present in the array.
\r
537 var checkIfPresent = this.testInstanceData.Executions.find(Instances => Instances.id === execution.historicTestInstance._id);
\r
539 //calculates the time it took for the execution/
\r
540 var executionTime = this.calcTime(execution);
\r
542 //If execution is not present, push the test instance with a count of 1.
\r
543 if (!checkIfPresent) {
\r
544 //If not present, add it to testInstanceData with a default count of 1.
\r
546 this.testInstanceData.Executions.push({
\r
547 Name: execution.historicTestInstance.testInstanceName,
\r
548 id: execution.historicTestInstance._id,
\r
549 testResult: execution.testResult,
\r
550 executionTime: executionTime,
\r
552 Average: executionTime
\r
555 // If Present update count and execution time.
\r
556 var position = this.testInstanceData.Executions.findIndex(Instances => Instances.id === execution.historicTestInstance._id);
\r
557 this.testInstanceData.Executions[position].Count += 1;
\r
558 this.testInstanceData.Executions[position].executionTime += executionTime;
\r
559 this.testInstanceData.Executions[position].Average = this.testInstanceData.Executions[position].executionTime / this.testInstanceData.Executions[position].Count;
\r
564 //queries data for the scheduled tests.
\r
565 getScheduledTests(groupId) {
\r
567 //Queries a list of test instances by group ID
\r
568 this.testInstanceService.find({
\r
569 groupId: groupId['_id'],
\r
570 $select: ["_id", "testInstanceName", "groupId"],
\r
572 }).subscribe(result => {
\r
574 //Iterate through the list and add the test instances to the list.
\r
575 for (var index in result) {
\r
576 var checkIfPresent = this.testInstances.find(id => id === result[index]._id);
\r
577 if (!checkIfPresent)
\r
578 this.testInstances.push({ id: result[index]._id, name: result[index].testInstanceName });
\r
582 //Queries all of the scheduled tests.
\r
583 this.schedService.find({
\r
585 $select: ["data.testSchedule._testInstanceId", 'nextRunAt'],
\r
591 }).subscribe(result => {
\r
593 this.scheduledTests = [];
\r
594 for (var index in result) {
\r
596 //If the scheduled testinstance is owned by the group, push the result.
\r
597 var checkIfTestBelongsToUserGroup = this.testInstances.findIndex(testInstances => testInstances.id === result[index].data.testSchedule._testInstanceId);
\r
598 if (checkIfTestBelongsToUserGroup >= 0) {
\r
600 //If the next run at is valid, the test is scheduled.
\r
601 if (result[index].nextRunAt) {
\r
602 let d1 = new Date(result[index].nextRunAt);
\r
603 this.scheduledTests.push({
\r
604 id: result[index].data.testSchedule._testInstanceId,
\r
605 name: this.testInstances[checkIfTestBelongsToUserGroup].name,
\r
606 dateExec: d1.toDateString(),
\r
607 timeExec: d1.toLocaleTimeString()
\r
615 //populate multi line chart
\r
616 populateMultiLineChartData(execution) {
\r
618 let executionDate = new Date(execution.startTime)
\r
619 let currentData = this.testInstanceData.Individual_Exec;
\r
621 //find if Instance is already present in the array.
\r
622 let position = this.testInstanceData.Individual_Exec.findIndex(Instances => Instances.id === execution.historicTestInstance._id);
\r
624 //First execution for this instance
\r
625 if (currentData[position] == undefined) {
\r
627 testInstanceName: execution.historicTestInstance.testInstanceName,
\r
628 testDefinitionName: execution.historicTestDefinition.testDefintionName,
\r
629 id: execution.historicTestInstance._id,
\r
630 dateData: [{ date: executionDate, count: count, name: execution.historicTestInstance.testInstanceName }],
\r
633 //execution already present
\r
635 //find index of Date
\r
636 let indexOfDate = currentData[position].dateData.findIndex((element) => {
\r
638 executionDate.getFullYear() === element.date.getFullYear() &&
\r
639 executionDate.getMonth() === element.date.getMonth() &&
\r
640 executionDate.getDate() === element.date.getDate()
\r
644 //Check if the exeuction date is valid for this instance. If it is not present, push a new date and count.
\r
645 if (currentData[position].dateData[indexOfDate] == undefined) {
\r
647 //Push the new Date
\r
648 currentData[position].dateData.push({ date: executionDate, count: count, name: execution.historicTestInstance.testInstanceName, id: execution.historicTestInstance._id});
\r
649 currentData[position].total++;
\r
651 //date is already present
\r
652 currentData[position].dateData[indexOfDate].count++;
\r
653 currentData[position].total++;
\r
657 //Gets the initial data for the default page.
\r
658 async getDefaultData(group, query?) {
\r
663 this.scheduledTests = [];
\r
665 this.startDefaultData.next(group);
\r
666 let groupId = group;
\r
667 //let startDate = moment().subtract(2, 'weeks').toDate();
\r
669 //query sheduled tests
\r
670 //this.getScheduledTests(group);
\r
674 groupId: groupId['_id'],
\r
678 "historicTestDefinition._id",
\r
679 "historicTestDefinition.testName",
\r
680 "historicTestInstance._id",
\r
681 "historicTestInstance.testInstanceName",
\r
682 "testHeadResults.startTime",
\r
683 "testHeadResults.endTime",
\r
684 "testHeadResults.testHeadName",
\r
685 "testHeadResults.testHeadId",
\r
686 "testHeadResults.testHeadGroupId",
\r
687 "testHeadResults.statusCode",
\r
695 $gte: this.filters.startDate,
\r
696 $lte: this.filters.endDate
\r
701 //Query test Executions
\r
702 await new Promise((resolve, reject) => {
\r
703 this.testExecution.find(query).subscribe(result => {
\r
706 this.testDefinitionData = {
\r
707 //Executions Array thats made of objects with date, tdName, result
\r
711 this.testInstanceData = {
\r
713 "Individual_Exec": []
\r
716 this.executionList = result as Array<any>;
\r
717 let currentData = this.testDefinitionData.Executions;
\r
721 //iterate through the results and populate the appropriate arrays.
\r
722 for (let index in this.executionList) {
\r
724 let newItem = this.executionList[index];
\r
726 //get default line chart Data
\r
727 this.populateLineChartData(newItem, currentData);
\r
729 //get pie chart data.
\r
730 this.populatePieChartData(newItem);
\r
732 //Get BarChart Data
\r
733 //this.populateBarChartData(newItem);
\r
735 //get multi line chart data
\r
736 //this.populateMultiLineChartData(newItem);
\r
739 //sort the two arrays descending.
\r
740 this.testInstanceData.Executions.sort((a, b) => b.Count - a.Count);
\r
741 this.testInstanceData.Individual_Exec.sort((a, b) => b.total - a.total);
\r
748 // this.tdFilters = {
\r
749 // startDate: moment().subtract(2, 'weeks').toDate(),
\r
750 // endDate: moment().toDate(),
\r
753 // this.tiFilters = {
\r
754 // startDate: moment().subtract(2, 'weeks').toDate(),
\r
755 // endDate: moment().toDate(),
\r
756 // selectedTDs: [],
\r
757 // selectedTIs: [],
\r
758 // multiLineLimit: 5,
\r
760 this.finishedDefaultData.next(res);
\r