Создайте адаптивную панель инструментов с помощью Angular Material и ng2-Charts
Опубликовано: 2022-03-10Создание дашборда с нуля часто бывает довольно сложным. Вы должны создать инструменты для сбора данных об интересующих вас элементах. После сбора эти данные должны быть представлены вашим пользователям в понятной и осмысленной форме. Это включает в себя сложное планирование того, какие данные включать и как их эффективно отображать. Когда у вас есть план, реализация дизайна становится сложной задачей, особенно потому, что она включает в себя создание нескольких компонентов.
С Angular Material и ng2-charts вы можете использовать схемы, чтобы сократить усилия и время, которые вы можете потратить на создание панели инструментов. Angular Material поставляется с рядом схем, которые можно использовать для создания панели инструментов. Точно так же ng2-charts предоставляет схемы для создания нескольких компонентов диаграммы. В этой статье я покажу, как использовать ng2-charts и Angular Material для довольно быстрой настройки панели мониторинга.
Пример
Чтобы проиллюстрировать, как создать информационную панель, мы возьмем пример интернет-магазина, торгующего изделиями из кожи, такими как сумки, кошельки, ключницы и т. д. Владелец магазина хотел бы отслеживать информацию, например, откуда покупатели приходят в его интернет-магазин, как продаются их товары, как источники трафика связаны с продажами и т. д.
Мы создадим информационную панель для отображения этой информации и поможем владельцу магазина проанализировать ее. Приборная панель будет содержать четыре небольшие сводные карточки, четыре различных вида диаграмм и таблицу с последними сделанными заказами. На четырех сводных карточках будет отображаться такая информация, как общий доход от продаж, средняя стоимость заказа, общее количество заказов и количество вернувшихся клиентов. На диаграммах будет отображаться количество проданных единиц каждого продукта, продажи по источникам трафика, количество посещений интернет-магазина с течением времени и продажи за неделю.
Предпосылки
Чтобы продолжить, вам необходимо установить 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 требует charts.js в качестве зависимости. Для установки ng2-charts выполните:
npm install ng2-charts --save
Затем установите charts.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
. Вы должны увидеть это:
Схема генерирует четыре карты в шаблоне и отображает их в адаптивной сетке. Angular Material CDK использует пакет Layout
для оформления этой адаптивной сетки карточек. Утилита BreakpointObserver
пакета Layout
оценивает медиа-запросы и вносит изменения в пользовательский интерфейс на их основе. Доступны различные точки останова, но в сгенерированном компоненте учитываются только две категории. Breakpoints.Handset
и другие запросы, которые ему не соответствуют. Пакет Layout
определяет 14 состояний точек останова, которые можно использовать для настройки отклика панели мониторинга.
// dashboard.component.js ... cards = this.breakpointObserver.observe(Breakpoints.Handset).pipe( map(({ matches }) => { if (matches) { ... } ... }) );
Возвращаясь к информационной панели, поскольку на информационной панели будут четыре сводные карточки, четыре диаграммы и таблица, всего нам потребуется девять карточек. Breakpoints.Handset
и Breakpoints.Tablet
будут отображаться в сетке с одним столбцом, где:
- Четыре итоговые карты занимают одну строку.
- Диаграммы будут занимать две строки.
- Таблица будет занимать четыре строки.
Совпадения Breakpoints.Handset
и без Breakpoints.Tablet
будут отображаться в четырех столбцах, где:
- Четыре сводные карты будут занимать одну строку и один столбец.
- Диаграммы будут охватывать две строки и два столбца.
- Таблица будет занимать четыре строки и четыре столбца.
Это должно выглядеть примерно так, как показано на снимке экрана ниже при совпадении без 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
cards
Переменная 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
замените значения colspan
и rowspan
элементов mat-grid-tile
и свойство cols
элемента mat-grid-list
.
<!--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>
Панель инструментов будет выглядеть точно так же, как на последнем снимке экрана, указанном выше.
Генерация диаграмм
Четыре диаграммы, которые нам нужны для приборной панели:
- Радарная диаграмма продуктов по проданным единицам.
- Круговая диаграмма продаж по источникам трафика.
- Гистограмма сеансов интернет-магазина.
- Линейный график продаж за год.
Подобно созданию информационной панели, создание компонентов диаграммы требует запуска схемы. Используя схемы ng2-charts, сгенерируйте четыре разные диаграммы. Мы поместим их в папку с названием charts. Запустите 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
После запуска этих команд все четыре компонента диаграммы генерируются и заполняются демонстрационными данными, готовыми к отображению. В зависимости от того, какие данные вы хотите показать, выберите диаграммы, которые больше всего соответствуют вашим потребностям в визуализации данных. Для каждой из диаграмм, созданных выше, добавьте класс chartContainer
в элементы div
, которые окружают элемент canvas
в шаблонах диаграмм.
<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
из службы. Кроме того, вам потребуется изменить сгенерированный источник данных вашей таблицы, чтобы использовать данные из службы. Для начала внедрите службу в конструктор класса таблицы. Давайте возьмем в качестве примера таблицу со списком последних заказов для этой панели. Чтобы получить данные для таблицы, давайте OrderService
в конструктор OrdersTableComponent
, изменим утверждение типа 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; }, ... }); } ... }
Далее нам нужно изменить класс OrdersTableDataSource
, чтобы принимать OrderService
в качестве параметра в его конструкторе. Нам также придется изменить его методы connect
и destroy
. Метод connect
подключает источник данных к таблице и обновляет таблицу, когда новые элементы данных выпускаются из возвращаемого им потока, в данном случае наблюдаемого массива заказов. Константа dataMutations
объединяет первые события загрузки данных, разбиения на страницы и сортировки в один поток для использования таблицей. Разбивка на страницы и сортировка выполняются на стороне сервера OrderService
. Поэтому нам нужно передать смещение и размер страницы из paginator и активного поля сортировки, а также направление сортировки свойства sort в метод getOrders
службы OrderService
. Метод 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() {} }
В шаблоне таблицы заказов вставьте новые столбцы и привяжите свойство length
<mat-paginator>
к свойству 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>
После того, как данные будут добавлены в таблицу, панель мониторинга будет выглядеть следующим образом:
Создание компонента мини-карты
Все, что осталось, чтобы заполнить информационную панель, — это заполнить четыре маленькие карточки вверху. Наличие небольших сводных карточек в составе информационной панели упрощает выделение кратких фрагментов информации, для которых не нужны целые диаграммы или таблицы. В этом примере четыре мини-карты будут отображать общий объем продаж, среднюю стоимость заказа, общее количество заказов и количество постоянных покупателей, посетивших магазин в течение дня. Это всего лишь пример. Эти мини-карты не могут быть созданы, как с навигацией, компоновкой панели инструментов, диаграммами и таблицей. У них нет схем. Ниже мы кратко рассмотрим, как их создать. Хотя мы собираемся добавить данные, специфичные для примера, вы можете добавить к ним все, что хотите, или вообще отказаться от них. Для начала сгенерируйте компонент mini-card
, запустите:
ng gc mini-card -m app --style css
Вы можете найти шаблон для компонента, связанного здесь, и его стиль здесь. Этот компонент имеет восемь входных свойств, которые можно добавить здесь. Чтобы получить данные для компонентов мини-карты, внедрите службу, которая предоставляет им данные, в конструктор 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 и заполнить их данными из сервиса:
<!--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, посетите их сайт, ссылка на который приведена здесь.