Skip to content

Instantly share code, notes, and snippets.

@janakprajapati2112
Last active October 24, 2018 10:18
Show Gist options
  • Save janakprajapati2112/1425202b5a1141a24cf96b62fbbce67c to your computer and use it in GitHub Desktop.
Save janakprajapati2112/1425202b5a1141a24cf96b62fbbce67c to your computer and use it in GitHub Desktop.
import {
Subject
} from 'rxjs';
import {
Component,
OnInit,
ViewEncapsulation,
AfterViewInit,
Input,
Output,
ComponentFactoryResolver,
ViewChild,
ViewContainerRef,
Directive,
Inject,
QueryList,
ViewChildren,
Injectable,
ChangeDetectionStrategy,
ChangeDetectorRef
} from '@angular/core';
import {
Http,
RequestMethod,
RequestOptions,
Response,
ResponseOptions,
XHRBackend,
Headers
} from "@angular/http";
import {
Observable
} from 'rxjs';
import {
delay,
map
} from 'rxjs/operators';
import 'rxjs/Rx';
import {
ApplicationApiService
} from '../_services/api.service';
@Injectable()
@Component({
selector: 'dynamic-component',
template: `
<div class="snippet" *ngIf="reportLoading === true">
<div class="stage">
<div class="dot-typing"></div>
</div>
</div>
<ng-container *ngFor="let rData of splitByData; let i = index; last as isLast">
<div class="row report-row" >
<div class="col-4" [ngStyle]="{'padding-left': calculateTextPadding(nextSplit.id) }">
<button
class="btn btn-sm"
*ngIf="checkIfHaveMoreSplits(nextSplit.id,splitOptions) !== 0 && rData.isCollapsed == true"
(click)="splitData(rowWiseFilterObj(rData,nextSplit.id,selectedRow),nextSplit.id,selectedFilters,splitOptions,i,rData,selectedDate)">+</button>
<button
class="btn btn-sm"
*ngIf="checkIfHaveMoreSplits(nextSplit.id,splitOptions) !== 0 && rData.isCollapsed == false"
(click)="removeDynamicComponent(rData,i)"
>-</button>
<span *ngIf="nextSplit.id !== '__time'">{{rData[nextSplit.id]}}</span>
<span *ngIf="nextSplit.id === '__time'">{{ rData[nextSplit.id] | date:'dd-MM-yyyy HH:mm:ss Z'}}</span>
</div>
<div class="col-2">{{convertToDecimals(rData.wins,2)}}</div>
<div class="col-2">{{convertToDecimals(rData.conversions,2)}}</div>
<div class="col-1">{{convertToDecimals(rData.cost,2)}}</div>
<div class="col-1">{{convertToDecimals(rData.bids,2)}}</div>
<div class="col-1">{{convertToDecimals(rData.impressions,2)}}</div>
<div class="col-1">{{convertToDecimals(rData.rev_payout,2)}}</div>
</div>
<div *ngIf="isLast">{{altrows("#ffffff","#f5f5f5")}}</div>
<ng-template #dynamic ></ng-template>
</ng-container>
`
})
export class DynamicComponent implements OnInit, AfterViewInit {
@Input() selectedRow: any;
@Input() nextSplit: any;
@Input() selectedFilters: any;
@Input() splitOptions: any;
@Input() splitByData: any;
@Input() rowData: any;
@Input() reportLoading: any;
@Input() selectedDate: any;
factoryResolver;
rootViewContainer;
@ViewChildren('dynamic', {
read: ViewContainerRef
}) viewContainerRef: QueryList<ViewContainerRef>
constructor(
@Inject(ComponentFactoryResolver) factoryResolver,
private _apis: ApplicationApiService,
private cd: ChangeDetectorRef
) {
this.factoryResolver = factoryResolver
}
ngOnInit() {
}
ngAfterViewInit() {
}
setRootViewContainerRef(viewContainerRef) {
this.rootViewContainer = viewContainerRef
}
addDynamicComponent(selectedRow, nextSplit, selectedFilters, splitOptions, sRow, selectedDate) {
const factory = this.factoryResolver
.resolveComponentFactory(DynamicComponent)
const component = factory
.create(this.rootViewContainer.parentInjector)
component.instance.selectedRow = selectedRow;
component.instance.nextSplit = nextSplit;
component.instance.selectedFilters = selectedFilters;
component.instance.splitOptions = splitOptions;
component.instance.selectedDate = selectedDate;
var a = JSON.parse(JSON.stringify(selectedFilters));
var b = JSON.parse(JSON.stringify(selectedRow));
a.filter(function(o1) {
return b.some(function(o2) {
if (o1.id === o2.id) {
o1.values = o2.values;
}
});
});
//Find values that are in result1 but not in result2
var uniqueResultOne = a.filter(function(obj) {
return !b.some(function(obj2) {
return obj.id == obj2.id;
});
});
//Find values that are in result2 but not in result1
var uniqueResultTwo = b.filter(function(obj) {
return !a.some(function(obj2) {
return obj.id == obj2.id;
});
});
//Combine the two arrays of unique entries
var result = a.concat(uniqueResultOne.concat(uniqueResultTwo));
result = result.filter((s1, pos, arr) => arr.findIndex((s2) => s2.id === s1.id) === pos);
this.reportLoading = true;
this._apis.getReportData(nextSplit.id, this.getApiFilters(result), selectedDate).subscribe(response => {
if (response.status == 1200) {
response.data.split_by_data.map(function(obj) {
obj.isCollapsed = true;
return obj;
});
sRow.isCollapsed = false;
component.instance.splitByData = response.data.split_by_data;
this.reportLoading = false;
}
})
this.rootViewContainer.insert(component.hostView)
}
getApiFilters(selectedFilters) {
var apiFilters: any = [{}];
for (var i = 0; i < selectedFilters.length; i++) {
if (selectedFilters[i].values.length > 0) {
var k;
k = selectedFilters[i].id
apiFilters[0][k] = selectedFilters[i].values
}
}
return apiFilters[0];
}
checkIfHaveMoreSplits(c, splitOptions) {
if (splitOptions.length > 0) {
var index = splitOptions.findIndex(function(v) {
return v.id == c
})
if (typeof (splitOptions[index + 1]) != "undefined") {
return splitOptions[index + 1];
} else {
return 0;
}
}
}
splitData(obj, cSplit, sFilters, splitOptions, index, sRow, selectedDate) {
var nextSplit = this.checkIfHaveMoreSplits(cSplit, splitOptions);
this.setRootViewContainerRef(this.viewContainerRef.toArray()[index]);
this.addDynamicComponent(obj, nextSplit, sFilters, splitOptions, sRow, selectedDate);
}
rowWiseFilterObj(row, split, prev) {
if (prev.length == 0) {
var arr = [];
var obj = {
id: split,
label: split,
values: [row[split]]
}
arr.push(obj);
return arr;
} else {
var obj = {
id: split,
label: split,
values: [row[split]]
}
prev.push(obj);
return prev
}
}
removeDynamicComponent(rowData, index) {
this.viewContainerRef.toArray()[index].clear();
rowData.isCollapsed = true;
this.altrows("#ffffff", "#f5f5f5");
}
convertToDecimals(input, decimals) {
var exp, rounded,
suffixes = ['K', 'M', 'B', 'T', 'P', 'E'];
if (input < 1000) {
return parseFloat(input).toFixed(2);;
}
exp = Math.floor(Math.log(input) / Math.log(1000));
return (input / Math.pow(1000, exp)).toFixed(decimals) + suffixes[exp - 1];
}
calculateTextPadding(id) {
var index = this.splitOptions.findIndex(function(v) {
return v.id == id
})
if (typeof (index) != "undefined") {
return index * 40 + "px"
} else {
return "0px";
}
}
altrows(firstcolor, secondcolor) {
var tableElements = document.getElementsByClassName("report-row");
for (var j = 0; j < tableElements.length; j++) {
if (j % 2 == 0) {
(tableElements[j]).className = "row report-row odd";
}
else {
(tableElements[j]).className = "row report-row even";
}
}
}
}
<!--<input type="text" ngxDaterangepickerMd
[locale]="{applyLabel: 'ok', format: 'DD-MM-YYYY'}"
startKey="start"
endKey="end"
[(ngModel)]="selected" [ranges]="ranges"/> -->
<div class="row text-right" style="margin-top: 10px;">
<div class="col-md-6"></div>
<div class="col-md-6 text-right" style="padding-right: 0px;">
<input type="hidden"
ngxDaterangepickerMd
[(ngModel)]="selectedDate"
[showCustomRangeLabel]="true"
[alwaysShowCalendars]="true"
[ranges]="ranges"
[linkedCalendars]="false"
[isInvalidDate] = "isInvalidDate"
placeholder="Select please..."
[keepCalendarOpeningWithRange]="keepCalendarOpeningWithRange"
[showRangeLabelOnInput]="showRangeLabelOnInput"
(rangeClicked)="datesUpdated($event)"
(datesUpdated)="datesUpdated($event)"/>
<a href="javascript:;" class="ngx-daterangepicker-action waves-effect waves-light btn btn-sm btn-primary text-right" (click)="openDatePicker($event)" style="font-size: 14px;">
{{ selectedDate.startDate | date:'dd/MM/yyyy'}} to {{ selectedDate.endDate | date:'dd/MM/yyyy'}}<i class="fa fa-calendar" style="
margin: 10px 7px;
"></i> </a>
</div>
</div>
<div class="snippet" *ngIf="reportLoading === true">
<div class="stage">
<div class="dot-typing"></div>
</div>
</div>
<div class="row filter-row" style="border-bottom: 1px solid #ccc; margin-top: 20px;">
<div class="general-selected-filters">
Filter by:
<div class="filter-item" *ngFor="let filter of sFilters">
<div class="clause" *ngIf="filter.values.length > 0">
<span class="attribute" (click)="getFilterValues(filter,$event)">{{ filter.label }} :</span>
<span class="value" *ngIf="filter.values.length < 3" (click)="getFilterValues(filter,$event)">{{ arrToString(filter.values)
}}</span>
<span class="value" *ngIf="filter.values.length >= 3" (click)="getFilterValues(filter,$event)">{{ filter.values | slice:0:2 }} +{{ filter.values.length-2 }}</span>
<span class="remove-icon" ><i class="fa fa-times-circle" (click)="updateFilters(filter,'d')"></i></span>
</div>
</div>
</div>
<div class="addfilter btn btn-sm" (click)="openFilterSelection($event)" style="margin: -2px 0px;
text-align: right;
right: 10px;
position: absolute;">
<i class="fa fa-plus"></i>
</div>
</div>
<div class="row split-row">
<div class="general-selected-filters">
Split by:
<div class="filter-item" *ngFor="let filter of splitOpt">
<div class="clause">
<span class="attribute">{{ filter.text }}</span>
<span class="remove-icon"><i class="fa fa-times-circle" (click)="updateFilters(filter,'s')"></i></span>
</div>
</div>
</div>
<div class="addfilter btn btn-sm" (click)="openSplitSelection($event)" style="margin: 1px 0px;
text-align: right;
right: 10px;
position: absolute;">
<i class="fa fa-plus"></i>
</div>
</div>
<div class="popover-overlay-container" *ngIf="filterSelection || splitSelection " >
<div class="popover-overlay" (click)="hidePopup()"></div>
<div></div>
</div>
<div class="add-filter-menu" *ngIf="filterSelection" [ngStyle]="{'top': posY, 'left': posX}" >
<div class="add-filter-menu-results-container" >
<div class="attribute-selector" *ngIf="dimentionSelection">
<div class="clearable-input" placeholder="Search">
<input placeholder="Search" type="text" [(ngModel)]="query">
<div class="delete-button"></div>
</div>
<ul class="menu-options attribute-choices" >
<li *ngFor="let dimention of filterDimentions | searchfilter: query" class="" (click)="getFilterValues(dimention)">{{ dimention.text }}</li>
</ul>
</div>
<div class="value-selector" *ngIf="dValueSelection">
<div class="clearable-input" >
<input placeholder="Search" type="text" name="searchText" [(ngModel)]="q" (input)="onSearchChange()">
<div class="delete-button" ></div>
</div>
<div class="list-cont">
<div class="dvalue-loading" *ngIf="appLoading==true">
<div class="m-loader m-loader--primary" style="width: 30px; display: inline-block;"></div>
</div>
<ul class="menu-options attribute-values" >
<li *ngFor="let dimention of filterDimentionsValues" class="" (click)="selectFilters(dimention);">
<label class="m-checkbox app-checkbox" *ngIf="currentSelectedDimension !== '__time'">
<input type="checkbox" (click)="selectFilters(dimention)" [checked]="((-1 !== checkIfDimvalueExists(dimention)) ? 'checked' : '')"/>
{{ dimention[currentSelectedDimension]}}
<span></span>
</label>
<label class="m-checkbox app-checkbox" *ngIf="currentSelectedDimension === '__time'">
<input type="checkbox" (click)="selectFilters(dimention)" [checked]="((-1 !== checkIfDimvalueExists(dimention)) ? 'checked' : '')"/>
{{ dimention[currentSelectedDimension] | date:'dd-MM-yyyy HH:mm:ss Z'}}
<span></span>
</label>
</li>
</ul>
<!-- <div class="no-results">No results</div> -->
</div>
<div class="bottom-bar text-right" >
<button class="apply-button btn btn-sm btn-danger " (click)="goBackToDimensions()" style="position: absolute;
top: 6px;
right: 77px;
height: 28px;
font-size: 13px;">Back</button>
<button class="apply-button btn btn-sm btn-primary" (click)="getReport()">Apply</button>
</div>
</div>
</div>
</div>
<div class="add-filter-menu" *ngIf="splitSelection" [ngStyle]="{'top': posY, 'left': posX}" >
<div class="add-filter-menu-results-container" >
<div class="attribute-selector" *ngIf="dimentionSelection">
<div class="clearable-input" placeholder="Search">
<input placeholder="Search" type="text" [(ngModel)]="query">
<div class="delete-button"></div>
</div>
<ul class="menu-options attribute-choices" >
<li *ngFor="let dimention of filterDimentions | searchfilter: query" class="" (click)="selectSplitDimention(dimention)" >{{ dimention.text }}</li>
</ul>
</div>
</div>
</div>
<div class="chart-container" >
<div class="report-nav" style="margin-top: 30px; margin-bottom: 30px;">
<ul class="nav nav-pills nav-justified">
<li class="reporting_nav"><a href="javascript:void(0)" class="plotgraph" data-label="Clicks" data-yparam="totalClicks">3.88M<span>Clicks</span></a></li>
<li class="reporting_nav active"><a href="javascript:void(0)" class="plotgraph" data-label="Conversions" data-yparam="totalConversions">742<span>Conversions</span></a></li>
<li class="reporting_nav"><a href="javascript:void(0)" class="plotgraph" data-label="Revenue" data-yparam="totalRevenueOg">$ 1.16k <span>Revenue</span></a></li>
<li class="reporting_nav"><a href="javascript:void(0)" class="plotgraph" data-label="Payout" data-yparam="totalRevenue">$ 823.43 <span>Payout</span></a></li>
<li class="reporting_nav"><a href="javascript:void(0)" class="plotgraph" data-label="CR" data-yparam="conversionRatio">0.02%<span>CR</span></a></li>
<li class="reporting_nav"><a href="javascript:void(0)" class="plotgraph" data-label="RPM" data-yparam="epc">$ 0.30<span>RPM</span></a></li>
<li class="reporting_nav" style="border-right:1px solid #eaeaea;"><a href="javascript:void(0)" class="plotgraph" data-label="Profit" data-yparam="profit">$ 341.15<span>Profit</span></a></li>
</ul>
</div>
<highcharts-chart
[Highcharts]="Highcharts"
[constructorType]="chartConstructor"
[options]="chartOptions"
[callbackFunction]="chartCallback"
[(update)]="updateFlag"
[oneToOne]="oneToOneFlag"
[runOutsideAngular]="runOutsideAngularFlag"
style="width: 100%; height: 350px; display: block;"
></highcharts-chart>
</div>
<div class="report-table-header" style="margin-top: 30px;" *ngIf="reportData.length > 0">
<div class="row report-row-header" >
<div class="col-4" style="padding-left: 5px;">#</div>
<div class="col-2">Impressions</div>
<div class="col-2">Conversion</div>
<div class="col-1">Bids</div>
<div class="col-1">Wins</div>
<div class="col-1">Cost</div>
<div class="col-1">Rev Payout</div>
</div>
</div>
<div class="report-table-container" >
<ng-container *ngFor="let rData of reportData; let i = index; last as isLast" >
<div class="row report-row" >
<div class="col-4" style="padding-left: 5px;">
<button
class="btn btn-sm"
*ngIf="checkIfHaveMoreSplits(this.splitOpt[0].id) !== 0 && rData.isCollapsed == true"
(click)="splitData(rowWiseFilterObj(rData,this.splitOpt[0].id),this.splitOpt[0].id,sFilters,splitOpt,i,rData,selectedDate)"
row="rData">+</button>
<button
class="btn btn-sm"
*ngIf="checkIfHaveMoreSplits(this.splitOpt[0].id) !== 0 && rData.isCollapsed == false"
(click)="removeDynamicComponent(rData,i)"
>-</button>
<span *ngIf="this.splitOpt[0].id !== '__time'">{{rData[this.splitOpt[0].id]}}</span>
<span *ngIf="this.splitOpt[0].id === '__time'">{{ rData[this.splitOpt[0].id] | date:'dd-MM-yyyy HH:mm:ss Z'}}</span>
</div>
<div class="col-2">{{convertToDecimals(rData.impressions,2)}}</div>
<div class="col-2">{{convertToDecimals(rData.conversions,2)}}</div>
<div class="col-1">{{convertToDecimals(rData.bids,2)}}</div>
<div class="col-1" >{{convertToDecimals(rData.wins,2)}}</div>
<div class="col-1">{{convertToDecimals(rData.cost,2)}}</div>
<div class="col-1">{{convertToDecimals(rData.rev_payout,2)}}</div>
</div>
<div *ngIf="isLast">{{altrows("#ffffff","#f5f5f5")}}</div>
<ng-template #dynamic ></ng-template>
</ng-container>
</div>
import {
Injectable,
ChangeDetectionStrategy,
ChangeDetectorRef,
Renderer2,
Inject,
QueryList,
ViewChildren,
} from '@angular/core';
import {
Subject
} from 'rxjs';
import {
Component,
OnInit,
ViewEncapsulation,
AfterViewInit,
Input,
Output,
ComponentFactoryResolver,
ViewChild,
ViewContainerRef,
Directive
} from '@angular/core';
import {
ModalDismissReasons,
NgbDateStruct,
NgbModal,
NgbRatingConfig
} from "@ng-bootstrap/ng-bootstrap";
import {
distinctUntilChanged,
debounceTime,
switchMap,
tap
} from 'rxjs/operators'
import {
Http,
RequestMethod,
RequestOptions,
Response,
ResponseOptions,
XHRBackend,
Headers
} from "@angular/http";
import {
ActivatedRoute
} from '@angular/router';
import {
ScriptLoaderService
} from '../_services/script-loader.service';
import {
ConfigService
} from '../_services/config.service';
import {
ApplicationApiService
} from '../_services/api.service';
import {
ToastrService
} from 'ngx-toastr';
import {
Helpers
} from '../helpers';
import swal from 'sweetalert2';
import {
Service
} from './service';
import * as moment from 'moment';
import { DaterangepickerComponent, DaterangepickerDirective } from 'ngx-daterangepicker-material';
import * as Highcharts from 'highcharts';
@Component({
selector: 'app-reports',
templateUrl: './template/reports.component.html',
encapsulation: ViewEncapsulation.None,
// changeDetection: ChangeDetectionStrategy.OnPush
})
@Injectable()
export class ReportsComponent implements OnInit, AfterViewInit {
filterSelection: any = false;
dimentionSelection: any = false;
splitSelection: any = false;
dValueSelection: any = false;
filterDimentions: any = [];
selectedDimentions: any = [];
filterDimentionsValues: any = [];
currentSelectedDimension: any = [];
appLoading: any = false;
query: any = '';
q: any = '';
sFilters: any = [];
splitOpt: any = [];
posX: any = 100;
posY: any = 100;
reportData: any = [];
service: any;
reportLoading:boolean = false;
selectedDate: any = {
startDate:moment(),
endDate:moment()
};
showRangeLabelOnInput: boolean = true;
alwaysShowCalendars: boolean = true;
keepCalendarOpeningWithRange: boolean = true;
ranges: any = {
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'Last 7 Days': [moment().subtract(6, 'days'), moment()],
'Last 30 Days': [moment().subtract(29, 'days'), moment()],
'This Month': [moment().startOf('month'), moment().endOf('month')],
'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
}
invalidDates: moment.Moment[] = [];
isInvalidDate = (m: moment.Moment) => {
return this.invalidDates.some(d => d.isSame(m, 'day') )
}
// chart
Highcharts = Highcharts; // required
chartConstructor = 'chart'; // optional string, defaults to 'chart'
chartOptions = {
chart: {
type: "area"
},
title: {
text: "Impressions"
},
plotOptions: {
area: {
fillColor: "rgba(92, 205, 222,0.2)",
lineColor: "#5ccdde",
},
series: {
marker: {
fillColor: '#FFFFFF',
lineWidth: 1,
lineColor: null // inherit from series
},
fillOpacity: 0.5
}
},
xAxis: {
categories: ["2018-10-16", "2018-10-17", "2018-10-18", "2018-10-19", "2018-10-20", "2018-10-21", "2018-10-22"],
},
yAxis: {
title: {
text: "Y"
},
},
tooltip: {
enabled: false
},
series: [{
name: "Impressions",
data: [21526628, 27342813, 15790662, 20631074, 20898211, 27230549, 3769183],
type: "area"
}]
};
@ViewChild(DaterangepickerDirective) pickerDirective: DaterangepickerDirective;
picker: DaterangepickerComponent;
@ViewChildren('dynamic', {
read: ViewContainerRef
}) viewContainerRef: QueryList < ViewContainerRef >
constructor(
private _script: ScriptLoaderService,
private _apis: ApplicationApiService,
private modalService: NgbModal,
private cfr: ComponentFactoryResolver,
private toastr: ToastrService,
private _configService: ConfigService,
private http: Http,
private cd: ChangeDetectorRef,
private activatedRoute: ActivatedRoute,
@Inject(Service) service,
) {
this.service = service
}
ngOnInit() {
this.picker = this.pickerDirective.picker;
}
ngAfterViewInit() {
Helpers.bodyClass('m-page--wide m-header--fixed m-header--fixed-mobile m-footer--push m-aside--offcanvas-default reports-page');
this._apis.getReportDimensions().subscribe(response => {
if (response.status == 1200) {
this.filterDimentions = response.data;
}
});
// this.cd.detach();
}
openFilterSelection(e) {
var xPos;
if (e.clientX > 1024) {
xPos = e.clientX - 250;
} else {
xPos = e.clientX
}
this.posX = xPos - 10 + "px";
this.posY = e.clientY + 10 + "px";
this.filterSelection = true
this.dimentionSelection = true;
this.dValueSelection = false;
}
openSplitSelection(e) {
var xPos;
if (e.clientX > 1024) {
xPos = e.clientX - 250;
} else {
xPos = e.clientX
}
this.posX = xPos - 10 + "px";
this.posY = e.clientY + 10 + "px";
this.splitSelection = true
this.dimentionSelection = true;
this.dValueSelection = false;
}
getFilterValues(d, e) {
if (e) {
var xPos;
if (e.clientX > 1024) {
xPos = e.clientX - 250;
} else {
xPos = e.clientX
}
this.posX = xPos - 10 + "px";
this.posY = e.clientY + 10 + "px";
}
this.filterDimentionsValues = [];
this.appLoading = true;
this.currentSelectedDimension = d.id;
var apiFilters: any = [{}];
var index = this.sFilters.findIndex(function(v) {
return v.id == d.id
});
if (index === -1) {
for (var i = 0; i < this.sFilters.length; i++) {
if (this.sFilters[i].values.length > 0) {
var k;
k = this.sFilters[i].id
apiFilters[0][k] = this.sFilters[i].values;
}
}
} else {
for (var i = 0; i < index; i++) {
if (this.sFilters[i].values.length > 0) {
var k;
k = this.sFilters[i].id
apiFilters[0][k] = this.sFilters[i].values;
}
}
}
delete apiFilters[0][d.id]
this._apis.getFilterDimentionValues(d.id, this.q, apiFilters[0],this.selectedDate).subscribe(response => {
if (response.status == 1200) {
this.filterDimentionsValues = response.data.split_by_data;
this.appLoading = false;
}
})
this.filterSelection = true
this.dValueSelection = true;
this.dimentionSelection = false;
}
onSearchChange() {
var apiFilters: any = [{}];
for (var i = 0; i < this.sFilters.length; i++) {
if (this.sFilters[i][0].values.length > 0) {
var k;
k = this.sFilters[i][0].id
apiFilters[0][k] = this.sFilters[i][0].values;
}
}
this._apis.getFilterDimentionValues(this.currentSelectedDimension, this.q, apiFilters[0],this.selectedDate).subscribe(response => {
if (response.status == 1200) {
this.filterDimentionsValues = response.data.split_by_data;
this.appLoading = false;
}
})
}
hidePopup() {
this.filterSelection = false
this.dValueSelection = false;
this.dimentionSelection = false;
this.splitSelection = false;
}
goBackToDimensions() {
this.filterSelection = true
this.dimentionSelection = true;
this.dValueSelection = false;
}
selectFilters(d) {
var a = this.currentSelectedDimension;
if (this.sFilters.filter(e => e.id === a).length > 0) {
this.sFilters.filter(function(v) {
if (v.id == a) {
if (!v.values.includes(d[a])) {
v.values.push(d[a])
} else {
var index = v.values.indexOf(d[a]);
if (index > -1) {
v.values.splice(index, 1);
}
}
}
});
} else {
let labelText;
for(var i=0; i<this.filterDimentions.length; i++) {
if(this.filterDimentions[i].id == this.currentSelectedDimension) {
labelText = this.filterDimentions[i].text;
}
}
var obj = {
id: this.currentSelectedDimension,
label: labelText,
values: [d[a]],
}
this.sFilters.push(obj)
}
this.sFilters = this.sFilters.filter(function(v) {
return v.values.length > 0;
});
}
checkIfDimvalueExists(d) {
var a = this.currentSelectedDimension;
if (this.sFilters.length > 0) {
var sel = this.sFilters.filter(function(v) {
if (v.id == a) {
return v
}
});
if (sel.length > 0) {
var index = sel[0]["values"].indexOf(d[a]);
return index;
} else {
return -1;
}
} else {
return -1;
}
}
arrToString(d) {
return d.toString()
}
selectSplitDimention(d) {
if (this.splitOpt.filter(e => e.id === d.id).length == 0) {
this.splitOpt.push(d);
if(this.splitOpt.length === 1){
this.getReport();
} if(this.splitOpt.length === 0){
this.reportData = [];
} else{
// do nothing
}
} else {
this.splitOpt = this.splitOpt.filter(function(obj) {
return obj.id !== d.id;
});
if(this.splitOpt.length === 0) {
this.reportData = [];
} else {
this.reportData = [];
this.getReport();
}
}
this.hidePopup();
}
getReport() {
this.hidePopup();
if(this.splitOpt.length === 0) {
return false;
}
var apiFilters: any = [{}];
for (var i = 0; i < this.sFilters.length; i++) {
if (this.sFilters[i].values.length > 0) {
var k;
k = this.sFilters[i].id
apiFilters[0][k] = this.sFilters[i].values
}
}
var split = this.splitOpt[0].id;
this.reportData=[];
this.reportLoading = true;
this._apis.getReportData(split, apiFilters[0],this.selectedDate).subscribe(response => {
if (response.status == 1200) {
this.reportData = response.data.split_by_data;
this.reportData.map(function(obj) {
obj.isCollapsed = true;
return obj;
});
this.reportLoading = false;
//this.cd.detectChanges();
}
});
}
checkIfHaveMoreSplits(c) {
if (this.splitOpt.length > 0) {
var index = this.splitOpt.findIndex(function(v) {
return v.id == c
})
if (typeof(this.splitOpt[index + 1]) != "undefined") {
return this.splitOpt[index + 1];
} else {
return 0;
}
}
}
splitData(obj, cSplit, sF, splitOptions, index,rowData,selectedDate) {
var nextSplit = this.checkIfHaveMoreSplits(cSplit);
this.service.setRootViewContainerRef(this.viewContainerRef.toArray()[index]);
this.service.addDynamicComponent(obj, nextSplit, sF, splitOptions,rowData,selectedDate);
}
removeDynamicComponent(rowData,index) {
this.viewContainerRef.toArray()[index].clear();
rowData.isCollapsed = true;
}
rowWiseFilterObj(row, split) {
var arr = [];
var obj = {
id: split,
label: split,
values: [row[split]]
}
arr.push(obj);
return arr;
}
convertToDecimals(input, decimals) {
var exp, rounded,
suffixes = ['K', 'M', 'B', 'T', 'P', 'E'];
if (input < 1000) {
return parseFloat(input).toFixed(2);;
}
exp = Math.floor(Math.log(input) / Math.log(1000));
return (input / Math.pow(1000, exp)).toFixed(decimals) + suffixes[exp - 1];
}
altrows(firstcolor,secondcolor)
{
var tableElements = document.getElementsByClassName("report-row") ;
for(var j = 0; j < tableElements.length; j++)
{
if(j%2==0){
(<any>tableElements[j]).style.backgroundColor = firstcolor ;
}
else{
(<any>tableElements[j]).style.backgroundColor = secondcolor ;
}
}
}
updateFilters(d,o) {
if(o === "s") {
this.splitOpt = this.splitOpt.filter(function(obj) {
return obj.id !== d.id;
});
if(this.splitOpt.length > 0){
this.getReport();
} else{
this.reportData = [];
}
}
if(o === "d") {
this.sFilters = this.sFilters.filter(function(obj) {
return obj.id !== d.id;
});
if(this.sFilters.length > 0){
this.getReport();
} else{
//this.reportData = [];
}
}
}
openDatePicker(e) {
this.pickerDirective.open(e);
}
datesUpdated(e) {
if(e.startDate != null && e.endDate != null) {
this.getReport();
}
}
}
import {
ComponentFactoryResolver,
Injectable,
Inject,
ReflectiveInjector
} from '@angular/core'
import {
Http,
RequestMethod,
RequestOptions,
Response,
ResponseOptions,
XHRBackend,
Headers
} from "@angular/http";
import {
Observable
} from 'rxjs';
import {
delay,
map
} from 'rxjs/operators';
import 'rxjs/Rx';
import {
ApplicationApiService
} from '../_services/api.service';
import {
DynamicComponent
} from './dynamic.component'
@Injectable()
export class Service {
factoryResolver;
rootViewContainer;
reportLoading: boolean = false;
constructor(
@Inject(ComponentFactoryResolver) factoryResolver,
private _apis: ApplicationApiService,
) {
this.factoryResolver = factoryResolver
}
setRootViewContainerRef(viewContainerRef) {
this.rootViewContainer = viewContainerRef
}
addDynamicComponent(selectedRow, nextSplit, selectedFilters, splitOptions, rowData, selectedDate) {
const factory = this.factoryResolver
.resolveComponentFactory(DynamicComponent)
const component = factory
.create(this.rootViewContainer.parentInjector)
component.instance.selectedRow = selectedRow;
component.instance.nextSplit = nextSplit;
component.instance.selectedFilters = selectedFilters;
component.instance.splitOptions = splitOptions;
component.instance.rowData = rowData;
component.instance.reportLoading = true;
component.instance.selectedDate = selectedDate;
var a = JSON.parse(JSON.stringify(selectedFilters));
var b = JSON.parse(JSON.stringify(selectedRow));
a.filter(function(o1) {
return b.some(function(o2) {
if (o1.id === o2.id) {
o1.values = o2.values;
}
});
});
//Find values that are in result1 but not in result2
var uniqueResultOne = a.filter(function(obj) {
return !b.some(function(obj2) {
return obj.id == obj2.id;
});
});
//Find values that are in result2 but not in result1
var uniqueResultTwo = b.filter(function(obj) {
return !a.some(function(obj2) {
return obj.id == obj2.id;
});
});
//Combine the two arrays of unique entries
var result = a.concat(uniqueResultOne.concat(uniqueResultTwo));
result = result.filter((s1, pos, arr) => arr.findIndex((s2) => s2.id === s1.id) === pos);
this.reportLoading = true;
this._apis.getReportData(nextSplit.id, this.getApiFilters(result), selectedDate).subscribe(response => {
if (response.status == 1200) {
response.data.split_by_data.map(function(obj) {
obj.isCollapsed = true;
return obj;
})
component.instance.splitByData = response.data.split_by_data;
component.instance.selectedDate = selectedDate;
component.instance.reportLoading = false;
rowData.isCollapsed = false;
}
})
this.rootViewContainer.insert(component.hostView)
}
getApiFilters(selectedFilters) {
var apiFilters: any = [{}];
for (var i = 0; i < selectedFilters.length; i++) {
if (selectedFilters[i].values.length > 0) {
var k;
k = selectedFilters[i].id
apiFilters[0][k] = selectedFilters[i].values
}
}
return apiFilters[0];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment