Skip to content

Commit 02ebd54

Browse files
committed
chore: add streaming data grid demo
1 parent 0415e63 commit 02ebd54

File tree

14 files changed

+16706
-15782
lines changed

14 files changed

+16706
-15782
lines changed

examples-standalone/kendoangular-landing-page/package-lock.json

Lines changed: 15760 additions & 15760 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples-standalone/kendoangular-landing-page/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"@progress/kendo-angular-progressbar": "18.5.2",
4141
"@progress/kendo-angular-scheduler": "^18.5.2",
4242
"@progress/kendo-angular-toolbar": "18.5.2",
43+
"@progress/kendo-angular-tooltip": "^18.5.2",
4344
"@progress/kendo-angular-treeview": "18.5.2",
4445
"@progress/kendo-angular-utils": "18.5.2",
4546
"@progress/kendo-data-query": "^1.0.0",
Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
1-
<div
2-
id="app"
3-
style="display: flex; flex-direction: column; width: 630px; height: 680px; margin-left: 7px; gap: 30px;"
4-
>
5-
<div>
6-
<app-transactions-dashboard></app-transactions-dashboard>
7-
</div>
8-
<div
9-
style="display: flex; flex-direction: row; justify-content: space-evenly; gap: 30px;"
10-
>
11-
<div style="max-height: 310px; flex: 1;">
12-
<app-bottom-left></app-bottom-left>
1+
<div id="app" style="display: flex; flex-direction: column; width: 630px; height: 680px; margin-left: 7px; gap: 30px">
2+
<div>
3+
<app-transactions-dashboard></app-transactions-dashboard>
134
</div>
14-
<div style="max-height: 310px; flex: 1;">
15-
<app-bottom-right></app-bottom-right>
5+
<div style="display: flex; flex-direction: row; justify-content: space-evenly; gap: 30px">
6+
<div style="max-height: 310px; flex: 1">
7+
<app-bottom-left></app-bottom-left>
8+
</div>
9+
<div style="max-height: 310px; flex: 1">
10+
<app-bottom-right></app-bottom-right>
11+
</div>
1612
</div>
17-
</div>
1813
</div>
19-
<!-- <app-scheduler></app-scheduler> -->
14+
<!-- <app-scheduler></app-scheduler> -->

examples-standalone/kendoangular-landing-page/src/app/app.routes.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ import { Routes } from '@angular/router';
22
import { TransactionsDashboardComponent } from './components/transactions-dashboard/transactions-dashboard.component';
33
import { BottomLeftComponent } from './components/bottom-left/bottom-left.component';
44
import { BottomRightComponent } from './components/bottom-right/bottom-right.component';
5+
import { DynamicGridComponent } from './components/dynamic-grid/dynamic-grid.component';
56

67
export const routes: Routes = [
7-
{ path: 'dashboard', component: TransactionsDashboardComponent },
8-
{ path: 'transactions', component: TransactionsDashboardComponent },
9-
{ path: 'bottom-left', component: BottomLeftComponent },
10-
{ path: 'bottom-right', component: BottomRightComponent },
11-
{ path: 'home', redirectTo: 'dashboard', pathMatch: 'full' },
12-
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' }
8+
{ path: 'dashboard', component: TransactionsDashboardComponent },
9+
{ path: 'transactions', component: TransactionsDashboardComponent },
10+
{ path: 'bottom-left', component: BottomLeftComponent },
11+
{ path: 'bottom-right', component: BottomRightComponent },
12+
{ path: 'grid', component: DynamicGridComponent },
13+
{ path: 'home', redirectTo: 'dashboard', pathMatch: 'full' },
14+
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
1315
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.grid-wrapper {
2+
display: flex;
3+
grid: auto auto / 1fr 1fr;
4+
grid-gap: 40px;
5+
justify-content: center;
6+
align-items: center;
7+
padding: 30px 0;
8+
}
9+
10+
.asset-type {
11+
display: flex;
12+
flex-direction: row;
13+
gap: 5px;
14+
align-items: center;
15+
}
16+
17+
.red {
18+
color: #f31700;
19+
}
20+
21+
.green {
22+
color: #37b400;
23+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<div class="grid-wrapper">
2+
<kendo-grid
3+
[data]="gridView"
4+
[height]="440"
5+
[rowHeight]="36"
6+
scrollable="virtual"
7+
[skip]="state.skip"
8+
[sort]="state.sort"
9+
[filter]="state.filter"
10+
[pageSize]="state.take"
11+
[columnMenu]="menuSettings"
12+
[sortable]="true"
13+
(dataStateChange)="dataStateChange($event)"
14+
>
15+
<ng-template kendoGridToolbarTemplate>
16+
<kendo-label [for]="gridSize" text="Rows: "></kendo-label>
17+
<kendo-dropdownlist
18+
#gridSize
19+
[data]="gridDataSize"
20+
[value]="currentGridDataSize"
21+
textField="text"
22+
valueField="value"
23+
kendoGridToolbarFocusable
24+
(valueChange)="onGridSizeChange($event)"
25+
>
26+
<ng-template kendoDropDownListItemTemplate let-dataItem>
27+
<span class="template">{{ dataItem.value | kendoNumber }}</span>
28+
</ng-template>
29+
</kendo-dropdownlist>
30+
<kendo-label class="k-display-block" [for]="slider" text="Refresh rate:"></kendo-label>
31+
<div kendoTooltip position="top" filter=".k-draghandle" [tooltipTemplate]="template">
32+
<kendo-slider
33+
kendoGridToolbarFocusable
34+
#slider
35+
tickPlacement="none"
36+
[min]="100"
37+
[max]="1000"
38+
[value]="refreshInterval"
39+
[showButtons]="false"
40+
[smallStep]="200"
41+
[largeStep]="500"
42+
(valueChange)="onRefreshIntervalChange($event)"
43+
></kendo-slider>
44+
</div>
45+
</ng-template>
46+
<kendo-grid-column title="Company" field="company">
47+
<ng-template kendoGridHeaderTemplate let-column>
48+
<strong>{{ column.title }}</strong>
49+
</ng-template>
50+
</kendo-grid-column>
51+
<kendo-grid-column title="Assets Type" field="assetType">
52+
<ng-template
53+
kendoGridFilterMenuTemplate
54+
let-column="column"
55+
let-filter="filter"
56+
let-filterService="filterService"
57+
>
58+
<app-multi-checkbox-filter
59+
[field]="column.field"
60+
[filterService]="filterService"
61+
[currentFilter]="filter"
62+
></app-multi-checkbox-filter>
63+
</ng-template>
64+
<ng-template kendoGridHeaderTemplate let-column>
65+
<strong>{{ column.title }}</strong>
66+
</ng-template>
67+
<ng-template kendoGridCellTemplate let-dataItem>
68+
<div class="asset-type">
69+
<span [innerHTML]="getAssetTypeIcon(dataItem.assetType)"></span>
70+
<span>{{ dataItem.assetType }}</span>
71+
</div>
72+
</ng-template>
73+
</kendo-grid-column>
74+
<kendo-grid-column title="Price" field="price" filter="numeric">
75+
<ng-template kendoGridHeaderTemplate let-column>
76+
<strong>{{ column.title }}</strong>
77+
</ng-template>
78+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
79+
<span>{{ dataItem.price | kendoNumber : 'c' }}</span>
80+
</ng-template>
81+
</kendo-grid-column>
82+
<kendo-grid-column title="Price Change" field="change" filter="numeric">
83+
<ng-template kendoGridHeaderTemplate let-column>
84+
<strong>{{ column.title }}</strong>
85+
</ng-template>
86+
<ng-template kendoGridCellTemplate let-dataItem>
87+
<kendo-svg-icon
88+
[icon]="dataItem.change > 0 ? positivePriceChangeIcon : negativePriceChangeIcon"
89+
[themeColor]="dataItem.change > 0 ? 'success' : 'error'"
90+
></kendo-svg-icon>
91+
<span [ngClass]="[dataItem.change > 0 ? 'green' : 'red']">{{ dataItem.change }}</span>
92+
</ng-template>
93+
</kendo-grid-column>
94+
<kendo-grid-column title="Timeline" field="timeline" [columnMenu]="false">
95+
<ng-template kendoGridHeaderTemplate let-column>
96+
<strong>{{ column.title }}</strong>
97+
</ng-template>
98+
<ng-template kendoGridCellTemplate let-dataItem>
99+
<kendo-sparkline
100+
[data]="dataItem.timeline"
101+
type="column"
102+
[seriesColors]="['#1274AC']"
103+
[chartArea]="{ background: 'transparent' }"
104+
[style.width.%]="100"
105+
>
106+
<ng-template kendoSparklineTooltipTemplate let-value="value">
107+
<span>{{ value | kendoNumber : 'c' }}</span>
108+
</ng-template>
109+
</kendo-sparkline>
110+
</ng-template>
111+
</kendo-grid-column>
112+
<kendo-grid-column title="Status" field="status">
113+
<ng-template kendoGridHeaderTemplate let-column>
114+
<strong>{{ column.title }}</strong>
115+
</ng-template>
116+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
117+
<kendo-chip rounded="full" [themeColor]="getThemeColor(dataItem.status)">{{
118+
dataItem.status
119+
}}</kendo-chip>
120+
</ng-template>
121+
</kendo-grid-column>
122+
</kendo-grid>
123+
</div>
124+
125+
<ng-template #template>
126+
<span>{{ refreshInterval + ' ms' }}</span>
127+
</ng-template>
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { Component, OnInit, OnDestroy } from '@angular/core';
2+
import { ChipThemeColor, KENDO_BUTTONS } from '@progress/kendo-angular-buttons';
3+
import { SVGIcon, caretAltDownIcon, caretAltUpIcon } from '@progress/kendo-svg-icons';
4+
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
5+
import { DataService } from '../../services/data.service';
6+
import { BehaviorSubject, Observable, Subject, Subscription, combineLatest } from 'rxjs';
7+
import { switchMap, takeUntil, tap, startWith } from 'rxjs/operators';
8+
import { FormsModule } from '@angular/forms';
9+
import { CommonModule } from '@angular/common';
10+
import { ColumnMenuSettings, DataStateChangeEvent, GridDataResult, KENDO_GRID } from '@progress/kendo-angular-grid';
11+
import { KENDO_DROPDOWNS } from '@progress/kendo-angular-dropdowns';
12+
import { KENDO_INPUTS } from '@progress/kendo-angular-inputs';
13+
import { KENDO_CHARTS } from '@progress/kendo-angular-charts';
14+
import { KENDO_LABELS } from '@progress/kendo-angular-label';
15+
import { IntlModule } from '@progress/kendo-angular-intl';
16+
import { KENDO_ICONS } from '@progress/kendo-angular-icons';
17+
import { KENDO_TOOLTIPS } from '@progress/kendo-angular-tooltip';
18+
import { cashIcon, goldIcon, realEstateIcon, securitiesIcon } from '../../data/custom-icons';
19+
import { DynamicGridItem } from '../../models/dynamic-grid-item';
20+
import { State } from '@progress/kendo-data-query';
21+
import { MultiCheckboxFilterComponent } from './multi-checkbox-filter/multi-checkbox-filter.component';
22+
23+
@Component({
24+
selector: 'app-dynamic-grid',
25+
standalone: true,
26+
imports: [
27+
FormsModule,
28+
CommonModule,
29+
KENDO_GRID,
30+
KENDO_DROPDOWNS,
31+
KENDO_INPUTS,
32+
KENDO_CHARTS,
33+
KENDO_BUTTONS,
34+
KENDO_LABELS,
35+
KENDO_TOOLTIPS,
36+
KENDO_ICONS,
37+
IntlModule,
38+
MultiCheckboxFilterComponent,
39+
],
40+
templateUrl: './dynamic-grid.component.html',
41+
styleUrl: './dynamic-grid.component.css',
42+
})
43+
export class DynamicGridComponent {
44+
public gridView!: GridDataResult;
45+
public refreshInterval: number = 100;
46+
public currentGridDataSize: { text: string; value: number } = { text: '100', value: 100 };
47+
public positivePriceChangeIcon: SVGIcon = caretAltUpIcon;
48+
public negativePriceChangeIcon: SVGIcon = caretAltDownIcon;
49+
50+
private dataSubscription!: Subscription;
51+
52+
public gridDataSize: { text: string; value: number }[] = [
53+
{ text: '100', value: 100 },
54+
{ text: '5000', value: 5000 },
55+
{ text: '50000', value: 50000 },
56+
{ text: '100000', value: 100000 },
57+
];
58+
public state: State = {
59+
skip: 0,
60+
take: 50,
61+
sort: [],
62+
group: [],
63+
filter: {
64+
logic: 'and',
65+
filters: [],
66+
},
67+
};
68+
public menuSettings: ColumnMenuSettings = {
69+
filter: true,
70+
sort: true,
71+
columnChooser: false,
72+
};
73+
74+
constructor(private domSanitizer: DomSanitizer, private dataService: DataService) {}
75+
76+
ngOnInit(): void {
77+
this.dataSubscription = this.dataService.fetchData(this.state).subscribe((result) => {
78+
this.gridView = result;
79+
});
80+
}
81+
82+
ngOnDestroy(): void {
83+
if (this.dataSubscription) {
84+
this.dataSubscription.unsubscribe();
85+
}
86+
}
87+
88+
public dataStateChange(state: DataStateChangeEvent): void {
89+
this.state = state;
90+
this.dataService.updateGridState(state);
91+
}
92+
93+
public onGridSizeChange(event: { text: string; value: number }): void {
94+
this.currentGridDataSize = event;
95+
this.dataService.updateTotalRecords(event.value);
96+
}
97+
98+
public onRefreshIntervalChange(event: number): void {
99+
this.refreshInterval = event;
100+
this.dataService.updateRefreshInterval(event);
101+
}
102+
103+
public getThemeColor(status: string): ChipThemeColor {
104+
switch (status) {
105+
case 'Filled':
106+
return 'info';
107+
case 'Open':
108+
return 'success';
109+
case 'Rejected':
110+
return 'error';
111+
default:
112+
return 'base';
113+
}
114+
}
115+
116+
public getAssetTypeIcon(assetType: string): SafeHtml {
117+
if (assetType === 'Real Estate') {
118+
return this.domSanitizer.bypassSecurityTrustHtml(realEstateIcon);
119+
} else if (assetType === 'Securities') {
120+
return this.domSanitizer.bypassSecurityTrustHtml(securitiesIcon);
121+
} else if (assetType === 'Cash') {
122+
return this.domSanitizer.bypassSecurityTrustHtml(cashIcon);
123+
} else if (assetType === 'Gold') {
124+
return this.domSanitizer.bypassSecurityTrustHtml(goldIcon);
125+
}
126+
return '';
127+
}
128+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.wrapper {
2+
padding: 1px;
3+
display: flex;
4+
flex-direction: column;
5+
gap: 7px;
6+
}
7+
8+
.items-wrapper {
9+
display: flex;
10+
flex-direction: column;
11+
gap: 5px;
12+
}
13+
14+
.item {
15+
display: flex;
16+
gap: 4px;
17+
flex-direction: row;
18+
align-items: center;
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<div class="wrapper">
2+
<div>
3+
<kendo-textbox rounded="none" (valueChange)="valueChange($event)">
4+
<ng-template kendoTextBoxPrefixTemplate>
5+
<kendo-svgicon [icon]="searchIcon"></kendo-svgicon>
6+
</ng-template>
7+
</kendo-textbox>
8+
</div>
9+
<div class="items-wrapper">
10+
@for (item of currentData; track item; let i = $index) {
11+
<div class="item">
12+
<kendo-checkbox
13+
#notification
14+
kendoCheckBox
15+
[checkedState]="isItemSelected(item)"
16+
(checkedStateChange)="onSelectionChange(item)"
17+
></kendo-checkbox>
18+
<kendo-label [for]="notification" [text]="item"></kendo-label>
19+
</div>
20+
}
21+
</div>
22+
</div>

0 commit comments

Comments
 (0)