Angular Material 및 ng2-Charts로 반응형 대시보드 만들기
게시 됨: 2022-03-10대시보드를 처음부터 만드는 것은 종종 매우 복잡합니다. 관심 항목에 대한 데이터를 수집하는 도구를 만들어야 합니다. 수집된 데이터는 사용자에게 이해하기 쉽고 의미 있는 방식으로 제공되어야 합니다. 여기에는 포함할 데이터와 이를 효과적으로 표시하는 방법에 대한 복잡한 계획이 포함됩니다. 일단 계획이 있으면 설계를 구현하는 것은 특히 여러 구성 요소를 구축해야 하기 때문에 엄청난 작업입니다.
Angular Material 및 ng2-charts를 사용하면 회로도를 활용하여 대시보드를 구축하는 데 드는 노력과 시간을 줄일 수 있습니다. Angular Material은 대시보드를 생성하는 데 사용할 수 있는 여러 회로도와 함께 제공됩니다. 마찬가지로 ng2-charts는 여러 차트 구성 요소를 생성하기 위한 회로도를 제공합니다. 이 기사에서는 ng2-charts와 Angular Material을 모두 사용하여 대시보드를 상당히 빠르게 설정하는 방법을 설명합니다.
예
대시보드를 구축하는 방법을 설명하기 위해 가방, 지갑, 키 홀더 등과 같은 가죽 제품을 판매하는 온라인 상점의 예를 들어보겠습니다. 상점 소유자는 고객이 온라인 상점을 방문하는 위치, 제품 판매 방법, 트래픽 소스가 판매와 어떤 관련이 있는지 등의 정보를 추적하려고 합니다.
이 정보를 표시하고 상점 소유자가 이를 분석하는 데 도움이 되는 대시보드를 작성합니다. 대시보드에는 4개의 작은 요약 카드, 4가지 다른 종류의 차트 및 가장 최근 주문을 나열하는 테이블이 포함됩니다. 4개의 요약 카드에는 총 판매 수익, 평균 주문 금액, 총 주문 수 및 재방문 고객 수와 같은 정보가 표시됩니다. 차트에는 각 제품의 판매 단위 수, 트래픽 소스별 판매, 시간 경과에 따른 온라인 상점 세션 및 해당 주의 판매가 표시됩니다.
전제 조건
따라 하려면 Angular CLI가 설치되어 있어야 합니다. 설치하지 않은 경우 cli.angular.io에서 다운로드하는 방법을 찾을 수 있습니다. 기존 Angular 프로젝트에서 시작하지 않는 경우 ng new <your project name>
을 실행하여 프로젝트를 생성해야 합니다. 예를 들어, 앞서 언급한 스토어에 대한 관리자 패널을 생성하려면 다음을 실행합니다.
ng new store-admin-panel
또한 프로젝트에는 경로가 구성되어 있어야 합니다. 새 앱에서 시작하는 경우 위의 프로젝트 설정 중에 Angular Routing 모듈을 추가할지 여부를 묻는 메시지가 표시되면 예 를 선택합니다.
프로젝트에 Angular Material 및 Ng2-Charts 추가
Angular Material은 주소록, 트리, 테이블, 탐색 등과 같은 다양한 유용한 구성 요소를 생성하기 위한 다양한 회로도와 함께 제공됩니다. 프로젝트에 Angular Material을 추가하려면 다음을 실행하십시오.
ng add @angular/material
후속 프롬프트에 제공된 옵션에서 테마를 선택합니다. 다음으로 Angular Material 타이포그래피 스타일과 브라우저 애니메이션을 추가할지 여부를 선택하라는 메시지가 표시됩니다. 당신은 이것들이 필요하지 않으며 그냥 아니오라고 대답할 수 있습니다.
다음으로 ng2-charts를 설치해야 합니다. ng2-charts는 종속성으로 chart.js 가 필요합니다. ng2-charts를 설치하려면 다음을 실행하십시오.
npm install ng2-charts --save
그런 다음 chart.js를 설치합니다.
npm install chart.js --save
차트에 액세스하려면 ChartsModule
을 AppModule
의 가져오기에 추가하십시오.
import { ChartsModule } from 'ng2-charts'; @NgModule({ imports: [ … ChartsModule, … ] })
마지막으로 기본적으로 ng2-charts와 함께 제공되지 않으므로 ng2-charts 회로도를 개발 종속성으로 설치합니다.
npm install --save-dev ng2-charts-schematics
탐색 구성 요소 생성
먼저 사용자가 앱을 편안하게 탐색할 수 있도록 탐색 구성 요소를 추가해야 합니다. 탐색에는 대시보드 및 관리자 패널의 일부가 될 기타 페이지에 대한 링크가 포함되어야 합니다. Angular 재질은 탐색 구성 요소를 생성하는 회로도를 제공합니다. 이 구성 요소의 이름을 nav
로 지정하겠습니다. 애플리케이션에 사이드 탐색을 추가하려면 다음을 실행합니다.
ng generate @angular/material:navigation nav
탐색에서 다른 경로를 연결하려면 routerLink
지시문을 사용하고 사용자가 있는 경로에 따라 도구 모음에서 페이지 이름을 변경합니다.
// nav.component.ts ... menuItems = ['dashboard', 'sales', 'orders', 'customers', 'products'];
<!--nav.component.html--> ... <mat-nav-list> <a *ngFor="let item of menuItems" mat-list-item [routerLink]="'/'+item"> {{item | titlecase}} </a> ...
이 구성요소를 보려면 app.component.html
에 추가하십시오.
<!--app.component.html--> <app-nav></app-nav>
이것은 NavComponent
의 모습입니다.
탐색은 다른 구성 요소와 함께 표시되므로 여기에 router-outlet
를 추가하면 다른 구성 요소 간에 전환하는 데 도움이 됩니다. nav.component.html
템플릿에서 </mat-toolbar>
를 닫은 직후 <!-- Add Content Here -->
주석을 <router-outlet></router-outlet>
.
<!--nav.component.html--> <mat-sidenav-container> ... <mat-sidenav-content> <mat-toolbar> ... </mat-toolbar> <router-outlet></router-outlet> </mat-sidenav-content> </mat-sidenav-container>
이 문서의 다음 스크린샷에서 이 탐색 구성 요소는 자습서를 위해 생성할 대시보드를 더 잘 강조 표시하기 위해 생략됩니다. 이 대시보드를 구축하는 동안 따라가는 경우, 탐색은 여전히 대시보드와 함께 위의 그림과 같이 브라우저에 표시됩니다.
대시보드 생성
대시보드에서 가장 중요한 부분은 레이아웃입니다. 앞서 언급한 모든 구성 요소를 보유해야 하며 다른 장치에 표시될 때 응답해야 합니다. 대시보드 레이아웃을 생성하려면 @angular/material:dashboard
회로도를 실행해야 합니다. 반응형 대시보드 구성 요소를 생성합니다. 대시보드의 기본 이름을 회로도에 전달합니다. 이 경우 이름을 dash
로 지정하겠습니다.
ng generate @angular/material:dashboard dash
탐색 구성 요소 내에서 새로 생성된 대시보드를 보려면 라우터에 대한 경로를 추가하십시오.
// app-routing.module.ts import { DashComponent } from './dash/dash.component'; const routes: Routes = [{ path: 'dashboard', component: DashComponent }]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] })
완료되면 결과를 보려면 npm start
를 실행하고 localhost:4200/dashboard
로 이동합니다. 다음 내용이 표시되어야 합니다.
회로도는 템플릿에서 4개의 카드를 생성하고 반응형 그리드에 표시합니다. Angular Material CDK는 Layout
패키지를 사용하여 이 반응형 카드 그리드의 스타일을 지정합니다. Layout
패키지의 BreakpointObserver
유틸리티는 미디어 쿼리를 평가하고 이를 기반으로 UI를 변경합니다. 사용 가능한 다양한 중단점이 있지만 생성된 구성 요소 내에서는 두 가지 범주만 제공됩니다. Breakpoints.Handset
및 일치하지 않는 기타 쿼리. Layout
패키지는 대시보드의 응답성을 사용자 지정하는 데 사용할 수 있는 14개의 중단점 상태를 지정합니다.
// dashboard.component.js ... cards = this.breakpointObserver.observe(Breakpoints.Handset).pipe( map(({ matches }) => { if (matches) { ... } ... }) );
대시보드로 돌아가서 4개의 요약 카드, 4개의 차트 및 테이블이 대시보드에 있으므로 총 9개의 카드가 필요합니다. Breakpoints.Handset
및 Breakpoints.Tablet
일치 항목은 다음과 같은 1열 그리드에 표시됩니다.
- 4개의 요약 카드는 한 행에 걸쳐 있습니다.
- 차트는 두 행에 걸쳐 있습니다.
- 테이블은 4개의 행에 걸쳐 있습니다.
Non- Breakpoints.Handset
및 non- Breakpoints.Tablet
일치는 다음과 같은 4개의 열에 표시됩니다.
- 4개의 요약 카드는 하나의 행과 하나의 열에 걸쳐 있습니다.
- 차트는 두 개의 행과 두 개의 열에 걸쳐 있습니다.
- 테이블은 4개의 행과 4개의 열에 걸쳐 있습니다.
비 Breakpoints.Handset
및 비 Breakpoints.Tablet
일치에서 아래 스크린샷과 같아야 합니다. Breakpoints.Handset
및 Breakpoints.Tablet
일치 시 모든 항목이 한 열에 표시됩니다.
카드 구성 요소 만들기
대시보드 구성 요소에서 모든 카드는 반복을 통해 생성됩니다. 반복을 방지하기 위해 모든 새 구성 요소를 추가할 때 재사용 가능한 카드 구성 요소를 만듭니다. 카드 구성 요소는 제목을 입력으로 받아들이고 ng-content
를 사용하여 나머지 콘텐츠를 동적으로 추가합니다. 카드 구성 요소를 만들려면 다음을 실행합니다.
ng gc card -m app --style css
대시보드 구성 요소 템플릿에서 <mat-card>
태그 안에 포함된 마크업을 가져와서 카드 템플릿에 배치합니다.
<!--card.component.html--> <mat-card class="dashboard-card"> <mat-card-header> <mat-card-title> {{title}} <button mat-icon-button class="more-button" [matMenuTriggerFor]="menu" aria-label="Toggle menu"> <mat-icon>more_vert</mat-icon> </button> <mat-menu #menu="matMenu" xPosition="before"> <button mat-menu-item>Expand</button> <button mat-menu-item>Remove</button> </mat-menu> </mat-card-title> </mat-card-header> <mat-card-content class="dashboard-card-content"> <ng-content></ng-content> </mat-card-content> </mat-card>
카드에 제목을 입력으로 추가하려면:
// card.component.ts import { Component, Input } from '@angular/core'; ... export class CardComponent{ @Input() title: string; ... }
카드 스타일을 지정하려면:
/*card.component.css*/ .more-button { position: absolute; top: 5px; right: 10px; } .dashboard-card { position: absolute; top: 15px; left: 15px; right: 15px; bottom: 15px; } .dashboard-card-content { text-align: center; flex-grow: 1; display: flex; flex-direction: column; align-items: center; max-height: 100%; justify-content: center; align-items: stretch; } mat-card { display: flex; flex-direction: column; }
대시보드에 카드 추가
대시보드 요소는 반복이 아닌 개별적으로 추가되므로 이를 고려하여 대시보드 구성 요소를 수정해야 합니다. dashboard.component.ts
에서 cards
속성을 제거하고 대신 cardLayout
속성으로 바꿉니다. cardLayout
변수는 재료 그리드 목록의 열 수와 각 대시보드 카드에 걸쳐 있는 행과 열 수를 정의합니다. Breakpoints.Handset
및 Breakpoints.Tablet
쿼리 일치 항목은 1개 열에 표시되고 일치하지 않는 항목은 4개 열에 표시됩니다.
// dashboard.component.js ... cardLayout = this.breakpointObserver.observe(Breakpoints.Handset).pipe( map(({ matches }) => { if (matches) { return { columns: 1, miniCard: { cols: 1, rows: 1 }, chart: { cols: 1, rows: 2 }, table: { cols: 1, rows: 4 }, }; } return { columns: 4, miniCard: { cols: 1, rows: 1 }, chart: { cols: 2, rows: 2 }, table: { cols: 4, rows: 4 }, }; }) ); ...
dash.component.html
템플릿에서 mat-grid-tile
요소의 colspan
및 rowspan
값과 mat mat-grid-list
요소의 cols
속성을 바꿉니다.
<!--dash.component.html--> <div class="grid-container"> <h1 class="mat-h1">Dashboard</h1> <mat-grid-list cols="{{ ( cardLayout | async )?.columns }}" rowHeight="200px"> <!--Mini Cards--> <mat-grid-tile *ngFor="let i of [1, 2, 3, 4]" [colspan]="( cardLayout | async )?.miniCard.cols" [rowspan]="( cardLayout | async )?.miniCard.rows"> <app-card title="Card {{i}}"><div>Mini Card Content Here</div></app-card> </mat-grid-tile> <!--Charts--> <mat-grid-tile *ngFor="let i of [5, 6, 7, 8]" [colspan]="( cardLayout | async )?.chart.cols" [rowspan]="( cardLayout | async )?.chart.rows"> <app-card title="Card {{i}}"><div>Chart Content Here</div></app-card> </mat-grid-tile> <!--Table--> <mat-grid-tile [colspan]="( cardLayout | async )?.table.cols" [rowspan]="( cardLayout | async )?.table.rows"> <app-card title="Card 9"><div>Table Content Here</div></app-card> </mat-grid-tile> </mat-grid-list> </div>
대시보드는 위에 링크된 가장 최근 스크린샷과 똑같이 표시됩니다.
차트 생성
대시보드에 필요한 4가지 차트는 다음과 같습니다.
- 판매 단위별 제품의 레이더 차트입니다.
- 트래픽 소스별 매출의 원형 차트입니다.
- 온라인 상점 세션의 막대 차트입니다.
- 연도별 매출 꺾은선형 차트입니다.
대시보드 생성과 유사하게 차트 구성 요소 생성에는 도식 실행이 포함됩니다. ng2-chart 회로도를 사용하여 4개의 다른 차트를 생성합니다. 차트라는 폴더에 저장하겠습니다. ng generate ng2-charts-schematics:<chart type> <chart name>
실행하십시오.
ng generate ng2-charts-schematics:radar charts/product-sales-chart ng generate ng2-charts-schematics:pie charts/sales-traffic-chart ng generate ng2-charts-schematics:line charts/annual-sales-chart ng generate ng2-charts-schematics:bar charts/store-sessions-chart
이 명령을 실행하면 4개의 차트 구성 요소가 모두 생성되고 표시할 준비가 된 샘플 데이터로 채워집니다. 표시하려는 데이터에 따라 데이터 시각화 요구 사항에 가장 적합한 차트를 선택하십시오. 위에서 생성된 각 차트에 대해 차트 템플릿의 canvas
요소를 묶는 div
에 chartContainer
클래스를 추가합니다.
<div class="chartContainer"> <canvas baseChart width="400" height="400"> ...
다음으로 이 스타일을 styles.css
에 추가하여 모든 차트 구성 요소에서 액세스할 수 있도록 합니다.
/*styles.css*/ ... .chartContainer canvas { max-height: 250px; width: auto; } .chartContainer{ height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; }
차트에 데이터 추가하기
생성된 차트 구성 요소는 이미 연결된 샘플 데이터와 함께 제공됩니다. 자체 데이터를 제공하는 기존 서비스가 있는 경우 해당 서비스에서 이 데이터를 차트 구성 요소에 추가할 수 있습니다. 차트는 x축, 데이터 또는 데이터 세트, 차트 유형, 색상, 범례 및 기타 사용자 정의 옵션에 대한 레이블을 사용합니다. 차트에 데이터와 레이블을 제공하려면 선택한 소스에서 데이터를 가져와 차트에서 허용하는 형식으로 반환하는 서비스를 만듭니다. 예를 들어, AnnualSalesChartComponent
는 현재 연도의 각 월에 대한 판매 배열을 반환하는 SalesService
의 getSalesByMonth
메서드에서 데이터 세트와 레이블을 받습니다. 여기에서 이 서비스와 반환되는 데이터를 찾을 수 있습니다. 서비스를 AnnualSalesChartComponent
생성자에 개인 속성으로 삽입합니다. ngOnInit
수명 주기 후크 내에서 서비스에서 필요한 차트 데이터를 반환하는 메서드를 호출합니다.
// annual-sales-chart.component.ts import { SalesService } from 'src/app/sales/sales.service'; ... export class AnnualSalesChartComponent implements OnInit { public salesChartData: ChartDataSets[] = [ { data: [], label: 'Total Sales' }, ]; public salesChartLabels: Label[] = []; ... constructor(private salesService: SalesService) { } ngOnInit() { this.salesService.getSalesByMonth().subscribe({ next: salesItems => { salesItems.forEach(li => { this.salesChartData[0].data.push(li.revenue); this.salesChartLabels.push(li.month); }); }, ... }); } }
대시보드에 차트 추가
다음 단계는 dash.component.html
에서 대시보드에 차트를 추가하는 것입니다. 다음은 다음과 같습니다.
<!--dash.component.html--> ... <!--Charts--> <mat-grid-tile [colspan]="( cardLayout | async )?.chart.cols" [rowspan]="( cardLayout | async )?.chart.rows"> <app-card title="Monthly Revenue"> <app-annual-sale-chart></app-annual-sale-chart> </app-card> </mat-grid-tile> <mat-grid-tile [colspan]="( cardLayout | async )?.chart.cols" [rowspan]="( cardLayout | async )?.chart.rows"> <app-card title="Product Sales"> <app-product-sales-chart></app-product-sales-chart> </app-card> </mat-grid-tile> <mat-grid-tile [colspan]="( cardLayout | async )?.chart.cols" [rowspan]="( cardLayout | async )?.chart.rows"> <app-card title="Sales by Traffic Source"> <app-sales-traffic-chart></app-sales-traffic-chart> </app-card> </mat-grid-tile> <mat-grid-tile [colspan]="( cardLayout | async )?.chart.cols" [rowspan]="( cardLayout | async )?.chart.rows"> <app-card title="Online Store Sessions by Traffic Source"> <app-store-sessions-chart></app-store-sessions-chart> </app-card> </mat-grid-tile> ...
반응형 대시보드의 결과는 다음과 같습니다.
테이블 생성
상점 소유자에게 가장 최근에 접수된 주문과 해당 상태에 대한 개요를 제공하기 위해 주문 테이블을 추가합니다. 주문 테이블 구성 요소를 생성하려면 회로도를 실행합니다.
ng generate @angular/material:table orders-table
이렇게 하면 다음과 같은 테이블 구성 요소가 생성됩니다.
열이 많은 테이블은 핸드셋 및 태블릿 보기에 반응하도록 만들기 어려울 수 있습니다. 카드에 표를 추가할 때 가로로 스크롤할 수 있도록 하여 모든 데이터를 제대로 볼 수 있고 방해받지 않도록 합니다. 테이블 구성 요소에 아래 스타일을 추가하여 이 작업을 수행할 수 있습니다.
<!--table.component.html--> <div class="mat-elevation-z8 small-table"> <table mat-table class="full-width-table" matSort aria-label="Elements"> ...
/*table.component.css*/ ... .small-table{ overflow-x: scroll !important; }
대시 구성요소에 테이블을 추가하려면:
<!-- dashboard.component.html> ... <mat-grid-tile [colspan]="( cardLayout | async )?.table.cols" [rowspan]="( cardLayout | async )?.table.rows"> <app-card title="Latest Orders"> <app-orders-table></app-orders-table> </app-card> </mat-grid-tile> ...
테이블에 데이터 추가하기
차트와 마찬가지로 서비스에서 ngOnInit
메서드의 테이블에 데이터를 추가할 수 있습니다. 또한 서비스에서 데이터를 사용하려면 테이블에서 생성된 데이터 소스를 수정해야 합니다. 시작하려면 테이블의 클래스 생성자에 서비스를 삽입하십시오. 이 대시보드에 대한 최신 주문을 나열하는 테이블의 예를 살펴보겠습니다. 테이블에 대한 데이터를 가져오려면 OrdersTableComponent
생성자에 OrderService
를 삽입하고, 테이블 뷰 자식의 MatTable
유형 어설션을 변경하고, 주문 인터페이스를 반영하도록 표시된 열 목록을 수정합니다. 테이블에 추가되는 데이터에 관심이 있는 경우 여기에서 찾을 수 있습니다. 마지막은 테이블의 <mat-paginator>
에서 합계를 설정하는 데 사용할 수 있는 데이터 항목의 총 길이를 가져오는 것과 관련됩니다.
// orders-table.component.ts import { OrderService } from '../orders.service'; import { Order } from '../order'; ... export class OrdersTableComponent implements AfterViewInit, OnInit { ... @ViewChild(MatTable) table: MatTable ; dataLength: number; displayedColumns = [ "id", "date", "name", "status", "orderTotal", "paymentMode", ]; ... constructor(private orderService: OrderService){} ngOnInit() { this.datasource = new OrdersTableDataSource(this.orderService); this.orderService.getOrderCount().subscribe({ next: orderCount => { this.dataLength = orderCount; }, ... }); } ... }
// orders-table.component.ts import { OrderService } from '../orders.service'; import { Order } from '../order'; ... export class OrdersTableComponent implements AfterViewInit, OnInit { ... @ViewChild(MatTable) table: MatTable ; dataLength: number; displayedColumns = [ "id", "date", "name", "status", "orderTotal", "paymentMode", ]; ... constructor(private orderService: OrderService){} ngOnInit() { this.datasource = new OrdersTableDataSource(this.orderService); this.orderService.getOrderCount().subscribe({ next: orderCount => { this.dataLength = orderCount; }, ... }); } ... }
다음으로 OrderService
를 생성자의 매개변수로 허용하도록 OrdersTableDataSource
클래스를 수정해야 합니다. connect
및 destroy
메서드도 수정해야 합니다. connect
메서드는 데이터 소스를 테이블에 연결하고 반환하는 스트림(이 경우 관찰 가능한 주문 배열)에서 새 데이터 항목이 내보내지면 테이블을 업데이트합니다. dataMutations
상수는 첫 번째 데이터 로드, 페이지 매김 및 정렬 이벤트를 테이블이 사용할 하나의 스트림으로 결합합니다. 페이지 매김 및 정렬은 OrderService
서버 측에서 처리됩니다. 따라서 paginator의 오프셋과 페이지 크기와 정렬 속성의 활성 정렬 필드 및 정렬 방향을 OrderService
의 getOrders
메서드로 전달해야 합니다. disconnect
방법은 연결된 모든 연결을 닫고 연결 방법에 보류된 리소스를 해제하는 데 사용해야 합니다.
// orders-table.datasource.ts ... export class OrdersTableDataSource extends DataSource<Order> { paginator: MatPaginator; sort: MatSort; constructor(private orderService: OrderService) { super(); } connect(): Observable<Order[]> { const dataMutations = [ of('Initial load'), this.paginator.page, this.sort.sortChange ]; return merge(...dataMutations).pipe(mergeMap(() => { return this.orderService.getOrders( this.paginator.pageIndex * this.paginator.pageSize, this.paginator.pageSize, this.sort.active, this.sort.direction ); })); } disconnect() {} }
주문 테이블 템플릿에서 새 열을 삽입하고 <mat-paginator>
의 length
속성을 dataLength
속성에 바인딩합니다. 상태 열의 경우 주문 상태를 더 잘 시각화하기 위해 <mat-chip>
요소를 사용합니다. <mat-chip>
에 액세스하려면 MatChipsModule
을 AppModule
에 대한 가져오기로 추가하십시오.
<!-- orders-table.component.html --> <div class="mat-elevation-z8"> <table mat-table class="full-width-table" matSort aria-label="Elements"> <!-- Id Column --> <ng-container matColumnDef="id"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Id</th> <td mat-cell *matCellDef="let row">{{row.id}}</td> </ng-container> <!-- Date Column --> <ng-container matColumnDef="date"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th> <td mat-cell *matCellDef="let row">{{row.date | date }}</td> </ng-container> <!-- Name Column --> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th> <td mat-cell *matCellDef="let row">{{row.name}}</td> </ng-container> <!-- Order Total Column --> <ng-container matColumnDef="orderTotal"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Order Total</th> <td mat-cell *matCellDef="let row">{{row.orderTotal | currency}}</td> </ng-container> <!-- Payment Mode Column --> <ng-container matColumnDef="paymentMode"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Mode</th> <td mat-cell *matCellDef="let row">{{row.paymentMode}}</td> </ng-container> <!-- Status Column --> <ng-container matColumnDef="status"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Status</th> <td mat-cell *matCellDef="let row"> <mat-chip-list> <mat-chip color="{{ row.status == 'delivered' ? 'primary' : ( row.status == 'shipped' ? 'accent' : 'warn' ) }}" selected> {{row.status}} </mat-chip> </mat-chip-list> </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> <mat-paginator #paginator [length]="dataLength" [pageIndex]="0" [pageSize]="5" [pageSizeOptions]="[5, 10, 15, 20]"> </mat-paginator> </div>
데이터가 테이블에 추가되면 대시보드는 다음과 같이 표시됩니다.
미니 카드 구성 요소 만들기
대시보드를 완성하기 위해 남은 것은 상단에 있는 4개의 작은 카드를 채우는 것뿐입니다. 대시보드의 일부로 더 작은 요약 카드를 사용하면 전체 차트나 표가 필요하지 않은 간략한 정보를 쉽게 강조 표시할 수 있습니다. 이 예에서 4개의 미니 카드에는 총 판매액, 평균 주문 금액, 총 주문 수 및 당일 매장을 방문한 재방문 고객 수가 표시됩니다. 이것은 단지 예일 뿐입니다. 이러한 미니 카드는 탐색, 대시보드 레이아웃, 차트 및 테이블과 같이 생성할 수 없습니다. 회로도가 없습니다. 아래에서 생성 방법을 간략하게 살펴보겠습니다. 예제에 특정한 데이터를 추가할 것이지만 원하는 것을 추가하거나 완전히 제거하기로 결정할 수 있습니다. 시작하려면 mini-card
구성 요소를 생성하고 다음을 실행하십시오.
ng gc mini-card -m app --style css
여기에서 링크된 구성 요소의 템플릿과 해당 스타일을 찾을 수 있습니다. 이 구성 요소에는 여기에서 추가하는 방법을 찾을 수 있는 8개의 입력 속성이 있습니다. 미니 카드 구성 요소에 데이터를 가져오려면 DashComponent
생성자에 데이터를 제공하는 서비스를 삽입하십시오. 서비스에서 받은 데이터를 DashComponent
의 속성에 할당합니다. 이 경우 StoreSummaryService
에서 데이터를 miniCardData
속성에 할당합니다. 방법은 다음과 같습니다.
// dash.component.ts export class DashComponent implements OnInit{ ... miniCardData: StoreSummary[]; constructor(private breakpointObserver: BreakpointObserver, private summaryService: StoreSummaryService) {} ngOnInit() { this.summaryService.getStoreSummary().subscribe({ next: summaryData => { this.miniCardData = summaryData; } }); } }
대시 구성 요소에 mini-cards
를 추가하고 서비스의 데이터로 채우려면:
<!--dash.component.html--> ... <!--Mini Cards--> <mat-grid-tile *ngFor="let mc of miniCardData" [colspan]="( cardLayout | async )?.miniCard.cols" [rowspan]="( cardLayout | async )?.miniCard.rows"> <app-mini-card [title]="mc.title" [textValue]="mc.textValue" [value]="mc.value" [color]="mc.color" [percentValue]="mc.percentValue"></app-mini-card> </mat-grid-tile> ...
아래 스크린샷은 미니 카드가 채워진 대시보드의 모습입니다.
모든 것을 합치다
결국 대시보드 구성 요소 템플릿에는 다음이 포함되어야 합니다.
<!-- dashboard.component.html --> <div class="grid-container"> <h1 class="mat-h1">Dashboard</h1> <mat-grid-list cols="{{ ( cardLayout | async )?.columns }}" rowHeight="200px"> <!--Mini Cards--> <mat-grid-tile *ngFor="let mc of miniCardData" [colspan]="( cardLayout | async )?.miniCard.cols" [rowspan]="( cardLayout | async )?.miniCard.rows"> <app-mini-card [icon]="mc.icon" [title]="mc.title" [value]="mc.value" [color]="mc.color" [isIncrease]="mc.isIncrease" duration="since last month" [percentValue]="mc.percentValue" [isCurrency]="mc. isCurrency"></app-mini-card> </mat-grid-tile> <!--Charts--> <mat-grid-tile [colspan]="( cardLayout | async )?.chart.cols" [rowspan]="( cardLayout | async )?.chart.rows"> <app-card title="Monthly Revenue"> <app-annual-sale-chart></app-annual-sale-chart> </app-card> </mat-grid-tile> <mat-grid-tile [colspan]="( cardLayout | async )?.chart.cols" [rowspan]="( cardLayout | async )?.chart.rows"> <app-card title="Product Sales"> <app-product-sales-chart></app-product-sales-chart> </app-card> </mat-grid-tile> <mat-grid-tile [colspan]="( cardLayout | async )?.chart.cols" [rowspan]="( cardLayout | async )?.chart.rows"> <app-card title="Sales by Traffic Source"> <app-sales-traffic-chart></app-sales-traffic-chart> </app-card> </mat-grid-tile> <mat-grid-tile [colspan]="( cardLayout | async )?.chart.cols" [rowspan]="( cardLayout | async )?.chart.rows"> <app-card title="Online Store Sessions by Traffic Source"> <app-store-sessions-chart></app-store-sessions-chart> </app-card> </mat-grid-tile> <!--Table--> <mat-grid-tile [colspan]="( cardLayout | async )?.table.cols" [rowspan]="( cardLayout | async )?.table.rows"> <app-card title="Latest Orders"> <app-orders-table></app-orders-table> </app-card> </mat-grid-tile> </mat-grid-list> </div>
결과 대시보드에 포함된 내용은 다음과 같습니다.
결론
대시보드를 생성하려면 상당한 양의 작업과 계획이 필요합니다. 더 빠르게 빌드하는 방법은 Angular Material 및 ng2-charts에서 제공하는 다양한 도식을 사용하는 것입니다. 이러한 회로도를 사용하면 명령을 실행하면 완전히 완전한 구성 요소가 생성되고 대시보드가 상당히 빠르게 실행되고 실행될 수 있습니다. 이렇게 하면 데이터 서비스를 만들고 대시보드 구성 요소에 추가하는 데 더 많은 시간을 할애할 수 있습니다.
Angular Material에서 제공하는 일부 회로도에 대해 자세히 알아보려면 material.angular.io를 방문하고 ng2-charts에서 제공하는 회로도에 대해서는 여기 링크된 해당 사이트를 방문하세요.