สร้างแดชบอร์ดที่ตอบสนองด้วยวัสดุเชิงมุมและแผนภูมิ ng2-Charts

เผยแพร่แล้ว: 2022-03-10
สรุปอย่างย่อ ↬ แผนผังใน Angular 9 คือตัวสร้างโค้ดที่สามารถสร้างส่วนประกอบและรูปแบบในโปรเจ็กต์โดยใช้เทมเพลตและเลย์เอาต์ที่กำหนดไว้ล่วงหน้า ในบทความนี้ Zara Cooper อธิบายวิธีใช้ประโยชน์จากแผนผังใน Angular Material และ ng2-chart เพื่อลดเวลาและงานที่ต้องใช้ในการสร้างแดชบอร์ดอย่างมาก

การสร้างแดชบอร์ดตั้งแต่เริ่มต้นมักจะค่อนข้างซับซ้อน คุณต้องสร้างเครื่องมือเพื่อรวบรวมข้อมูลเกี่ยวกับรายการที่สนใจ เมื่อเก็บรวบรวมข้อมูลนี้แล้ว จะต้องนำเสนอในรูปแบบที่เข้าใจง่ายและมีความหมายต่อผู้ใช้ของคุณ มันเกี่ยวข้องกับการวางแผนที่ซับซ้อนของข้อมูลที่จะรวมและวิธีแสดงข้อมูลอย่างมีประสิทธิภาพ เมื่อคุณมีแผนแล้ว การนำการออกแบบไปใช้นั้นเป็นงานใหญ่ โดยเฉพาะอย่างยิ่งเนื่องจากมันเกี่ยวข้องกับการสร้างส่วนประกอบหลายอย่าง

ด้วยวัสดุเชิงมุมและแผนภูมิ ng2- คุณสามารถใช้ประโยชน์จากแผนผังเพื่อลดความพยายามและเวลาที่คุณอาจใช้ในการสร้างแดชบอร์ด Angular Material มาพร้อมกับแผนผังจำนวนมากที่คุณสามารถใช้สร้างแดชบอร์ดได้ ในทำนองเดียวกัน แผนภูมิ ng2-จะแสดงแผนผังสำหรับการสร้างส่วนประกอบแผนภูมิหลายส่วน ในบทความนี้ ฉันจะอธิบายวิธีใช้ทั้งแผนภูมิ ng2-และวัสดุเชิงมุม เพื่อตั้งค่าแดชบอร์ดอย่างรวดเร็ว

ตัวอย่าง

เพื่อแสดงวิธีสร้างแดชบอร์ด เราจะยกตัวอย่างร้านค้าออนไลน์ที่ขายสินค้าเครื่องหนัง เช่น กระเป๋า กระเป๋าสตางค์ ที่ใส่กุญแจ และอื่นๆ เจ้าของร้านต้องการติดตามข้อมูลต่างๆ เช่น ที่มาของลูกค้าในร้านค้าออนไลน์ วิธีการขายผลิตภัณฑ์ แหล่งที่มาของการเข้าชมเกี่ยวข้องกับการขาย และอื่นๆ

เราจะสร้างแดชบอร์ดเพื่อแสดงข้อมูลนี้และช่วยเจ้าของร้านค้าวิเคราะห์ แดชบอร์ดจะประกอบด้วยการ์ดสรุปขนาดเล็กสี่ใบ แผนภูมิสี่ประเภทที่แตกต่างกัน และตารางที่แสดงรายการคำสั่งซื้อล่าสุด การ์ดสรุปสี่ใบจะแสดงข้อมูลต่างๆ เช่น รายได้รวมจากการขาย มูลค่าการสั่งซื้อเฉลี่ย จำนวนคำสั่งซื้อทั้งหมด และจำนวนลูกค้าที่กลับมา แผนภูมิจะแสดงจำนวนหน่วยที่ขายสำหรับแต่ละผลิตภัณฑ์ ยอดขายตามแหล่งที่มาของการเข้าชม เซสชันร้านค้าออนไลน์ในช่วงเวลาหนึ่ง และยอดขายสำหรับสัปดาห์

ข้อกำหนดเบื้องต้น

คุณจะต้องติดตั้ง Angular CLI เพื่อติดตาม หากคุณไม่ได้ติดตั้งไว้ คุณสามารถดูวิธีติดตั้งได้ที่ cli.angular.io หากคุณไม่ได้เริ่มต้นจากโปรเจ็กต์ Angular ที่มีอยู่ก่อนแล้ว คุณต้องสร้างโปรเจ็กต์โดยเรียกใช้ ng new <your project name> ตัวอย่างเช่น ในการสร้างแผงการดูแลระบบสำหรับร้านค้าดังกล่าว เราจะเรียกใช้:

 ng new store-admin-panel

โครงการของคุณต้องมีการกำหนดค่าเส้นทางด้วย หากคุณเริ่มต้นจากแอปใหม่ ให้เลือก ใช่ เมื่อได้รับแจ้งว่าจะเพิ่มโมดูลการกำหนดเส้นทางเชิงมุมระหว่างการตั้งค่าโครงการด้านบนหรือไม่

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

เพิ่มวัสดุเชิงมุมและแผนภูมิ Ng2-Chart ให้กับโครงการของคุณ

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 schematics เป็นการพึ่งพา dev เนื่องจากไม่ได้จัดส่งพร้อมกับ ng2-charts โดยค่าเริ่มต้น

 npm install --save-dev ng2-charts-schematics

การสร้างส่วนประกอบการนำทาง

ก่อนอื่น เราต้องเพิ่มองค์ประกอบการนำทางเพื่อช่วยให้ผู้ใช้เคลื่อนผ่านแอพได้อย่างสะดวกสบาย การนำทางควรมีลิงก์ไปยังแดชบอร์ดและหน้าอื่นๆ ที่จะเป็นส่วนหนึ่งของแผงการดูแลระบบ วัสดุเชิงมุมให้แผนผังที่สร้างส่วนประกอบการนำทาง เราจะตั้งชื่อคอมโพเนนต์นี้ว่า 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

ในการดูแดชบอร์ดที่สร้างขึ้นใหม่ภายในคอมโพเนนต์ nav ให้เพิ่มเส้นทางไปยังเราเตอร์

 // 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 คุณควรเห็นสิ่งนี้:

ส่วนประกอบแดชบอร์ดที่สร้างขึ้น
องค์ประกอบแดชบอร์ดที่สร้างขึ้น (ตัวอย่างขนาดใหญ่)

แผนผังสร้างการ์ดสี่ใบในเทมเพลตและแสดงในกริดที่ตอบสนอง CDK วัสดุเชิงมุมใช้แพ็คเกจ Layout เพื่อจัดรูปแบบตารางการ์ดที่ตอบสนองนี้ ยูทิลิตี้ BreakpointObserver ของแพ็คเกจ Layout จะประเมินการสืบค้นสื่อและทำการเปลี่ยนแปลง UI ตามนั้น มีจุดสั่งหยุดที่หลากหลาย แต่ภายในองค์ประกอบที่สร้างขึ้น จะรองรับเพียงสองหมวดหมู่เท่านั้น Breakpoints.Handset และคำถามอื่นๆ ที่ไม่ตรงกัน แพ็คเกจ Layout ย์เอาต์ระบุสถานะเบรกพอยต์ 14 สถานะที่คุณสามารถใช้เพื่อปรับแต่งการตอบสนองของแดชบอร์ดของคุณ

 // dashboard.component.js ... cards = this.breakpointObserver.observe(Breakpoints.Handset).pipe( map(({ matches }) => { if (matches) { ... } ... }) );

กลับไปที่แดชบอร์ด เนื่องจากการ์ดสรุปสี่ใบ แผนภูมิสี่รายการ และตารางจะอยู่บนแดชบอร์ด เราจึงต้องมีการ์ดทั้งหมดเก้าใบ การจับคู่ Breakpoints.Handset พอยต์.แฮนด์เซ็ตและ Breakpoints.Tablet พอยต์.แท็บเล็ตจะแสดงในตารางแบบหนึ่งคอลัมน์โดยที่:

  • การ์ดสรุปสี่ใบจะครอบคลุมหนึ่งแถว
  • แผนภูมิจะครอบคลุมสองแถว
  • ตารางจะครอบคลุมสี่แถว

Non- Breakpoints.Handset และ non- 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 แทน ตัวแปร 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 สร้างแผนภูมิสี่แบบที่แตกต่างกัน เราจะวางไว้ในโฟลเดอร์ที่เรียกว่าแผนภูมิ เรียกใช้ 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 เรียกวิธีการที่ส่งคืนข้อมูลแผนภูมิที่จำเป็นจากบริการภายใน hook ของวงจรการใช้งาน 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; }

ในการเพิ่มตารางไปยังองค์ประกอบ dash:

 <!-- 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 ดังนั้น เราจำเป็นต้องส่งออฟเซ็ตและขนาดหน้าจากตัวแบ่งหน้าและฟิลด์การเรียงลำดับที่ใช้งานอยู่ และทิศทางการจัดเรียงของคุณสมบัติการเรียงลำดับไปยังเมธอด 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() {} }

ในเทมเพลตตารางคำสั่งซื้อ ให้แทรกคอลัมน์ใหม่และผูกคุณสมบัติของ <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>

เมื่อเพิ่มข้อมูลลงในตารางแล้ว แดชบอร์ดจะมีลักษณะดังนี้:

แดชบอร์ดพร้อมแผนภูมิและตาราง
แดชบอร์ดพร้อมแผนภูมิและตาราง (ตัวอย่างขนาดใหญ่)

การสร้างส่วนประกอบมินิการ์ด

สิ่งที่เหลืออยู่เพื่อให้แดชบอร์ดสมบูรณ์คือการเติมการ์ดขนาดเล็กสี่ใบที่อยู่ด้านบนสุด การมีการ์ดสรุปที่มีขนาดเล็กลงเป็นส่วนหนึ่งของแดชบอร์ดทำให้ง่ายต่อการเน้นส่วนข้อมูลสั้นๆ ที่ไม่ต้องการแผนภูมิหรือตารางทั้งหมด ในตัวอย่างนี้ การ์ดขนาดเล็กสี่ใบจะแสดงยอดขายรวม มูลค่าการสั่งซื้อเฉลี่ย จำนวนคำสั่งซื้อทั้งหมด และจำนวนลูกค้าที่กลับมาเยี่ยมชมร้านค้าในวันนั้น นี่เป็นเพียงตัวอย่าง ไม่สามารถสร้างมินิการ์ดเหล่านี้ได้เช่นเดียวกับการนำทาง เค้าโครงแดชบอร์ด แผนภูมิ และตาราง พวกเขาไม่มีแผนผัง ด้านล่างนี้เราจะอธิบายวิธีการสร้างโดยสังเขป แม้ว่าเราจะเพิ่มข้อมูลเฉพาะสำหรับตัวอย่าง คุณสามารถเพิ่มอะไรก็ได้ที่คุณต้องการหรือตัดสินใจที่จะยกเลิกทั้งหมด ในการเริ่มต้น สร้างองค์ประกอบ 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 โปรดไปที่เว็บไซต์ที่ลิงก์ไว้ที่นี่