Crea un dashboard reattivo con materiale angolare e grafici ng2
Pubblicato: 2022-03-10La creazione di una dashboard da zero è spesso piuttosto complicata. Devi creare strumenti per raccogliere dati su elementi di interesse. Una volta raccolti, questi dati devono essere presentati ai tuoi utenti in modo facile da capire e significativo. Implica una pianificazione complessa di quali dati includere e come visualizzarli in modo efficace. Una volta che hai un piano, l'implementazione del progetto è un compito enorme, soprattutto perché comporta la costruzione di più componenti.
Con Angular Material e ng2-charts, puoi sfruttare gli schemi per ridurre lo sforzo e il tempo che potresti dedicare alla creazione di un dashboard. Angular Material viene fornito con una serie di schemi che puoi utilizzare per generare un dashboard. Allo stesso modo, ng2-charts fornisce schemi per la generazione di più componenti del grafico. In questo articolo, illustrerò come utilizzare sia ng2-charts che Angular Material per configurare un dashboard abbastanza rapidamente.
Un esempio
Per illustrare come costruire una dashboard, prenderemo l'esempio di un negozio online che vende articoli in pelle come borse, portafogli, portachiavi e così via. Il proprietario del negozio vorrebbe tenere traccia di informazioni come da dove provengono i clienti nel loro negozio online, come vendono i loro prodotti, come le fonti di traffico si relazionano alle vendite, tra le altre cose.
Creeremo una dashboard per visualizzare queste informazioni e aiutare il proprietario del negozio ad analizzarle. La dashboard conterrà quattro piccole schede riepilogative, quattro diversi tipi di grafici e una tabella che elenca gli ordini più recenti effettuati. Le quattro schede riepilogative visualizzeranno informazioni quali il ricavo totale delle vendite, il valore medio dell'ordine, il numero totale di ordini e il numero di clienti abituali. I grafici mostreranno il numero di unità vendute per ciascun prodotto, le vendite per fonte di traffico, le sessioni del negozio online nel tempo e le vendite della settimana.
Prerequisiti
Per seguire, dovrai avere installato Angular CLI. Se non lo hai installato, puoi scoprire come ottenerlo su cli.angular.io. Se non stai partendo da un progetto Angular preesistente, devi generarne uno eseguendo ng new <your project name>
. Ad esempio, per creare un pannello di amministrazione per il suddetto negozio, eseguiremo:
ng new store-admin-panel
Il tuo progetto deve anche avere percorsi configurati per esso. Se stai partendo da una nuova app, seleziona Sì quando ti viene chiesto se aggiungere un modulo di routing angolare durante la configurazione del progetto sopra.
Aggiungi materiale angolare e grafici Ng2 al tuo progetto
Angular Material viene fornito con vari schemi per generare una varietà di componenti utili come rubriche, alberi, tabelle, navigazione e così via. Per aggiungere materiale angolare al tuo progetto, esegui:
ng add @angular/material
Scegli un tema tra le opzioni fornite nei prompt successivi. Successivamente, ti verrà chiesto di scegliere se aggiungere gli stili tipografici di Angular Material e le animazioni del browser. Non hai bisogno di questi e potresti semplicemente rispondere di no.
Successivamente, dovrai installare ng2-charts. ng2-charts richiede charts.js come dipendenza. Per installare ng2-charts esegui:
npm install ng2-charts --save
Quindi installa charts.js:
npm install chart.js --save
Per accedere ai grafici, aggiungi ChartsModule
alle importazioni di AppModule
.
import { ChartsModule } from 'ng2-charts'; @NgModule({ imports: [ … ChartsModule, … ] })
Infine, installa gli schemi ng2-charts come dipendenza dev perché non vengono forniti con ng2-charts per impostazione predefinita.
npm install --save-dev ng2-charts-schematics
Generazione di un componente di navigazione
Prima di tutto, dovremo aggiungere un componente di navigazione per aiutare gli utenti a manovrare comodamente attraverso l'app. La navigazione dovrebbe contenere collegamenti alla dashboard e ad altre pagine che faranno parte del pannello di amministrazione. Il materiale angolare fornisce uno schema che genera un componente di navigazione. Chiameremo questo componente nav
. L'aggiunta di un side nav all'applicazione viene eseguita eseguendo:
ng generate @angular/material:navigation nav
Per collegare altri percorsi nella navigazione, utilizzare la direttiva routerLink
e modificare il nome della pagina nella barra degli strumenti a seconda del percorso su cui si trova un utente.
// 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> ...
Per vedere questo componente, aggiungilo a app.component.html
.
<!--app.component.html--> <app-nav></app-nav>
Ecco come appare il NavComponent
.

Poiché il navigatore verrà visualizzato insieme ad altri componenti, l'aggiunta di una router-outlet
aiuterebbe a passare da un altro componente all'altro. Nel modello nav.component.html
, subito dopo la chiusura </mat-toolbar>
, sostituisci il commento <!-- Add Content Here -->
con <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>
Negli screenshot che seguono in questo articolo, questo componente di navigazione verrà omesso per evidenziare meglio la dashboard che creeremo per il bene del tutorial. Se stai seguendo durante la creazione di questa dashboard, il navigatore apparirà ancora come mostrato sopra nel tuo browser con la dashboard al suo interno.
Genera il dashboard
La parte più importante della dashboard è il suo layout. Deve contenere tutti i componenti menzionati in precedenza ed essere reattivo quando viene visualizzato su dispositivi diversi. Per generare il layout del dashboard, dovrai eseguire lo schema @angular/material:dashboard
. Genererà un componente dashboard reattivo. Passa il nome preferito per la tua dashboard allo schema. In questo caso, chiamiamolo dash
.
ng generate @angular/material:dashboard dash
Per visualizzare il dashboard appena generato all'interno del componente nav, aggiungi un percorso per esso al router.
// app-routing.module.ts import { DashComponent } from './dash/dash.component'; const routes: Routes = [{ path: 'dashboard', component: DashComponent }]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] })
Una volta terminato, per vedere i risultati, esegui npm start
e vai su localhost:4200/dashboard
. Dovresti vedere questo:

Lo schema genera quattro carte nel modello e le visualizza in una griglia reattiva. Angular Material CDK utilizza il pacchetto Layout
per definire lo stile di questa griglia di carte reattiva. L'utilità BreakpointObserver
del pacchetto Layout
valuta le query multimediali e apporta modifiche all'interfaccia utente in base ad esse. Sono disponibili vari punti di interruzione, ma all'interno del componente generato vengono soddisfatte solo due categorie. Il Breakpoints.Handset
e altre query che non corrispondono. Il pacchetto Layout
specifica 14 stati di punto di interruzione che puoi utilizzare per personalizzare la reattività della dashboard.
// dashboard.component.js ... cards = this.breakpointObserver.observe(Breakpoints.Handset).pipe( map(({ matches }) => { if (matches) { ... } ... }) );
Tornando alla dashboard, poiché sulla dashboard ci saranno quattro schede riepilogative, quattro grafici e un tavolo, abbiamo bisogno di nove schede in totale. Le corrispondenze Breakpoints.Handset
e Breakpoints.Tablet
verranno visualizzate in una griglia a una colonna in cui:
- Le quattro schede riepilogative si estenderanno su una riga.
- I grafici si estenderanno su due righe.
- La tabella si estenderà su quattro righe.
Le corrispondenze non Breakpoints.Handset
e non Breakpoints.Tablet
verranno visualizzate in quattro colonne in cui:
- Le quattro schede riepilogative si estenderanno su una riga e una colonna.
- I grafici si estenderanno su due righe e due colonne.
- La tabella si estenderà su quattro righe e quattro colonne.
Dovrebbe essere simile allo screenshot qui sotto nelle corrispondenze non Breakpoints.Handset
e non Breakpoints.Tablet
. Nelle corrispondenze Breakpoints.Handset
e Breakpoints.Tablet
, tutto verrà visualizzato solo in una colonna.

Crea un componente della carta
Nel componente dashboard, tutte le carte vengono generate tramite l'iterazione. Per evitare ripetizioni, quando aggiungiamo tutti i nuovi componenti, creeremo un componente della carta riutilizzabile. Il componente della scheda accetterà un titolo come input e utilizzerà ng-content
per aggiungere dinamicamente il resto del contenuto. Per creare il componente della carta, eseguire:
ng gc card -m app --style css
Dal modello del componente dashboard, prenderemo semplicemente il markup racchiuso nel <mat-card>
e lo posizioneremo nel modello della scheda:
<!--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>
Per aggiungere il titolo come input alla scheda:
// card.component.ts import { Component, Input } from '@angular/core'; ... export class CardComponent{ @Input() title: string; ... }
Per modellare la carta:
/*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; }
Aggiunta di carte al dashboard
Poiché gli elementi del dashboard verranno aggiunti individualmente e non tramite l'iterazione, il componente del dashboard deve essere modificato per tener conto di ciò. In dashboard.component.ts
, rimuovi la proprietà cards
e sostituiscila invece con una proprietà cardLayout
. La variabile cardLayout
definirà il numero di colonne per l'elenco della griglia dei materiali e quante righe e colonne si estenderanno su ciascuna scheda dashboard. Le corrispondenze delle query Breakpoints.Handset
e Breakpoints.Tablet
verranno visualizzate in 1 colonna e quelle che non corrispondono verranno visualizzate in 4 colonne.
// 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 }, }; }) ); ...
Nel modello dash.component.html
, sostituisci i valori colspan
e rowspan
degli elementi mat-grid-tile
e la proprietà cols
dell'elemento 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>
La dashboard finirà per apparire esattamente come lo screenshot più recente collegato sopra.
Generazione dei grafici
I quattro grafici di cui abbiamo bisogno per la dashboard sono:
- Un grafico radar dei prodotti per unità venduta.
- Un grafico a torta delle vendite per fonte di traffico.
- Un grafico a barre delle sessioni del negozio online.
- Un grafico a linee delle vendite durante l'anno.
Simile alla creazione del dashboard, la generazione dei componenti del grafico implica l'esecuzione di uno schema. Usando gli schemi di ng2-charts, genera i quattro diversi grafici. Li metteremo in una cartella chiamata grafici. Esegui 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
Dopo aver eseguito questi comandi, tutti e quattro i componenti del grafico vengono generati e popolati con dati campione pronti per la visualizzazione. A seconda dei dati che desideri mostrare, scegli i grafici più adatti alle tue esigenze di visualizzazione dei dati. Per ciascuno dei grafici generati sopra, aggiungi la classe chartContainer
ai div
che racchiudono l'elemento canvas
nei modelli di grafico.
<div class="chartContainer"> <canvas baseChart width="400" height="400"> ...
Quindi, aggiungi questo stile a styles.css
in modo che possano essere accessibili a tutti i componenti del grafico.
/*styles.css*/ ... .chartContainer canvas { max-height: 250px; width: auto; } .chartContainer{ height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; }
Aggiunta di dati ai grafici
I componenti del grafico generati vengono forniti con dati di esempio già collegati. Se si dispone di servizi preesistenti che forniscono i propri dati, è possibile aggiungere questi dati ai componenti del grafico. I grafici accettano etichette per l'asse x, dati o set di dati, un tipo di grafico, colori, una legenda e altre opzioni di personalizzazione. Per fornire i dati e le etichette ai grafici, crea un servizio che preleverà i dati da una fonte di tua scelta e li restituirà in un formato accettato dai grafici. Ad esempio, AnnualSalesChartComponent
riceve il set di dati e le etichette dal metodo SalesService
di getSalesByMonth
che restituisce un array di vendite per ogni mese per l'anno corrente. Puoi trovare questo servizio qui e i dati che restituisce qui. Iniettare il servizio come proprietà privata al costruttore AnnualSalesChartComponent
. Chiama il metodo che restituisce i dati del grafico richiesti dal servizio all'interno dell'hook del ciclo di vita 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); }); }, ... }); } }
Aggiunta di grafici al dashboard
Il passaggio successivo prevede l'aggiunta dei grafici alla dashboard, in dash.component.html
. Ecco come appare:
<!--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> ...
Ecco come appare la dashboard reattiva risultante.

Generazione di una tabella
Aggiungeremo una tabella degli ordini per fornire al proprietario del negozio una panoramica degli ordini più recenti effettuati e del loro stato. Per generare il componente della tabella degli ordini, eseguire lo schema:
ng generate @angular/material:table orders-table
Questo genererà un componente della tabella che sarà simile a questo.

Può essere difficile rendere reattive le tabelle con molte colonne per le visualizzazioni del telefono e del tablet. Quando aggiungi il tavolo a una scheda, rendilo scorrevole orizzontalmente in modo che tutti i dati possano essere visualizzati correttamente e non siano ostruiti. Puoi farlo aggiungendo lo stile seguente al componente della tabella:
<!--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; }
Per aggiungere la tabella al componente trattino:
<!-- 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> ...
Aggiunta di dati alla tabella
Come con i grafici, puoi aggiungere dati alla tabella nel metodo ngOnInit
da un servizio. Inoltre, dovrai modificare l'origine dati generata dalla tabella per utilizzare i dati dal servizio. Per iniziare, inietta il servizio nel costruttore di classi della tabella. Prendiamo l'esempio di una tabella che elenca gli ultimi ordini per questa dashboard. Per ottenere i dati per la tabella, inseriamo OrderService
nel costruttore OrdersTableComponent
, modifichiamo l'asserzione di tipo MatTable
del figlio della visualizzazione tabella e modifichiamo l'elenco delle colonne visualizzate per riflettere un'interfaccia dell'ordine. Se sei interessato ai dati che vengono aggiunti alla tabella, puoi trovarli qui. L'ultima cosa consiste nell'ottenere la lunghezza totale degli elementi di dati disponibili da utilizzare per impostare il totale nel <mat-paginator>
della tabella.
// 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; }, ... }); } ... }
Successivamente, dovremo modificare la classe OrdersTableDataSource
per accettare OrderService
come parametro nel suo costruttore. Dovremo anche modificare i suoi metodi di connect
e destroy
. Il metodo connect
connette l'origine dati alla tabella e aggiorna la tabella quando vengono emessi nuovi elementi di dati dal flusso, restituisce, in questo caso, una matrice di ordini osservabile. La costante dataMutations
combina il primo caricamento dei dati, l'impaginazione e l'ordinamento degli eventi in un flusso che la tabella può utilizzare. L'impaginazione e l'ordinamento sono gestiti dal lato server di OrderService
. Quindi dobbiamo passare l'offset e la dimensione della pagina dall'impaginatore e il campo di ordinamento attivo e la direzione di ordinamento della proprietà di ordinamento al metodo getOrders
di OrderService
. Il metodo di disconnect
deve essere utilizzato per chiudere tutte le connessioni effettuate e rilasciare le risorse trattenute nel metodo di connessione.
// 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() {} }
Nel modello di tabella degli ordini, inserisci le nuove colonne e associa la proprietà length
di <mat-paginator>
alla proprietà dataLength
. Per la colonna dello stato, utilizzare un elemento <mat-chip>
per una migliore visualizzazione dello stato dell'ordine. Per avere accesso a <mat-chip>
, aggiungi MatChipsModule
come importazione in 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>
Una volta aggiunti i dati alla tabella, ecco come apparirà la dashboard:

Creazione di un componente di mini card
Tutto ciò che resta per completare la dashboard è popolare le quattro piccole carte che si trovano in alto. Avere schede riepilogative più piccole come parte del dashboard semplifica l'evidenziazione di brevi informazioni che non richiedono grafici o tabelle interi. In questo esempio, le quattro mini carte mostreranno le vendite totali, il valore medio dell'ordine, il numero totale di ordini e il numero di clienti abituali che hanno visitato il negozio durante la giornata. Questo è solo un esempio. Queste mini card non possono essere generate come con la navigazione, il layout del dashboard, i grafici e la tabella. Non hanno schemi. Di seguito analizzeremo brevemente come crearli. Anche se aggiungeremo dati specifici all'esempio, puoi aggiungere quello che vuoi o decidere di eliminarli del tutto. Per iniziare, genera il componente mini-card
, esegui:
ng gc mini-card -m app --style css
Puoi trovare il modello per il componente collegato qui e il suo stile qui. Questo componente ha otto proprietà di input che puoi scoprire come aggiungere qui. Per ottenere i dati dai componenti della scheda mini, iniettare il servizio che fornisce loro i dati nel costruttore DashComponent
. Assegna i dati ricevuti dal servizio a una proprietà di DashComponent
. In questo caso, otterremo i dati da StoreSummaryService
e li assegneremo alla proprietà miniCardData
. Ecco come:
// 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; } }); } }
Per aggiungere le mini-cards
al componente Dash e farle compilare con i dati del servizio:
<!--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> ...
Lo screenshot qui sotto mostra come apparirà la dashboard con le mini carte popolate.

Mettere tutto insieme
Alla fine, il modello del componente dashboard dovrebbe contenere:
<!-- 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>
Ecco cosa contiene la dashboard risultante.

Conclusione
La creazione di dashboard richiede una discreta quantità di lavoro e pianificazione. Un modo per costruirli più velocemente è utilizzare i vari schemi forniti da Angular Material e ng2-charts. Con questi schemi, l'esecuzione di un comando genererà un componente completamente completo e può comportare un dashboard attivo e funzionante abbastanza rapidamente. Questo ti lascia molto più tempo per concentrarti sulla creazione di servizi dati e aggiungerli ai componenti del dashboard.
Se vuoi saperne di più su alcuni degli schemi forniti da Angular Material, visita material.angular.io e per quelli forniti da ng2-charts, visita il loro sito collegato qui.