src/app/apm/collection/collection.component.ts
| selector | apm-collection |
| styleUrls | ./collection.component.scss |
| templateUrl | ./collection.component.html |
Properties |
Methods |
constructor(service: CollectionService, datePipe: DatePipe)
|
|||||||||
|
Parameters :
|
| ngOnInit |
ngOnInit()
|
|
Returns :
void
|
| onRowClicked | ||||
onRowClicked(row)
|
||||
|
Parameters :
Returns :
void
|
| onSearchTriggered | ||||
onSearchTriggered(event)
|
||||
|
Parameters :
Returns :
void
|
| body_size |
Type : number
|
Default value : 0
|
| colorScheme |
Type : object
|
Default value : {
domain: ['#5AA454', '#A10A28', '#C7B42C', '#AAAAAA']
}
|
| count |
Type : number
|
Default value : 0
|
| dataChart |
Type : any
|
Default value : []
|
| dataSource |
Type : any
|
Default value : new MatTableDataSource([])
|
| devicesDataSource |
Type : []
|
Default value : []
|
| displayedColumns |
Type : string[]
|
Default value : [
'url',
'method',
'duration',
'decoded_body_size',
'options',
'call_url',
'create_time'
]
|
| duration |
Type : string
|
Default value : '0'
|
| eventDataSource |
Type : []
|
Default value : []
|
| gradient |
Default value : false
|
| isLoadingResults |
Default value : true
|
| isRateLimitReached |
Default value : false
|
| paginator |
Type : MatPaginator
|
Decorators :
@ViewChild(MatPaginator, {static: true})
|
| resultsLength |
Type : number
|
Default value : 0
|
| search |
Type : SearchComponent
|
Decorators :
@ViewChild(SearchComponent, {static: true})
|
| showLegend |
Default value : false
|
| showXAxis |
Default value : true
|
| showXAxisLabel |
Default value : true
|
| showYAxis |
Default value : true
|
| showYAxisLabel |
Default value : true
|
| sidenav |
Type : MatSidenav
|
Decorators :
@ViewChild(MatSidenav, {static: true})
|
| xAxisLabel |
Type : string
|
Default value : 'Country'
|
| yAxisLabel |
Type : string
|
Default value : 'Population'
|
import { Component, OnInit, ViewChild } from '@angular/core';
import { DatePipe } from '@angular/common';
import {
MatPaginator,
MatTableDataSource,
MatSidenav
} from '@angular/material';
import { SelectionModel } from '@angular/cdk/collections';
import { merge, of as observableOf } from 'rxjs';
import { catchError, map, startWith, switchMap } from 'rxjs/operators';
import { SearchComponent } from '../../component';
import { CollectionService } from './collection.service';
@Component({
selector: 'apm-collection',
templateUrl: './collection.component.html',
styleUrls: ['./collection.component.scss']
})
export class CollectionComponent implements OnInit {
displayedColumns: string[] = [
'url',
'method',
'duration',
'decoded_body_size',
'options',
'call_url',
'create_time'
];
dataSource: any = new MatTableDataSource([]);
resultsLength = 0;
isLoadingResults = true;
isRateLimitReached = false;
devicesDataSource = [];
eventDataSource = [];
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@ViewChild(MatSidenav, { static: true }) sidenav: MatSidenav;
@ViewChild(SearchComponent, { static: true }) search: SearchComponent;
body_size = 0;
count = 0;
duration = '0';
// chart
dataChart: any = [];
showXAxis = true;
showYAxis = true;
gradient = false;
showLegend = false;
showXAxisLabel = true;
xAxisLabel = 'Country';
showYAxisLabel = true;
yAxisLabel = 'Population';
colorScheme = {
domain: ['#5AA454', '#A10A28', '#C7B42C', '#AAAAAA']
};
constructor(private service: CollectionService, private datePipe: DatePipe) { }
ngOnInit() {
this.search.onSearch.subscribe(() => (this.paginator.pageIndex = 0));
merge(this.search.onSearch, this.paginator.page)
.pipe(
startWith({}),
switchMap(search => {
return this.service.getList(this.paginator.pageIndex, search);
}),
map(data => {
this.isLoadingResults = false;
this.isRateLimitReached = false;
this.resultsLength = data.data.totalNum;
this.resultsLength = 40;
return data.data.datalist;
}),
catchError(() => {
this.isLoadingResults = false;
this.isRateLimitReached = true;
return observableOf([]);
})
)
.subscribe(data => {
this.dataSource = data;
data.map(d => {
this.dataChart.push({
name: this.datePipe.transform(d.create_time, 'yyyy-MM-dd hh:mm:ss'),
value: d.duration
});
});
});
this.service.getCount().subscribe(res => {
this.body_size = res.data.body_size;
this.count = res.data.count;
this.duration = parseFloat(res.data.duration).toFixed(2);
});
}
onRowClicked(row) {
this.sidenav.open();
this.eventDataSource = [
{
name: 'AJAX地址',
value: row.call_url
},
{
name: '请求耗时',
value: row.duration
},
{
name: '请求方式',
value: row.method
},
{
name: '请求参数',
value: row.options
},
{
name: '速度类型',
value: row.speed_type
},
{
name: 'body大小',
value: row.decoded_body_size
},
{
name: '所属URL',
value: row.url
},
{
name: '完整URL',
value: row.full_url
},
{
name: '生成时间',
value: this.datePipe.transform(row.create_time, 'yyyy-MM-dd hh:mm:ss')
}
];
this.devicesDataSource = [
{
name: 'IP地址',
value: ''
},
{
name: '来源城市',
value: ''
},
{
name: '浏览器',
value: ''
},
{
name: '操作系统',
value: ''
},
{
name: 'language',
value: ''
},
{
name: 'userAgent',
value: ''
}
];
}
onSearchTriggered(event) { }
}
<mat-sidenav-container class="collection-container">
<mat-sidenav #sidenav mode="over" position="end">
<!-- <button mat-icon-button (click)="sidenav.toggle()">
<mat-icon>close</mat-icon>
</button> -->
<apm-collection-detail
[eventDataSource]="eventDataSource"
[devicesDataSource]="devicesDataSource"
></apm-collection-detail>
</mat-sidenav>
<mat-sidenav-content>
<div fxLayout="row wrap" fxLayoutGap="12px grid">
<div fxFlex.gt-xs="33.33" fxFlex.lt-md="50" fxFlex.lt-sm="100">
<stb-widget-state
[value]="duration"
icon="group_add"
backgroundcolor="linear-gradient(-134deg, #8C99E0 0%, #6572B8 100%)"
textcolor="white"
property="响应平均耗时"
changeicon="trending_up"
valuesubfix="ms"
></stb-widget-state>
</div>
<div fxFlex.gt-xs="33.33" fxFlex.lt-md="50" fxFlex.lt-sm="100">
<stb-widget-state
[value]="count"
icon="pageview"
backgroundcolor="linear-gradient(-134deg, #4DD0E2 0%, #4CA8BA 100%)"
textcolor="white"
property="调用次数"
changeicon="trending_up"
valuesubfix="次"
></stb-widget-state>
</div>
<div fxFlex.gt-xs="33.33" fxFlex.lt-md="50" fxFlex.lt-sm="100">
<stb-widget-state
[value]="body_size"
icon="monetization_on"
backgroundcolor="linear-gradient(-134deg, #81C683 0%, #62A864 100%)"
textcolor="white"
property="Body大小"
changeicon="trending_down"
></stb-widget-state>
</div>
</div>
<mat-card class="m-b-20 m-t-20">
<mat-card-header>
<mat-card-title>性能分析</mat-card-title>
</mat-card-header>
<mat-card-content class="chart-container">
<ngx-charts-bar-vertical
*ngIf="dataChart?.length"
[results]="dataChart"
[gradient]="gradient"
[xAxis]="showXAxis"
[yAxis]="showYAxis"
[legend]="showLegend"
[showXAxisLabel]="showXAxisLabel"
[showYAxisLabel]="showYAxisLabel"
>
</ngx-charts-bar-vertical>
</mat-card-content>
</mat-card>
<stbui-search
placeholder="输入过滤条件"
class="mat-elevation-z4 m-b-16"
(onSearch)="onSearchTriggered($event)"
>
</stbui-search>
<div class="mat-elevation-z4">
<div class="table-container">
<table class="table-hover" mat-table [dataSource]="dataSource">
<ng-container matColumnDef="url">
<th mat-header-cell *matHeaderCellDef>API地址</th>
<td mat-cell *matCellDef="let element">{{ element.url }}</td>
</ng-container>
<ng-container matColumnDef="method">
<th mat-header-cell *matHeaderCellDef>请求方式</th>
<td mat-cell *matCellDef="let element">{{ element.method }}</td>
</ng-container>
<ng-container matColumnDef="duration">
<th mat-header-cell *matHeaderCellDef>请求耗时</th>
<td mat-cell *matCellDef="let element">{{ element.duration }}</td>
</ng-container>
<ng-container matColumnDef="decoded_body_size">
<th mat-header-cell *matHeaderCellDef>资源大小</th>
<td mat-cell *matCellDef="let element">
{{ element.decoded_body_size }}
</td>
</ng-container>
<ng-container matColumnDef="options">
<th mat-header-cell *matHeaderCellDef>请求参数</th>
<td mat-cell *matCellDef="let element">{{ element.options }}</td>
</ng-container>
<ng-container matColumnDef="call_url">
<th mat-header-cell *matHeaderCellDef>调用页面</th>
<td mat-cell *matCellDef="let element">{{ element.call_url }}</td>
</ng-container>
<ng-container matColumnDef="create_time">
<th mat-header-cell *matHeaderCellDef>请求时间</th>
<td mat-cell *matCellDef="let element">
{{ element.create_time | date: 'yyyy-MM-dd hh:mm:ss' }}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: displayedColumns"
(click)="onRowClicked(row)"
></tr>
</table>
</div>
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
</div>
</mat-sidenav-content>
</mat-sidenav-container>
./collection.component.scss
.collection-container {
display: flex;
flex-direction: column;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
mat-sidenav-content {
padding: 24px;
}
}
.table-container {
position: relative;
overflow: auto;
}
table {
width: 100%;
}
.chart-container {
min-height: 400px;
}