2 |
3 |
Lazy Loading Data
4 |
This is an example of lazy loading data. There are about 100 customer and
5 | the page initially loads 10 customer.
6 | When you scroll to bottom it loads another 10, till it loads all the 100 customer
7 |
8 |
9 |
20 |
21 |
22 |
Loading...
23 |
24 |
--------------------------------------------------------------------------------
/webui/src/app/pages/customers/customers.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit,TemplateRef, ViewChild,HostListener } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { CustomerService } from '../../services/api/customer.service';
4 |
5 | @Component({
6 | selector: 's-customers-pg',
7 | templateUrl: './customers.component.html',
8 | styleUrls: [ './customers.scss'],
9 | })
10 |
11 | export class CustomersComponent implements OnInit {
12 |
13 |
14 |
15 | columns:any[];
16 | rows:any[];
17 | pageSize:number=10;
18 | currentPage:number=0;
19 | isLastPageLoaded:boolean=false;
20 | isLoading:boolean=false;
21 |
22 | constructor(private router: Router, private customerService: CustomerService) { }
23 |
24 | ngOnInit() {
25 | let me = this;
26 | me.getPageData();
27 |
28 | this.columns=[
29 | {prop:"id" , name: "ID" , width:50 },
30 | {prop:"firstName", name: "First Name" , width:120 },
31 | {prop:"lastName" , name: "Last Name" , width:120 },
32 | {prop:"company" , name: "Company" , width:120 },
33 | {prop:"email" , name: "Email" , width:200 },
34 | {prop:"phone" , name: "Phone" , width:160 },
35 | {prop:"address" , name: "Address" , width:220 },
36 | ];
37 | }
38 |
39 | getPageData(isAppend:boolean=false) {
40 |
41 | if (this.isLastPageLoaded===false){
42 | let me = this;
43 | me.isLoading=true;
44 | this.customerService.getCustomers(this.currentPage,this.pageSize).subscribe((data) => {
45 | me.isLastPageLoaded=data.last;
46 | me.currentPage = data.currentPageNumber+1;
47 | if (isAppend===true){
48 | me.rows = me.rows.concat(data.items);
49 | }
50 | else{
51 | me.rows = data.items;
52 | }
53 | me.isLoading=false;
54 | });
55 | }
56 | }
57 |
58 | onScroll() {
59 | console.log("bottom")
60 | if (this.isLoading===false){
61 | this.getPageData(true);
62 | }
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/webui/src/app/pages/customers/customers.scss:
--------------------------------------------------------------------------------
1 | @import '../../../assets/scss/var';
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/webui/src/app/pages/dashboard/dashboard.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Orders by Status
4 |
10 |
11 |
12 |
13 |
14 |
Orders By Payment Type
15 |
21 |
22 |
23 |
24 |
25 |
Orders By Country
26 |
38 |
39 |
40 |
41 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/webui/src/app/pages/order_stats/order_stats.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { OrderService } from '../../services/api/order.service';
3 | import { Router } from '@angular/router';
4 | import { NgxChartsModule} from '@swimlane/ngx-charts';
5 | import 'rxjs/add/operator/mergeMap';
6 |
7 |
8 | @Component({
9 | selector: 's-order_stats-pg',
10 | templateUrl: './order_stats.component.html',
11 | styleUrls: [ './order_stats.scss'],
12 | })
13 |
14 | export class OrderStatsComponent implements OnInit {
15 | view: any[] = [460, 180];
16 | ordersByStatusData : any[] = [];
17 | ordersByPaymentData: any[] = [];
18 | ordersByCountryData: any[] = [];
19 | colorScheme = {
20 | domain: ['#007cbb', '#61c673', '#ff8e28', '#ef2e2e']
21 | };
22 | barColorScheme = {
23 | domain: ['#007cbb']
24 | }
25 |
26 | constructor(private router: Router, private orderService: OrderService) { }
27 |
28 | ngOnInit() {
29 | var me = this;
30 | this.getPageData()
31 | }
32 |
33 | getPageData() {
34 | var me = this;
35 |
36 | /**
37 | * This is an Example of sequencing RxJS observable using mergeMap
38 | * (We are sequencing the API calls as the H2 DB used by the backend is failing to serve multiple request at once)
39 | */
40 | me.orderService.getOrderStats("status")
41 | .mergeMap(function(statusData) {
42 | me.ordersByStatusData = statusData.items;
43 | console.log("Received Orders By Status");
44 | return me.orderService.getOrderStats("paytype");
45 | }).mergeMap( function(payTypeData) {
46 | me.ordersByPaymentData = payTypeData.items;
47 | console.log("Received Orders By Payment Type");
48 | return me.orderService.getOrderStats("country")
49 | }).subscribe(function(countryData){
50 | me.ordersByCountryData = countryData.items;
51 | console.log("Received Orders By Country");
52 | });
53 | }
54 |
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/webui/src/app/pages/order_stats/order_stats.scss:
--------------------------------------------------------------------------------
1 | @import '../../../assets/scss/var';
2 | h4{margin-top: 16px;}
3 | .s-order-dash-pg {
4 | margin: 0px;
5 | display:flex;
6 | flex-wrap:wrap;
7 | flex-direction:row;
8 | justify-content:center;
9 | .chart-box{
10 | margin:16px;
11 | padding:0 16px;
12 | background-color: #fff;
13 | border:1px solid #ccc;
14 | border-radius: 2px;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/webui/src/app/pages/orders/orders.component.html:
--------------------------------------------------------------------------------
1 |
2 |
Large Dataset with - Dynamic DOM
3 |
Here we are loading about 600 rows in one ajax call.
4 | However to keep the DOM footprint low we don not create those many DOM elements.
5 | As the user scrolls up and down , DOM elements are added and removed based on the data in memory.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
28 |
29 |
Loading...
30 |
31 |
32 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |